Virüs vs Panzehir kodu golf [kapalı]


12

'V' ile gösterilen virüsleri, 'a' ile gösterilen panzehir1 ve 'b' ile gösterilen panzehir2'yi içeren dikdörtgen bir 2D dizi vardır ('v', 'a' ve 'b' dışında bir değer yoktur).

Panzehir1 komşu virüsleri yalnızca yatay ve dikey yönlerde öldürebilir, ancak panzehir2 komşu virüsleri (varsa) yatay, dikey ve çapraz yönlerde öldürebilir.

Panzehirler aktive edildiğinde, sonunda kaç virüs kalacaktır?

Örnekler:

Giriş:

vv
vv

Çıktı: 4

Giriş:

av
vv

Çıktı: 1

Giriş:

vvv
vbv
vvv

Çıktı: 0

Giriş:

bvb
bav
vab
vvv
vvb
vvv
vvv
bva
vav

Çıktı: 3


2
Düzenlemelerinizi takdir ediyorum @Grimy - Ayrıca güzel bir meydan okuma :)
pixma140

2
@KevinCruijssen, düzensiz şekilli değil.
Kiara Dan

4
"V", "a" ve "b" yerine 3 (farklı) keyfi değer alabilir miyiz?
attinat

2
antivirüsler etrafa dolanıyor mu (yani, alt sıradaki "a" üst sıradaki "v" yi kaldıracaktır)?
Brian

2
@Kiara Dan 3 karaktere izin vermemeyi tavsiye ederim, çünkü bazı karakterleri meydan okumada tutuyor, ayrıca harflerin kod noktaları ile zorla zekice.
lirtosiast

Yanıtlar:


8

Python 3 , 135 bayt

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

Çevrimiçi deneyin!

Kevin Cruijssen sayesinde -2 bayt

açıklama

'B'nin yanında bulunursa, tüm' v 'yerine' b 'yerine geçer. Ardından, 'a'nın yanında bulunursa tüm' v 'yerine' c 'yerine geçer. Dizinin aktarılmış sürümü ile ikinci bir yineleme, tüm dikey ve çapraz virüsleri temizler. Son olarak, kalan 'v' sayısını döndürür.


Daha okunabilir bir özyinelemeli işlev olarak (155 bayt)


3
Sonra alanı kaldırabilirsiniz y>1else. Güzel yaklaşım olsa. İlk başta bunun diyagonal ile nasıl başa çıkacağından emin değildim b, ancak değiştirmeleriniz nedeniyle bu iyi çalışıyor gibi görünüyor. :) Benden +1.
Kevin Cruijssen

@KevinCruijssen Teşekkürler! Köşegenler, 'b'nin yanındaysa' v 'yerine' a 'değiştirilerek halledilir. İkinci yinelemede, bitişik 'v'ler çıkarılır.
Jitse

3
Aşağıdaki giriş için çıktı 3 olmalı, ancak geri dönen 4 olmalıdır: bvb bav vab vvv vvb vvv vvv bva vav
Kiara Dan


1
@KevinCruijssen Daha da kısa bir tane buldunuz, ancak öneriniz başka bir bayt kazandırıyor!
Jitse

5

JavaScript (ES7), 108 bayt

Girdiyi bir karakter matrisi olarak alır.

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

Çevrimiçi deneyin!

Orijinal cevabıma benzer, ancak yapmak V>'a'>(x-X)**2+y*y-2aslında aşağıda açıklanan altıgen hileyi kullanmaktan 1 bayt daha kısa. ¯ \ _ (ツ) _ / ¯


JavaScript (ES7), 109 bayt

Girdiyi bir karakter matrisi olarak alır.

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

Çevrimiçi deneyin!

Nasıl?

bir1=(x1,y1)bir2=(x2,y2)

S(bir1,bir2)=(x2-x1)2+(y2-y1)2

Tamsayı koordinatları göz önüne alındığında, aşağıdaki gibi görünür:

854585212541145212585458

Bu nedenle:

  • bir1bir2S(bir1,bir2)<2
  • bir1bir2S(bir1,bir2)<3

238

  • bir16-810=210
  • B16-810=310

Yorumlananlar

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

teşekkürler @Arnauld, kodu da açıklayabilir misiniz?
Kiara Dan

3
@KiaraDan Bitti.
Arnauld

3

05AB1E , 33 30 29 bayt

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

Çevrimiçi deneyin veya birkaç test vakasını doğrulayın .

Port of @Jitse 's Python 3 yanıtı , bu yüzden onu oyladığınızdan emin olun! @Jitse
sayesinde -1 bayt .

Açıklama:

Eski sürümün avantajı, yeni sürümün açık bir şekilde ihtiyaç duyduğu bir dize listesini zip / transpoze edebilmesidir. S ve Jsadece karakter listeleriyle çalıştığı için. Ancak, yeni sürüm, daha €Âkısa bir sıkıştırılmış dize ile birlikte kullanılarak hala 3 bayt daha kısadır. Eski sürümde, yalnızca son değeri haritanın içindeki yığında tutar, ancak yeni sürümde, haritanın içindeki yığındaki tüm değerleri tutar.

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

Bu 05AB1E madenin ucu (Bknz kompres dizeleri sözlükte parçası değil? Nasıl ) anlamak için.•s¯}˜?• olduğunu "vbvabbca".


Buna gerek yok bc=> baEğer uygularsanız bv=> baönce av=> ac. Böylece .•6øнãI•("bvavbaac" ın sıkıştırılmış şekli) yeterlidir, 2 bayt tasarrufu sağlar.
Grimmy

@Grimy Ancak son test durumu için 3 yerine 1 sonucunu verir .
Kevin Cruijssen

1
Üç yerine @KevinCruijssen iki yedek adımlar görünüyor hile yapmak sonuçta
Jitse

@ Teşekkürler. Sıkıştırma dizesi 2 bayt daha kısa, ama şimdi .:( :artık mevcut olana kadar tüm değiştirmeye devam ) yerine (tümünü bir kez değiştirin) gerekir. Yine de -1. :) Bilmeme izin verdiğin için teşekkürler.
Kevin Cruijssen

2

Java 10, 211 209 bayt

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

Tüm sekizli mücadeleye cevabımın değiştirilmesi . @Ceilingcat
sayesinde -2 bayt .

Çevrimiçi deneyin.

Açıklama:

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

1

Odun kömürü , 39 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

WS⊞υι≔⪫υ⸿θPθ

Giriş dizelerini \rkarakterlerle birleştirin ve sonucu tuvale çizin.

≔⁰η

Canlı virii sayısını temizleyin.

Fθ«

Girişteki karakterlerin üzerine gelin.

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

Şimdiki karakter bir virüstür ve bherhangi bir yönde bitişik s yoksa adikey olarak s varsa canlı virii sayısını artırın.

ι»

Bir sonraki karakterle tekrarlayın.

⎚Iη

Tuvali temizleyin ve toplam canlı virii sayısını yazdırın.


1

Perl ( -00lp), 82 bayt

vBoşluk ile değiştirmek için normal ifadeyi kullanarak , ardından vs

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

TIO

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.