Dinding Perisai

18

Latar belakang sejarah

Dinding perisai adalah formasi perang taktis yang berasal setidaknya 2500 SM. Itu terdiri dari prajurit yang tumpang tindih perisai mereka dengan orang-orang dari teman mereka untuk membentuk 'dinding'. Daya tarik taktik tersebut berasal dari fakta bahwa bahkan prajurit yang paling tidak terampil pun bisa bertarung di dinding selama mereka memiliki perisai dan senjata. Karena kedekatan dinding, ada sedikit ruang untuk bergerak, dan pertempuran biasanya menjadi pertandingan dorong yang diperjuangkan dengan senjata tajam.

Tantangan

Tugas Anda adalah membuat program atau fungsi yang, dengan memberikan dua array / daftar / vektor prajurit sebagai input, menentukan hasil pertempuran. Daftar tersebut akan mewakili satu dinding pelindung, dan mereka akan mengikuti notasi tertentu:

Viking:

Para prajurit nordik memiliki dorongan yang kuat untuk pertempuran. Selama akhir abad ke-8 hingga pertengahan abad ke-11, para penjahat Denmark menyerbu kerajaan-kerajaan Inggris untuk mencari kekayaan dan tanah yang bisa ditanami. Untuk tujuan tantangan ini, ini adalah prajurit jagoan:

  • The JARL: Biasanya ditemukan memimpin anak buahnya dari pusat dinding, jarls adalah pemimpin gerombolan viking. Membawa 15 kerusakan untuk mati, dan memberikan 2 kerusakan per putaran.
  • The Berserker: Meskipun fantasi telah sangat memutar citra berserkers, prajurit ini dikenal untuk bertarung di trans-seperti kemarahan tanpa jenis perlindungan selain perisai mereka. Membawa 6 kerusakan untuk mati, dan memberikan 3 kerusakan per putaran.
  • The Chieftain: Kepala Suku adalah orang-orang kaya yang memiliki orang-orang gratis di layanan mereka. Mereka biasanya mendapatkan kemenangan besar dan kekayaan dalam pertempuran. Membawa 10 kerusakan untuk mati, dan memberikan 2 kerusakan per putaran.
  • The Free Men: Prajurit yang bertugas sebagai kepala suku. Mereka disumpah untuk memperjuangkan tuan mereka sampai mati. Membawa 8 kerusakan untuk mati, dan memberikan 1 kerusakan per putaran.
  • The Skald: Skalds, biasanya diterjemahkan sebagai bard, adalah orang bebas yang disewa untuk menulis puisi, cerita atau lagu tentang perbuatan besar para pejuang nordic. Membawa 8 kerusakan untuk mati, dan memberikan masing-masing 1 bonus kerusakan prajurit yang berdekatan. Skalds tidak mengalami kerusakan. Prajurit tidak bisa mendapatkan lebih dari 1 bonus kerusakan dengan cara ini.

Saxon:

Orang Saxon datang untuk menetap di Inggris dari benua Eropa setelah runtuhnya Kekaisaran Romawi pada abad ke-5. Untuk tujuan tantangan ini, ada prajurit saxon:

  • The EARL: Ealdormen , biasa disebut Earls, adalah anggota bangsawan tinggi. Mereka biasanya memegang bentangan tanah yang luas dan memiliki ratusan atau bahkan ribuan pria bersumpah. Membawa 20 kerusakan untuk mati, dan memberikan 1 kerusakan per putaran.
  • The Kmalam: Untuk kurangnya istilah yang lebih baik, ksatria adalah bangsawan kecil yang dimiliki beberapa tanah. Dalam kebanyakan kasus, para ksatria disumpah sebagai pelayan ke Earl. Membawa 10 kerusakan untuk mati, dan memberikan 2 kerusakan per putaran.
  • Sang Wpendatang: Laki-laki biasa, biasanya bangsawan kecil tanpa tanah atau petani yang melayani seorang ksatria. Ketika berdekatan dengan Knight atau Earl, prajurit memiliki bonus +1 kerusakan. Membawa 8 kerusakan untuk mati, dan menghasilkan 2 kerusakan per putaran.
  • The Fyrd: The Fyrd adalah milisi-seperti sekelompok orang bebas, biasanya petani miskin, yang akan membawa senjata (atau senjata-seperti pertanian menerapkan) mereka harus berjuang di dinding. Membawa 5 kerusakan untuk mati, dan memberikan 1 kerusakan per putaran.
  • The Priest: Imam sangat dihargai dalam budaya Saxon awal, menjadi bentara firman Allah. Imam mengambil 15 kerusakan untuk mati, dan mencegah hingga 1 kerusakan setiap prajurit yang berdekatan akan ditangani. Imam tidak mengalami kerusakan. Imam tidak bisa mencegah lebih dari 1 kerusakan pada seorang prajurit.

Dinding

Dinding saling bertemu di pusat mereka. Setiap putaran, masing-masing prajurit memberikan kerusakan pada prajurit langsung di depannya atau, jika tidak ada prajurit hidup di depannya, prajurit hidup yang berdekatan secara diagonal dengan kesehatan yang tersisa. Jika ada dasi, pilih prajurit yang lebih dekat ke tepi dinding.

Contoh:

Vikings
[M,M,M,B,B,C,J,C,B,B,M,M,M]
[F,F,F,W,W,K,E,K,W,W,F,F,F]
Saxons

To make matters easier, let's convert these walls into numbers:
Round 0:
 M M M B B C  J  C  B B M M M
[8,8,8,6,6,10,15,10,6,6,8,8,8]
[5,5,5,8,8,10,20,10,8,8,5,5,5]
 F F F W W K  E  K  W W F F F

Round 1: Notice that 2 of the Saxons' warriors are adjacent to Knights, so they have a +1 damage bonus.
 M M M B B C J  C B B M M M
[7,7,7,4,3,8,14,8,3,4,7,7,7]
 | | | | | | || | | | | | |
[4,4,4,5,5,8,18,8,5,5,4,4,4]
 F F F W W K E  K W W F F F

Round 2: 
 M M M B B C J  C B B M M M
[6,6,6,2,0,6,13,6,0,2,6,6,6]
 | | | | | | || | | | | | |
[3,3,3,2,2,6,16,6,2,2,3,3,3]
 F F F W W K E  K W W F F F

Round 3: Remember to collapse the arrays to account for dead warriors. Also, notice that the 2 outermost Fyrd are now attacking the diagonally adjacent viking. 
   M M M B C J  C B M M M
  [4,5,4,0,4,12,4,0,4,5,4]
  /| | | | | || | | | | |\
[2,2,2,1,0,4,14,4,0,1,2,2,2]
 F F F W W K E  K W W F F F

Round 4: Notice once again the saxon Warriors next to the Knights dealing 3 damage:
   M M M C J  C M M M
  [2,4,1,2,11,2,1,4,2]
  /| | | | || | | | |\
[2,1,1,0,2,12,2,0,1,1,2]
 F F F W K E  K W F F F
Round 5:
 M M M C J  C M M M
[1,3,0,0,10,0,0,3,1]
 | | | | || | | | |
[1,0,0,0,10,0,0,0,1]
 F F F K E  K F F F

Round 6: 
    M M J M M
   [1,2,9,2,1]
     \| | |/   
     [0,8,0]
      F E F
Rounds 7 and 8:
      M M J M M         M M J M M
     [1,2,8,2,1]       [1,2,8,2,1]
         \|/               \|/ 
         [4]               [0]
          E                 E  

Output: Viking victory.

Aturan:

  • Berlaku celah default .
  • Anda dapat menggunakan metode IO yang nyaman .
  • Ini adalah , jadi kode terpendek (dalam byte, per bahasa) menang.
  • Anda mungkin tidak menganggap daftar memiliki panjang yang sama, tetapi mereka akan selalu dapat disejajarkan di pusat mereka (akan selalu ada jumlah prajurit yang ganjil di setiap daftar jika daftar memiliki ukuran yang berbeda).
  • Anda dapat menampilkan nilai kebenaran / kesalahan. Silakan tentukan dalam jawaban Anda setara dengan "kemenangan Viking / Saxon".
  • Yang kalah ditentukan ketika semua pejuang tembok mati.
  • Jika Anda pernah berakhir dengan tembok yang tidak dapat disejajarkan selama eksekusi kode, sejajarkan mereka secara terpusat, tinggalkan satu prajurit tambahan di tembok yang lebih panjang ke sisi kanan. Misalnya:

      [M,M,M,J,M,M,M]
        [K,E,K,W];
    
          [B,B,B,J]    
    [K,K,W,W,K,E,K,W,W,K,K]
    
  • Jangan ragu untuk mencoba dan menguji kode Anda dengan pemasangan dinding apa pun, bukan hanya yang ada di kotak uji.

Kasus uji:

V: [M,M,B,C,B,C,J,C,B,C,B,M,M]
S: [F,F,W,K,W,K,E,K,W,K,W,F,F]
O: Viking victory.
------------------------------
V: [M,M,M,M,M,M,M,M,M,M]
S: [W,W,W,W,W,W,W,W,W,W]
O: Saxon victory.
------------------------------
V: [B,C,M,B,C,M,M,C,B,M,C,B,M]
S:   [W,F,W,F,E,E,E,F,W,F,W]
O: Viking victory.
------------------------------
V:         [B,B,B,J,B,B,B]
S: [W,W,W,W,K,K,K,E,K,K,K,W,W,W,W]
O: Saxon victory.
------------------------------
V: [J]
S: [E]
O: Viking victory.
------------------------------
V: [C,C,C,C,B,B,M,M,M,M,J,J,J,M,M,M,M,B,B,C,C,C,C]
S: [K,K,K,K,K,K,K,K,K,K,W,E,W,K,K,K,K,K,K,K,K,K,K]
O: Saxon victory.
------------------------------
V: [M,M,S,C,B,J,B,C,S,M,M]
S: [F,K,P,W,K,E,K,W,P,K,F]
O: Saxon victory.
------------------------------
V: [S,S,S,...,S]
S: [P,P,P,...,P]
O: UNDEFINED (since both priests and skalds deal no damage, you can output anything here.)
------------------------------

Ada beberapa ketidakakuratan historis. Jangan ragu untuk menunjukkannya dan saya akan melakukan yang terbaik untuk memperbaikinya.

J. Sallé
sumber
Tautan ke Sandbox
J. Sallé
Bisakah kita mendefinisikan simbol lain alih-alih huruf pertama dari nama, misalnya angka 0-9?
NieDzejkob
@NieDzejkob pasti. Pastikan Anda menentukan dalam jawaban Anda simbol mana yang digunakan untuk prajurit mana.
J. Sallé
3
Apakah dianggap curang untuk mengambil input sebagai properti alih-alih huruf? (contoh sebagai (health, damage, damagebonus, protbonus))
HyperNeutrino
@HyperNeutrino Saya tidak yakin, tapi saya pikir tidak apa-apa Saya tidak melihat bagaimana itu bisa memberi Anda keuntungan besar. Seperti yang saya katakan kepada NieDzejkob, selama Anda menentukan dalam jawaban Anda apa yang mewakili setiap prajurit, lakukan saja.
J. Sallé

Jawaban:

3

Python 2 , 576 573 565 554 540 549 byte

O=[(0,0)]
g=lambda D,W,i:D[i-1]*(W[i-1]<1)+D[i]+D[i+1]*(W[i+1]<1)
h=lambda*V:[v for v in zip(*V)if v[1]>0]
def f(v,s):
 l,L=len(v),len(s);m=max(l,L);a,b=(L-l)/2,(l-L)/2;V,U=zip(*O+O*a+v+O*a+O+O);S,T=zip(*O+O*b+s+O*b+O+O);z=[0]*(m+2);w=z[:];r=range(1,m+1);U=list(U);T=list(T)
 for i in r:w[i]=[0,2,3,2,1,0][V[i]]+(5in V[i-1:i+2:2])*(V[i]<5);z[i]=[0,1,2,2+({1,2}&set(S[i-1:i+2:2])>set()),1,0][S[i]]
 for i in r:U[i]-=g(z,V,i);d=g(w,S,i);T[i]-=d-(d>0)*(5in S[i-1:i+2:2])
 V=h(V,U);S=h(S,T)
 if([],[])<(V,S)!=(v,s):return(f(V,S)if S else'V')if V else'S'

Cobalah online!

TFeld
sumber
Jika saya mengerti dengan benar, bit ini: (5in V[i-1:i+2:2])menyiratkan bahwa skalds yang berdekatan dapat menimbulkan kerusakan. Anda mungkin perlu di ...*(V[i]!=5)sana. Tes:print f([S,S],[P]) # says V but should be a Draw
ngn
@ ngn Terima kasih untuk itu :)
TFeld
2

APL (Dyalog Classic) , 128 byte

{t l d b p←(-⌊2÷⍨+/0=⊃⍵)∘⌽¨⍵⋄l+←e+3+/0,0,⍨(0=te←(×≢¨p∩¨h)-⊖d+×≢¨b∩¨h3,/0,t,0⋄⍵≡a←↑¨(⊂↓l>0)/¨¨↓¨t l d b p:00s←+/l>0:×-/s⋄∇a}

Cobalah online!

Ada dua fungsi dalam tautan TIO: gadalah fungsi fgolf di atas dan merupakan fungsi yang tidak dipisahkan yang menerima sepasang string, mengubahnya menjadi representasi yang sesuai dan memanggil fungsi golf.

Inputnya adalah lima matriks: ttipe prajurit sebagai int; lkehidupan; dkerusakan; btipe prajurit apa yang memberikan bonus saat berdekatan; psama untuk perlindungan. Matriks terdiri dari dua baris - Viking dan Saxon. Jika prajurit mereka bukan nomor yang sama, matriks harus 0-empuk, meskipun tidak harus terpusat. Hasilnya adalah 1/ ¯1untuk kemenangan Viking / Saxon atau 0untuk hasil seri.

{
  t l d b p←(-⌊2÷⍨+/0=⊃⍵)∘⌽¨⍵  centre the matrices
   (-⌊2÷⍨+/0=⊃⍵) is a pair of numbers - by how much we should rotate (⌽) the rows
         +/0=⊃⍵  how many dead? (⊃⍵ is the types, dead warriors have type 0)
    -⌊2÷⍨        negated floor of half

  l+←e+3+/0,0,⍨(0=t)×e←(×≢¨p∩¨h)-⊖d+×≢¨b∩¨h←3,/0,t,0  compute and apply effective damage
   h3,/0,t,0  are triples of types - self and the two neighbours
   b∩¨h        for each warrior intersect (∩) h with his bonus-giving set b
   ×≢¨         non-empty? 0 or 1
   d+          add to the damage normally inflicted
              reverse vertically (harm the enemy, not self)
   (×≢¨p∩¨h)   same technique for protections (neighbouring priests)
   e          remember as "e" for "effective damage"; we still need to do the diagonal attacks
   (0=t      zero out the attacks on living warriors
   3+/0,0,⍨    sum triples - each warrior suffers the damage intended for his dead neigbours
   e+          add that to the effective damage
   l+←         decrease life ("e" is actually negative)

  ⍵≡a←↑¨(⊂↓l>0)/¨¨↓¨t l d b p:0  remove dead; if no data changed, it's a draw
  ⍝ ↓¨          split each matrix into two row-vectors
  ⍝ (⊂↓l>0)     boolean mask of warrios with any life left, split in two and enclosed
  ⍝ /¨¨         keep only the survivors
  ⍝ ↑¨          mix the pairs of rows into matrices again, implicitly padding with 0-s
  ⍝ a←          call that "a" - our new arguments
  ⍝ ⍵≡a ... :0  is "a" the same as our original arguments? - nothing's changed, it's a draw

  0∊s←+/l>0:×-/s ⍝ if one team has no members left, they lost
  ⍝ l>0         bitmask of survivors
  ⍝ s←+/l>0     how many in each camp
  ⍝ 0∊          has any of the two armies been annihilated?
  ⍝ :×-/s       if yes, which one? return sign of the difference: ¯1 or 1, or maybe 0

  ∇a ⍝ repeat
}
ngn
sumber