Virus vs Antidotes code golf [fermé]

12

Il existe un tableau 2D rectangulaire contenant des virus dénotés par «v», antidote1 dénoté par «a» et antidote2 dénoté par «b» (il n'y a pas de valeurs autres que «v», «a» et «b»).

Antidote1 peut tuer les virus voisins uniquement dans les directions horizontale et verticale, mais l'antidote2 peut tuer les virus voisins (le cas échéant) dans les directions horizontale, verticale et diagonale.

Une fois les antidotes activés, combien de virus resteront-ils à la fin?

Exemples:

Contribution:

vv
vv

Sortie: 4

Contribution:

av
vv

Sortie: 1

Contribution:

vvv
vbv
vvv

Sortie: 0

Contribution:

bvb
bav
vab
vvv
vvb
vvv
vvv
bva
vav

Sortie: 3

Kiara Dan
la source
2
J'apprécie vos modifications @Grimy - Également un beau défi :)
pixma140
2
@KevinCruijssen, il n'est pas de forme irrégulière.
Kiara Dan
4
Pouvons-nous prendre 3 valeurs arbitraires (distinctes) au lieu de "v", "a" et "b"?
attinat
2
les antivirus s'enroulent-ils (c.-à-d., "un" dans la rangée inférieure supprimerait un "v" dans la rangée supérieure)?
Brian
2
@Kiara Dan Je conseille de ne pas autoriser 3 valeurs distinctes, car cela garde un certain caractère dans le défi, ainsi qu'une possible ingéniosité forcée avec les points de code des lettres.
lirtosiast

Réponses:

8

Python 3 , 135 octets

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

Essayez-le en ligne!

-2 octets grâce à Kevin Cruijssen

Explication

Remplace tous les «v» par «b» s'ils se trouvent à côté de «b». Ensuite, remplace tous les «v» par «c» s'ils se trouvent à côté de «a». Une deuxième itération avec la version transposée de la matrice efface tous les virus verticaux et diagonaux. Enfin, il renverra le nombre restant de «v».


En tant que fonction récursive plus lisible (155 octets)

Jitse
la source
3
Vous pouvez supprimer l'espace après y>1else. Belle approche cependant. Au début, je n'étais pas sûr de savoir comment cela traitait la diagonale b, mais cela semble fonctionner très bien en raison de vos remplacements. :) +1 de ma part.
Kevin Cruijssen
@KevinCruijssen Merci! Les diagonales sont gérées en remplaçant «v» par «a» si elles sont à côté de «b». Dans la deuxième itération, les «v» adjacents sont ensuite supprimés.
Jitse
3
Pour l'entrée suivante, la sortie doit être 3, mais son retour 4: bvb bav vab vvv vvb vvv vvv bva vav
Kiara Dan
1
@KevinCruijssen Trouvé un encore plus court, mais votre suggestion enregistre un autre octet!
Jitse
5

JavaScript (ES7), 108 octets

Prend l'entrée comme une matrice de caractères.

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

Essayez-le en ligne!

Similaire à ma réponse d'origine, mais faire V>'a'>(x-X)**2+y*y-2est en fait 1 octet plus court que d'utiliser l'astuce hexa décrite ci-dessous. ¯ \ _ (ツ) _ / ¯


JavaScript (ES7), 109 octets

Prend l'entrée comme une matrice de caractères.

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

Essayez-le en ligne!

Comment?

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

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

Compte tenu des coordonnées entières, il se présente comme suit:

854585212541145212585458

Donc:

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

238

  • A16810=210
  • B16810=310

Commenté

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
la source
merci @Arnauld, pouvez-vous également expliquer le code?
Kiara Dan
3
@KiaraDan Done.
Arnauld
3

05AB1E , 33 30 29 octets

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

Essayez-le en ligne ou vérifiez quelques cas de test supplémentaires .

Port de la réponse Python 3 de @Jitse , alors assurez-vous de lui donner un vote positif!
-1 octet grâce à @Jitse .

Explication:

La version héritée a l'avantage de pouvoir compresser / transposer une liste de chaînes, où la nouvelle version aurait besoin d'une explicite Set J, car elle ne fonctionne qu'avec des listes de caractères. Mais, la nouvelle version est toujours plus courte de 3 octets en utilisant €Âen combinaison avec une chaîne compressée plus courte. Dans la version héritée, ne conserverait que la dernière valeur de la pile à l'intérieur de la carte, mais dans la nouvelle version, elle conserverait toutes les valeurs de la pile à l'intérieur de la carte.

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

Voir cette astuce de mes 05AB1E (section Comment chaînes Compresser ne font pas partie du dictionnaire? ) Pour comprendre pourquoi .•s¯}˜?•est "vbvabbca".

Kevin Cruijssen
la source
Vous n'avez pas besoin de bc=> basi vous postulez bv=> baavant av=> ac. Ainsi .•6øнãI•(la forme compressée de "bvavbaac") suffit, économisant 2 octets.
Grimmy
@Grimy Il en résulte cependant 1 au lieu de 3 pour le dernier cas de test .
Kevin Cruijssen
1
@KevinCruijssen deux étapes de remplacement au lieu de trois semblent faire l'affaire après tout
Jitse
@Jitse Merci. La chaîne de compression est plus courte de 2 octets, mais j'ai maintenant besoin de .:(remplacer tout une fois) au lieu de :(continuer à remplacer tout jusqu'à ce qu'il ne soit plus présent). Toujours -1, cependant. :) Merci de me le faire savoir.
Kevin Cruijssen
2

Java 10, 211 209 octets

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

Modification de ma réponse pour le challenge All the single eights .
-2 octets grâce à @ceilingcat .

Essayez-le en ligne.

Explication:

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
la source
1

Fusain , 39 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

WS⊞υι≔⪫υ⸿θPθ

Joignez les chaînes d'entrée avec des \rcaractères et dessinez le résultat sur le canevas.

≔⁰η

Effacez le nombre de virii vivants.

Fθ«

Faites une boucle sur les caractères dans l'entrée.

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

Si le personnage actuel est un virus et qu'il n'y a aucun bs adjacent dans aucune direction ou as orthogonalement, augmentez le nombre de virii vivants.

ι»

Répétez avec le caractère suivant.

⎚Iη

Nettoyez la toile et imprimez le nombre total de virii vivants.

Neil
la source
1

Perl ( -00lp), 82 octets

Utiliser regex pour remplacer vpar l'espace, puis compter le vs

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

TIO

Nahuel Fouilleul
la source