Kod wirusa przeciwko antidotum golf [zamknięty]

12

Istnieje prostokątna tablica 2D zawierająca wirusy oznaczone literą „v”, antidotum 1 oznaczone literą „a” i antidotum 2 oznaczone literą „b” (nie ma innych wartości niż „v”, „a” i „b”).

Antidotum 1 może zabijać sąsiednie wirusy tylko w kierunku poziomym i pionowym, ale antidotum 2 może zabijać sąsiednie wirusy (jeśli są) w kierunku poziomym, pionowym i ukośnym.

Po aktywowaniu antidotum, ile wirusów pozostanie na końcu?

Przykłady:

Wejście:

vv
vv

Wyjście: 4

Wejście:

av
vv

Wyjście: 1

Wejście:

vvv
vbv
vvv

Wyjście: 0

Wejście:

bvb
bav
vab
vvv
vvb
vvv
vvv
bva
vav

Wyjście: 3

Kiara Dan
źródło
2
Doceniam twoje zmiany @Grimy - Również fajne wyzwanie :)
pixma140
2
@KevinCruijssen, nie ma nieregularnego kształtu.
Kiara Dan
4
Czy możemy wziąć 3 (różne) arbitralne wartości zamiast „v”, „a” i „b”?
attinat
2
czy antywirusy się zawijają (tzn. „a” w dolnym rzędzie usuwa „v” w górnym rzędzie)?
Brian
2
@Kiara Dan Radziłbym nie dopuszczać żadnych 3 odrębnych wartości, ponieważ utrzymuje on pewien charakter w wyzwaniu, a także możliwą wymuszoną sprytność z punktami kodowymi liter.
lirtosiast

Odpowiedzi:

8

Python 3 , 135 bajtów

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

Wypróbuj online!

-2 bajty dzięki Kevin Cruijssen

Wyjaśnienie

Zamienia wszystkie „v” na „b”, jeśli znajduje się obok „b”. Następnie zamienia wszystkie „v” na „c”, jeśli znajduje się obok „a”. Druga iteracja z transponowaną wersją macierzy usuwa wszystkie wirusy pionowe i ukośne. Wreszcie zwróci pozostałą liczbę „v”.


Jako bardziej czytelna funkcja rekurencyjna (155 bajtów)

Jitse
źródło
3
Możesz usunąć spację później y>1else. Przyjemne podejście. Na początku nie byłem pewien, jak to działa z przekątną b, ale wydaje się, że działa dobrze ze względu na twoje zamienniki. :) +1 ode mnie.
Kevin Cruijssen
@KevinCruijssen Thanks! Za przekątne dba się, zastępując „v” „a”, jeśli znajdują się obok „b”. W drugiej iteracji sąsiednie „v” są następnie usuwane.
Jitse,
3
W przypadku następującego wejścia dane wyjściowe powinny wynosić 3, ale zwracane 4: bvb bav vab vvv vvb vvv vvv bva vav
Kiara Dan
1
@KevinCruijssen Znaleziono jeszcze krótszy, ale twoja sugestia oszczędza kolejny bajt!
Jitse,
5

JavaScript (ES7), 108 bajtów

Pobiera dane wejściowe jako macierz znaków.

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

Wypróbuj online!

Podobnie jak w mojej pierwotnej odpowiedzi, ale wykonanie V>'a'>(x-X)**2+y*y-2jest w rzeczywistości 1 bajt krótsze niż użycie sztuczki heksadecymalnej opisanej poniżej. ¯ \ _ (ツ) _ / ¯


JavaScript (ES7), 109 bajtów

Pobiera dane wejściowe jako macierz znaków.

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

Wypróbuj online!

W jaki sposób?

ZA1=(x1,y1)ZA2)=(x2),y2))

Q(ZA1,ZA2))=(x2)-x1)2)+(y2)-y1)2)

Biorąc pod uwagę współrzędne całkowite, wygląda to następująco:

8545852)12)5411452)12)585458

W związku z tym:

  • ZA1ZA2)Q(ZA1,ZA2))<2)
  • ZA1ZA2)Q(ZA1,ZA2))<3)

2)3)8

  • ZA16-810=2)10
  • b16-810=3)10

Skomentował

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
źródło
dzięki @Arnauld, czy możesz również wyjaśnić kod?
Kiara Dan
3
@KiaraDan Done.
Arnauld
3

05AB1E , 33 30 29 bajtów

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

Wypróbuj online lub sprawdź kilka innych przypadków testowych .

Port @Jitse „s Python 3 odpowiedzi , więc upewnij się, aby go upvote!
-1 bajt dzięki @Jitse .

Wyjaśnienie:

Zaletą starszej wersji jest możliwość skompresowania / transponowania listy ciągów, przy czym nowa wersja wymagałaby jawnego Si J, ponieważ działa tylko z listami znaków. Ale nowa wersja jest wciąż o 3 bajty krótsza dzięki €Âkombinacji z krótszym skompresowanym łańcuchem. W starszej wersji zachowałaby tylko ostatnią wartość na stosie wewnątrz mapy, ale w nowej wersji zachowałaby wszystkie wartości na stosie wewnątrz mapy.

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

Zobacz moją wskazówkę 05AB1E (sekcja Jak kompresować ciągi znaków, które nie są częścią słownika? ) Aby zrozumieć, dlaczego tak .•s¯}˜?•jest "vbvabbca".

Kevin Cruijssen
źródło
Nie potrzebujesz bc=> bajeśli złożysz wniosek bv=> baprzed av=> ac. Tak więc .•6øнãI•(skompresowana forma „bvavbaac”) wystarczy, oszczędzając 2 bajty.
Grimmy,
@Grimy To daje 1 zamiast 3 dla ostatniego przypadku testowego .
Kevin Cruijssen
1
@KevinCruijssen dwa kroki zamienne zamiast trzech wydaje rade po wszystkim
Jitse
@Jitse Thanks. Łańcuch kompresji jest o 2 bajty krótszy, ale teraz potrzebuję .:(zamień wszystko raz) zamiast :(wciąż zamieniaj wszystko, dopóki nie będzie już obecny). Nadal -1. :) Dzięki, że dałeś mi znać.
Kevin Cruijssen
2

Java 10, 211 209 bajtów

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

Modyfikacja mojej odpowiedzi na wyzwanie Wszystkie pojedyncze ósemki .
-2 bajty dzięki @ceilingcat .

Wypróbuj online.

Wyjaśnienie:

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
źródło
1

Węgiel drzewny , 39 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

WS⊞υι≔⪫υ⸿θPθ

Połącz ciągi wejściowe ze \rznakami i narysuj wynik na kanwie.

≔⁰η

Wyczyść liczbę żywych wirusów.

Fθ«

Pętla nad znakami na wejściu.

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

Jeśli obecna postać jest wirusem i nie ma sąsiadujących bs w żadnym kierunku lub as ortogonalnie, zwiększ liczbę żywych wirusów.

ι»

Powtórz z następną postacią.

⎚Iη

Wyczyść płótno i wydrukuj całkowitą liczbę żywych wirusów.

Neil
źródło
1

Perl ( -00lp), 82 bajty

Używając wyrażenia regularnego, aby zastąpić vspacją, policz vs

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

TIO

Nahuel Fouilleul
źródło