Virus vs Gegenmittel Code Golf [geschlossen]

11

Es gibt ein rechteckiges 2D-Array, das Viren enthält, die mit 'v' bezeichnet sind, Antidot1, das mit 'a' bezeichnet ist, und Antidot2, das mit 'b' bezeichnet wird (es gibt keine anderen Werte als 'v', 'a' und 'b').

Antidot1 kann benachbarte Viren nur in horizontaler und vertikaler Richtung abtöten, Antidot2 kann jedoch benachbarte (falls vorhanden) Viren in horizontaler, vertikaler und diagonaler Richtung abtöten.

Wie viele Viren bleiben nach Aktivierung der Gegenmittel am Ende übrig?

Beispiele:

Eingang:

vv
vv

Ausgabe: 4

Eingang:

av
vv

Ausgabe: 1

Eingang:

vvv
vbv
vvv

Ausgabe: 0

Eingang:

bvb
bav
vab
vvv
vvb
vvv
vvv
bva
vav

Ausgabe: 3

Kiara Dan
quelle
2
Ich schätze deine Änderungen @Grimy - Auch schöne Herausforderung :)
pixma140
2
@ KevinCruijssen, es ist nicht unregelmäßig geformt.
Kiara Dan
4
Dürfen wir 3 (verschiedene) willkürliche Werte anstelle von "v", "a" und "b" nehmen?
Attinat
2
Wickeln sich die Antiviren um (dh "a" in der unteren Reihe würde ein "v" in der oberen Reihe entfernen)?
Brian
2
@Kiara Dan Ich würde raten, keine 3 unterschiedlichen Werte zuzulassen, da dies einen gewissen Charakter in der Herausforderung behält, sowie eine mögliche erzwungene Klugheit mit Codepunkten der Buchstaben.
Lirtosiast

Antworten:

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

Probieren Sie es online aus!

-2 Bytes dank Kevin Cruijssen

Erläuterung

Ersetzt alle 'v' durch 'b', wenn sie neben 'b' gefunden werden. Ersetzt als Nächstes alle 'v' durch 'c', wenn sie neben 'a' gefunden werden. Eine zweite Iteration mit der transponierten Version des Arrays löscht alle vertikalen und diagonalen Viren. Schließlich wird die verbleibende Anzahl von 'v' zurückgegeben.


Als besser lesbare rekursive Funktion (155 Bytes)

Jitse
quelle
3
Sie können das Leerzeichen nach entfernen y>1else. Netter Ansatz. Anfangs war ich mir nicht sicher, wie dies mit der Diagonale umgeht b, aber das scheint aufgrund Ihrer Ersetzungen gut zu funktionieren. :) +1 von mir.
Kevin Cruijssen
@ KevinCruijssen Danke! Die Diagonalen werden durch Ersetzen von 'v' durch 'a' behoben, wenn sie sich neben 'b' befinden. In der zweiten Iteration werden dann die benachbarten 'v' entfernt.
Jitse
3
Für die folgende Eingabe sollte die Ausgabe 3 sein, aber die Rückgabe 4: bvb bav vab vvv vvb vvv vvv bva vav
Kiara Dan
1
@ KevinCruijssen Es wurde ein noch kürzeres gefunden, aber Ihr Vorschlag spart ein weiteres Byte!
Jitse
5

JavaScript (ES7), 108 Byte

Nimmt die Eingabe als Matrix von Zeichen auf.

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

Probieren Sie es online aus!

Ähnlich wie bei meiner ursprünglichen Antwort, aber dies V>'a'>(x-X)**2+y*y-2ist tatsächlich 1 Byte kürzer als bei Verwendung des unten beschriebenen Hexa-Tricks. ¯ \ _ (ツ) _ / ¯


JavaScript (ES7), 109 Byte

Nimmt die Eingabe als Matrix von Zeichen auf.

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

Probieren Sie es online aus!

Wie?

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

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

Unter Berücksichtigung ganzzahliger Koordinaten sieht es wie folgt aus:

854585212541145212585458

Deshalb:

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

238

  • A16810=210
  • B16810=310

Kommentiert

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
quelle
danke @Arnauld, kannst du auch den Code erklären?
Kiara Dan
3
@ KiaraDan Fertig.
Arnauld
3

05AB1E , 33 30 29 Bytes

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

Probieren Sie es online aus oder überprüfen Sie einige weitere Testfälle .

Port of @Jitses Python 3-Antwort , also stellen Sie sicher, dass Sie ihn positiv bewerten!
-1 Byte dank @Jitse .

Erläuterung:

Die Legacy-Version hat den Vorteil, dass sie eine String-Liste komprimieren / transponieren kann, wobei die neue Version eine explizite Sund benötigen würde J, da sie nur mit Zeichenlisten funktioniert. Die neue Version ist jedoch immer noch 3 Byte kürzer, wenn sie €Âin Kombination mit einer kürzeren komprimierten Zeichenfolge verwendet wird. In der Legacy-Version wird nur der letzte Wert auf dem Stapel in der Karte beibehalten, in der neuen Version werden jedoch alle Werte auf dem Stapel in der Karte beibehalten.

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

Lesen Sie diesen 05AB1E-Tipp von mir (Abschnitt Komprimieren von Zeichenfolgen, die nicht Teil des Wörterbuchs sind? ) , Um zu verstehen, warum dies so .•s¯}˜?•ist "vbvabbca".

Kevin Cruijssen
quelle
Sie brauchen nicht bc=>, bawenn Sie sich bewerben bv=> bavor av=> ac. Somit ist .•6øнãI•(komprimierte Form von "bvavbaac") ausreichend, um 2 Bytes zu sparen.
Grimmy
@Grimy Für den letzten Testfall ergibt sich jedoch 1 statt 3 .
Kevin Cruijssen
1
@KevinCruijssen zwei Ersetzungsschritten statt drei scheint den Trick schließlich
Jitse
@ Jitse Danke. Die Komprimierungszeichenfolge ist 2 Byte kürzer, aber ich brauche jetzt .:(alle einmal ersetzen) anstatt :(alle so lange ersetzen, bis sie nicht mehr vorhanden ist). Trotzdem -1. :) Danke für die Information.
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;}

Änderung meiner Antwort für die Herausforderung All the Single Eights .
-2 Bytes dank @ceilingcat .

Probieren Sie es online aus.

Erläuterung:

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
quelle
1

Holzkohle , 39 Bytes

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

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Erläuterung:

WS⊞υι≔⪫υ⸿θPθ

Verbinden Sie die Eingabezeichenfolgen mit \rZeichen und zeichnen Sie das Ergebnis auf die Leinwand.

≔⁰η

Löschen Sie die Anzahl der lebenden Viren.

Fθ«

Schleife über die Zeichen in der Eingabe.

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

Wenn das aktuelle Zeichen ein Virus ist und keine benachbarten bs in irgendeiner Richtung oder aorthogonal vorhanden sind, erhöhen Sie die Anzahl der lebenden Viren.

ι»

Wiederholen Sie mit dem nächsten Zeichen.

⎚Iη

Löschen Sie die Leinwand und drucken Sie die Gesamtzahl der lebenden Viren.

Neil
quelle
1

Perl ( -00lp), 82 Bytes

Verwenden Sie Regex, um vdurch Leerzeichen zu ersetzen , und zählen Sie dann die vs

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

TIO

Nahuel Fouilleul
quelle