El muro de escudos

18

Antecedentes históricos

El muro de escudos es una formación de guerra táctica que se remonta al menos a 2500 AC. Consistía en guerreros superponiendo sus escudos con los de sus compañeros para formar un 'muro'. El atractivo de la táctica proviene del hecho de que incluso el guerrero más inexperto podría luchar en una pared siempre que tuviera un escudo y un arma. Debido a la proximidad de las paredes, había poco espacio para moverse, y la batalla generalmente se convertía en una lucha de empuje con armas afiladas.

El reto

Su tarea es crear un programa o función que, dados dos conjuntos / listas / vectores de guerreros como entrada, decida el resultado de la batalla. Las listas representarán un muro de escudos de una sola línea y seguirán una notación específica:

Vikingos:

Los guerreros nórdicos tenían un impulso feroz por la batalla. Durante finales del siglo VIII hasta mediados del siglo XI, los vikingos daneses invadieron los reinos de Gran Bretaña en busca de riquezas y tierras cultivables. A los efectos de este desafío, estos son los guerreros de los vikingos:

  • El Jarl: Por lo general, los líderes de las hordas vikingas lideraban a sus hombres desde el centro del muro. Recibe 15 puntos de daño para morir e inflige 2 de daño por ronda.
  • El Berserker: aunque la fantasía ha torcido enormemente la imagen de los berserkers, se sabía que estos guerreros luchaban en una furia de trance sin ningún tipo de protección aparte de sus escudos. Sufre 6 daños al morir e inflige 3 daños por ronda.
  • El Chieftain: los jefes eran hombres ricos que tenían hombres libres a su servicio. Por lo general, habrían ganado gran gloria y riquezas en la batalla. Recibe 10 puntos de daño para morir e inflige 2 de daño por ronda.
  • The Free Men: Guerreros que sirvieron a un jefe. Juraron luchar por sus señores hasta la muerte. Sufre 8 daños al morir e inflige 1 daño por ronda.
  • El Skald: los skalds, generalmente traducidos como bardos, eran hombres libres que fueron contratados para escribir poemas, historias o canciones sobre las grandes obras de los guerreros nórdicos. Toma 8 daños para morir, y le da a cada guerrero adyacente 1 daño adicional. Los Skalds no causan daño. Los guerreros no pueden ganar más de 1 daño adicional de esta manera.

Sajones:

Los sajones llegaron a establecerse en Gran Bretaña desde la Europa continental después de la desaparición del Imperio Romano en el siglo quinto. Para los propósitos de este desafío, están los guerreros de los sajones:

  • El Earl: Ealdormen , comúnmente llamado Earls, eran miembros de la nobleza superior. Por lo general, tenían grandes extensiones de tierra y tenían cientos o incluso miles de hombres juramentados. Recibe 20 puntos de daño al morir e inflige 1 de daño por ronda.
  • La Knoche: a falta de un término mejor, los caballeros eran nobles menores que poseían algunas tierras. En la mayoría de los casos, los caballeros eran sirvientes jurados de un conde. Recibe 10 puntos de daño para morir e inflige 2 de daño por ronda.
  • El Warrior: hombres comunes, generalmente nobles menores sin tierra o campesinos que sirvieron a un caballero. Cuando están adyacentes a un Caballero o Conde, los guerreros tienen un bonificador de daño +1. Recibe 8 puntos de daño al morir e inflige 2 de daño por ronda.
  • El año Fpasado: el Fyrd era un grupo de hombres libres, como la milicia, generalmente agricultores pobres, que traían cualquier arma (o implemento agrícola similar al arma) que tenían que luchar en la pared. Sufre 5 daños al morir e inflige 1 daño por asalto.
  • El Psacerdote: los sacerdotes eran muy valorados en la cultura sajona temprana, siendo heraldos de las palabras de Dios. Los sacerdotes reciben 15 daños para morir y evitan hasta 1 daño por cada guerrero adyacente. Los sacerdotes no causan daño. Los sacerdotes no pueden evitar más de 1 daño a un guerrero.

La pared

Las paredes se encuentran en sus centros. Cada ronda, cada guerrero asigna daño al guerrero directamente frente a él o, si no hay un guerrero vivo frente a él, al guerrero vivo diagonalmente adyacente con menos salud restante. Si hay un empate, elige al guerrero más cerca del borde de la pared.

Ejemplo:

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.

Reglas:

  • Lagunas predeterminadas aplican las .
  • Puedes usar cualquier método conveniente de IO .
  • Esto es , por lo que gana el código más corto (en bytes, por idioma).
  • No puede suponer que las listas tendrán la misma longitud, pero lo harán siempre serán alineables en sus centros (siempre habrá un número impar de guerreros en cada lista si las listas son de diferentes tamaños).
  • Puede generar cualquier valor verdadero / falso. Especifique en su respuesta los equivalentes de "Victoria vikinga / sajona".
  • El perdedor se determina cuando todos los guerreros de un muro están muertos.
  • Si alguna vez terminas con paredes que no se pueden alinear durante la ejecución del código, alinealas lo más centralmente posible, dejando un guerrero extra en la pared más larga al lado derecho. P.ej:

      [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]
    
  • Siéntase libre de probar y probar su código con cualquier configuración de paredes, no solo las de los casos de prueba.

Casos de prueba:

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.)
------------------------------

Hay algunas inexactitudes históricas. Siéntase libre de señalarlos y haré todo lo posible para solucionarlos.

J. Sallé
fuente
Enlace al Sandbox
J. Sallé
¿Podemos definir otros símbolos en lugar de las primeras letras de los nombres, por ejemplo, números 0-9?
NieDzejkob
@NieDzejkob seguro. Solo asegúrate de especificar en tu respuesta qué símbolos se usaron para cada guerrero.
J. Sallé
3
¿Se consideraría hacer trampa para tomar la entrada como sus propiedades en lugar de letras? (ejemplo como (health, damage, damagebonus, protbonus))
HyperNeutrino
@HyperNeutrino No estoy exactamente seguro, pero creo que estaría bien. No veo cómo eso podría darte una gran ventaja. Como le dije a NieDzejkob, siempre y cuando especifiques en tu respuesta qué representa a cada guerrero, hazlo.
J. Sallé

Respuestas:

3

Python 2 , 576 573 565 554 540 549 bytes

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'

Pruébalo en línea!

TFeld
fuente
Si entiendo correctamente, este bit: (5in V[i-1:i+2:2])implica que los skalds adyacentes pueden infligir daño. Es posible que necesite un ...*(V[i]!=5)allí. Prueba:print f([S,S],[P]) # says V but should be a Draw
NGN
@ngn Gracias por eso :)
TFeld
2

APL (Dyalog Classic) , 128 bytes

{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}

Pruébalo en línea!

Hay dos funciones en el enlace TIO: ges la función golfed anterior y fes una función no golfizada que acepta un par de cadenas, las convierte en una representación adecuada y llama a la función golfed.

La entrada es de cinco matrices: ttipos de guerreros como ints; lvida; ddañar; bqué tipos de guerreros dan bonificación cuando están adyacentes; pLo mismo para la protección. Las matrices consisten en dos filas: vikingos y sajones. Si sus guerreros no son el mismo número, las matrices deben estar rellenadas con 0, aunque no necesariamente centradas. El resultado es 1/ ¯1para la victoria vikinga / sajona o 0para un empate.

{
  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
fuente