Virus vs Antídotos código golf [cerrado]

12

Hay una matriz 2D rectangular que contiene virus denotados por 'v', antídoto1 denotado por 'a' y antídoto2 denotado por 'b' (no hay valores distintos a 'v', 'a' y 'b').

Antidote1 puede matar virus vecinos en direcciones horizontales y verticales solamente, pero antidote2 puede matar virus vecinos (si los hay) en direcciones horizontal, vertical y diagonal.

Una vez que se activan los antídotos, ¿cuántos virus quedarán al final?

Ejemplos:

Entrada:

vv
vv

Salida: 4

Entrada:

av
vv

Salida: 1

Entrada:

vvv
vbv
vvv

Salida: 0

Entrada:

bvb
bav
vab
vvv
vvb
vvv
vvv
bva
vav

Salida: 3

Kiara Dan
fuente
2
Agradezco tus ediciones @Grimy - También es un buen desafío :)
pixma140
2
@KevinCruijssen, no tiene forma irregular.
Kiara Dan
44
¿Podemos tomar 3 valores arbitrarios (distintos) en lugar de "v", "a" y "b"?
attinat
2
¿se envuelven los antivirus (es decir, "una" en la fila inferior eliminaría una "v" en la fila superior)?
Brian
2
@Kiara Dan Aconsejaría que no permita 3 valores distintos, ya que mantiene cierto carácter en el desafío, así como la posible inteligencia forzada con puntos de código de las letras.
lirtosiast el

Respuestas:

8

Python 3 , 135 bytes

j=''.join
p='j(s)'+4*'.replace("%s%s","%s%s")'%(*'vbbbbvbbavacvaca',)
f=lambda x:j(eval(2*'(eval(p)for s in zip(*'+'x))))')).count('v')

Pruébalo en línea!

-2 bytes gracias a Kevin Cruijssen

Explicación

Reemplaza todas las 'v' por 'b' si se encuentran junto a 'b'. A continuación, reemplaza todas las 'v' a 'c' si se encuentran junto a 'a'. Una segunda iteración con la versión transpuesta de la matriz borra todos los virus verticales y diagonales. Finalmente, devolverá el número restante de 'v'.


Como una función recursiva más legible (155 bytes)

Jitse
fuente
3
Puede eliminar el espacio después y>1else. Buen enfoque sin embargo. Al principio no estaba seguro de cómo se trata esto con la diagonal b, pero parece funcionar bien debido a sus reemplazos. :) +1 de mi parte.
Kevin Cruijssen
@KevinCruijssen ¡Gracias! Las diagonales se resuelven reemplazando 'v' con 'a' si están al lado de 'b'. En la segunda iteración, las 'v' adyacentes se eliminan.
Jitse
3
Para la siguiente entrada, la salida debe ser 3, pero su retorno es 4: bvb bav vab vvv vvb vvv vvv bva vav
Kiara Dan
1
@KevinCruijssen ¡Encontró uno aún más corto, pero su sugerencia guarda otro byte!
Jitse
5

JavaScript (ES7), 108 bytes

Toma la entrada como una matriz de caracteres.

f=m=>(g=(y,X,V)=>m.map(r=>r.map((v,x)=>V?v>f&V>'a'>(x-X)**2+y*y-2?r[x]=n--:0:v<f?g(-y,x,v):n++)|y++))(n=0)|n

Pruébalo en línea!

Similar a mi respuesta original, pero hacerlo V>'a'>(x-X)**2+y*y-2es en realidad 1 byte más corto que usar el truco hexa descrito a continuación. ¯ \ _ (ツ) _ / ¯


JavaScript (ES7), 109 bytes

Toma la entrada como una matriz de caracteres.

f=m=>(g=(y,X,V)=>m.map(r=>r.map((v,x)=>V?v>f&(x-X)**2+y*y<V-8?r[x]=n--:0:v<f?g(-y,x,'0x'+v):n++)|y++))(n=0)|n

Pruébalo en línea!

¿Cómo?

A1=(x1,y1)A2=(x2,y2)

Q(A1,A2)=(x2x1)2+(y2y1)2

Teniendo en cuenta las coordenadas enteras, se ve de la siguiente manera:

854585212541145212585458

Por lo tanto:

  • A1A2Q(A1,A2)<2
  • A1A2Q(A1,A2)<3

238

  • A16810=210
  • B16810=310

Comentado

f =                      // named function, because we use it to test if a character
                         // is below or above 'm'
m => (                   // m[] = input matrix
  g = (                  // g is a recursive function taking:
    y,                   //   y = offset between the reference row and the current row
    X,                   //   X = reference column
    V                    //   V = reference value, prefixed with '0x'
  ) =>                   //
    m.map(r =>           // for each row r[] in m[]:
      r.map((v, x) =>    //   for each value v at position x in r[]:
        V ?              //     if V is defined:
          v > f &        //       if v is equal to 'v'
          (x - X) ** 2 + //       and the quadrance between the reference point and
          y * y          //       the current point
          < V - 8 ?      //       is less than the reference value read as hexa minus 8:
            r[x] = n--   //         decrement n and invalidate the current cell
          :              //       else:
            0            //         do nothing
        :                //     else:
          v < f ?        //       if v is either 'a' or 'b':
            g(           //         do a recursive call:
              -y,        //           pass the opposite of y
              x,         //           pass x unchanged
              '0x' + v   //           pass v prefixed with '0x'
            )            //         end of recursive call
          :              //       else:
            n++          //         increment n
      ) | y++            //   end of inner map(); increment y
    )                    // end of outer map()
  )(n = 0)               // initial call to g with y = n = 0
  | n                    // return n
Arnauld
fuente
gracias @Arnauld, ¿también puedes explicar el código?
Kiara Dan
3
@KiaraDan Hecho.
Arnauld
3

05AB1E , 33 30 29 bytes

2F.•s¯}˜?•2ô€Â2ä`.:S¶¡øJ»}'v¢

Pruébelo en línea o verifique algunos casos de prueba más .

Puerto de la respuesta de Python 3 de @Jitse , ¡así que asegúrate de votarlo!
-1 byte gracias a @Jitse .

Explicación:

La versión heredada tiene la ventaja de poder comprimir / transponer una lista de cadenas, donde la nueva versión necesitaría una lista explícita Sy J, dado que solo funciona con listas de caracteres. Pero, la nueva versión sigue siendo 3 bytes más corta al usarla €Âen combinación con una cadena comprimida más corta. En la versión heredada, solo mantendría el último valor en la pila dentro del mapa, pero en la nueva versión, mantendrá todos los valores en la pila dentro del mapa.

2F                  # Loop 2 times:
  .•s¯}˜?•          #  Push compressed string "vbvabbca"
   2ô               #  Split it into parts of size 2: ["vb","va","bb","ca"]
     €Â             #  Bifurcate (short for duplicate & reverse copy) each:
                    #   ["vb","bv","va","av","bb","bb","ca","ac"]
       2ä           #  Split it into two parts:
                    #   [["vb","bv","va","av"],["bb","bb","ca","ac"]]
         `          #  Push both those lists separated to the stack
          .:        #  Replace all strings once one by one in the (implicit) input-string
            S       #  Then split the entire modified input to a list of characters
             ¶¡     #  Split that list by newlines into sublists of characters
               ø    #  Zip/transpose; swapping rows/columns
                J   #  Join each inner character-list back together to a string again
                 »  #  And join it back together by newlines
}'v¢               '# After the loop: count how many "v" remain

Ver este consejo 05AB1E mío (sección Cómo comprimir cadenas que no forman parte del diccionario? ) Para entender por qué .•s¯}˜?•es "vbvabbca".

Kevin Cruijssen
fuente
No necesita bc=> basi aplica bv=> baantes av=> ac. Por lo tanto .•6øнãI•(forma comprimida de "bvavbaac") es suficiente, ahorrando 2 bytes.
Grimmy
@Grimy Sin embargo, da como resultado 1 en lugar de 3 para el último caso de prueba .
Kevin Cruijssen
1
@KevinCruijssen dos pasos de reemplazo en lugar de tres parecen ser el truco después de todo
Jitse
@Jitse Gracias. La cadena de compresión es 2 bytes más corta, pero ahora necesito .:(reemplazar todo una vez) en lugar de :(seguir reemplazando todo hasta que ya no esté presente). Todavía -1, sin embargo. :) Gracias por hacérmelo saber.
Kevin Cruijssen
2

Java 10, 211 209 bytes

m->{int i=m.length,j,c=0,f,t,I,J;for(;i-->0;)for(j=m[i].length;j-->0;c+=m[i][j]>98?f/9:0)for(f=t=9;t-->0;)try{f-=m[I=i+t/3-1][J=j+t%3-1]==98||Math.abs(I-i+J-j)==1&m[I][J]<98?1:0;}catch(Exception e){}return c;}

Modificación de mi respuesta para el desafío Todos los ochos individuales .
-2 bytes gracias a @ceilingcat .

Pruébalo en línea.

Explicación:

m->{                           // Method with char-matrix parameter & int return-type
  int i=m.length,              //  Amount of rows
      j,                       //  Amount of columns
      c=0,                     //  Virus-counter, starting at 0
      f,                       //  Flag-integer
      t,I,J;                   //  Temp-integers
  for(;i-->0;)                 //  Loop over the rows of the matrix
    for(j=m[i].length;j-->0    //   Inner loop over the columns
        ;c+=                   //     After every iteration: increase the counter by:
            m[i][j]>98         //      If the current cell contains a 'v'
             f/9               //      And the flag is 9:
                               //       Increase the counter by 1
            :0)                //      Else: leave the counter unchanged by adding 0
      for(f=t=9;               //    Reset the flag to 9
          t-->0;)              //    Loop `t` in the range (9, 0]:
         try{f-=               //     Decrease the flag by:
           m[I=i+t/3-1]        //      If `t` is 0, 1, or 2: Look at the previous row
                               //      Else-if `t` is 6, 7, or 8: Look at the next row
                               //      Else (`t` is 3, 4, or 5): Look at the current row
            [J=j+t%3-1]        //      If `t` is 0, 3, or 6: Look at the previous column
                               //      Else-if `t` is 2, 5, or 8: Look at the next column
                               //      Else (`t` is 1, 4, or 7): Look at the current column
            ==98               //      And if this cell contains a 'b'
            ||Math.abs(I-i+J-j)==1
                               //      Or if a vertical/horizontal adjacent cell
              &m[I][J]<98?     //      contains an 'a'
               1               //       Decrease the flag by 1
            :0;                //      Else: leave the flag unchanged by decreasing with 0
         }catch(Exception e){} //     Catch and ignore any ArrayIndexOutOfBoundsExceptions,
                               //     which is shorter than manual checks
  return c;}                   //  And finally return the virus-counter as result
Kevin Cruijssen
fuente
1

Carbón , 39 bytes

WS⊞υι≔⪫υ⸿θPθ≔⁰ηFθ«≧⁺›⁼ιv⁺№KMb№KVaηι»⎚Iη

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

WS⊞υι≔⪫υ⸿θPθ

Une las cadenas de entrada con los \rcaracteres y dibuja el resultado en el lienzo.

≔⁰η

Borrar el número de virii vivos.

Fθ«

Recorre los caracteres en la entrada.

≧⁺›⁼ιv⁺№KMb№KVaη

Si el personaje actual es un virus y no hay bs adyacentes en ninguna dirección u aortogonalmente, incremente el número de virus vivos.

ι»

Repite con el siguiente personaje.

⎚Iη

Despeje el lienzo e imprima el número total de virii vivos.

Neil
fuente
1

Perl ( -00lp), 82 bytes

Usando regex para reemplazar vpor espacio, luego cuenta el vs

/.
/;$,="(|..{@-})";$;="(|.{@-,@+})";$_=s/(a$,|b$;)\Kv|v(?=$,a|$;b)/ /s?redo:y/v//

TIO

Nahuel Fouilleul
fuente