Golf vs Virus kode penangkal [ditutup]

12

Ada array 2D persegi panjang yang mengandung virus yang dilambangkan dengan 'v', penangkal1 dilambangkan dengan 'a', dan penawar2 dilambangkan dengan 'b' (tidak ada nilai selain 'v', 'a' dan 'b').

Antidote1 dapat membunuh virus tetangga hanya dalam arah horisontal dan vertikal, tetapi penangkal2 dapat membunuh virus tetangga (jika ada) dalam arah horizontal, vertikal dan diagonal.

Setelah penangkal diaktifkan, berapa banyak virus yang akan tetap ada pada akhirnya?

Contoh:

Memasukkan:

vv
vv

Output: 4

Memasukkan:

av
vv

Output: 1

Memasukkan:

vvv
vbv
vvv

Output: 0

Memasukkan:

bvb
bav
vab
vvv
vvb
vvv
vvv
bva
vav

Output: 3

Kiara Dan
sumber
2
Saya menghargai suntingan Anda @Grimy - Tantangan juga bagus :)
pixma140
2
@KevinCruijssen, tidak berbentuk tidak teratur.
Kiara Dan
4
Bisakah kita mengambil 3 nilai arbitrer (berbeda) alih-alih "v", "a", dan "b"?
attinat
2
apakah anti-virus membungkus (yaitu, "a" di baris bawah akan menghapus "v" di baris atas)?
Brian
2
@ Kim Dan Saya akan menyarankan tidak mengizinkan 3 nilai yang berbeda, karena membuat beberapa karakter dalam tantangan, serta mungkin kepintaran paksa dengan poin kode huruf.
lirtosiast

Jawaban:

8

Python 3 , 135 byte

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

Cobalah online!

-2 byte terima kasih kepada Kevin Cruijssen

Penjelasan

Ganti semua 'v' ke 'b' jika ditemukan di sebelah 'b'. Selanjutnya, ganti semua 'v' ke 'c' jika ditemukan di sebelah 'a'. Iterasi kedua dengan versi array yang dipindahkan menghapus semua virus vertikal dan diagonal. Akhirnya, ia akan mengembalikan jumlah 'v's yang tersisa.


Sebagai fungsi rekursif yang lebih mudah dibaca (155 byte)

Jitse
sumber
3
Anda dapat menghapus ruang setelah y>1else. Pendekatan yang bagus. Pada awalnya saya tidak yakin bagaimana ini berurusan dengan diagonal b, tetapi itu tampaknya berfungsi dengan baik karena penggantian Anda. :) +1 dari saya.
Kevin Cruijssen
@KevinCruijssen Terima kasih! Diagonal diurus dengan mengganti 'v' dengan 'a' jika berada di sebelah 'b'. Di iterasi kedua, 'v's yang berdekatan kemudian dihapus.
Jitse
3
Untuk input berikut, output harus 3, tetapi mengembalikan 4: bvb bav vabvv vvv vvv vvv bva vav
Kiara Dan
1
@KevinCruijssen Menemukan yang lebih pendek, tetapi saran Anda menghemat satu byte lagi!
Jitse
5

JavaScript (ES7), 108 byte

Mengambil input sebagai matriks karakter.

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

Cobalah online!

Mirip dengan jawaban asli saya, tetapi melakukan V>'a'>(x-X)**2+y*y-2sebenarnya 1 byte lebih pendek daripada menggunakan trik hexa yang dijelaskan di bawah ini. ¯ \ _ (ツ) _ / ¯


JavaScript (ES7), 109 byte

Mengambil input sebagai matriks karakter.

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

Cobalah online!

Bagaimana?

SEBUAH1=(x1,y1)SEBUAH2=(x2,y2)

Q(SEBUAH1,SEBUAH2)=(x2-x1)2+(y2-y1)2

Mempertimbangkan koordinat integer, tampilannya sebagai berikut:

854585212541145212585458

Karena itu:

  • SEBUAH1SEBUAH2Q(SEBUAH1,SEBUAH2)<2
  • SEBUAH1SEBUAH2Q(SEBUAH1,SEBUAH2)<3

238

  • SEBUAH16-810=210
  • B16-810=310

Berkomentar

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
sumber
terima kasih @Arnauld, bisakah Anda juga menjelaskan kodenya?
Kiara Dan
3
@ KimaraDan Selesai.
Arnauld
3

05AB1E , 33 30 29 byte

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

Cobalah secara online atau verifikasi beberapa kasus uji lagi .

Port dari @Jitse 's Python 3 menjawab , jadi pastikan untuk mengunggahnya!
-1 byte terima kasih kepada @Jitse .

Penjelasan:

Versi lawas memiliki keuntungan karena dapat mem-zip / mengubah-daftar string, di mana versi baru akan membutuhkan yang eksplisit Sdan J, karena hanya bekerja dengan daftar karakter. Namun, versi baru masih 3 byte lebih pendek dengan menggunakan€Â kombinasi dengan string terkompresi yang lebih pendek. Di versi lawas, hanya akan menyimpan nilai terakhir di tumpukan di dalam peta, tetapi di versi baru, itu akan menyimpan semua nilai di tumpukan di dalam peta.

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

Lihat ini 05AB1E ujung tambang (bagian Cara string kompres bukan bagian dari kamus? ) Untuk memahami mengapa .•s¯}˜?•adalah "vbvabbca".

Kevin Cruijssen
sumber
Anda tidak perlu bc=> bajika Anda menerapkan bv=> basebelum av=>ac . Jadi .•6øнãI•(bentuk terkompresi `" bvavbaac ") sudah cukup, menghemat 2 byte.
Grimmy
@Grimy Menghasilkan 1 bukannya 3 untuk test case terakhir .
Kevin Cruijssen
1
@KevinCruijssen dua langkah pengganti bukannya tiga sepertinya melakukan trik setelah semua
Jitse
@Jitse, terima kasih. String kompresi 2 byte lebih pendek, tetapi saya sekarang perlu .:(ganti semua satu kali) alih-alih :(terus ganti semua sampai tidak ada lagi). Tapi tetap -1. :) Terima kasih telah memberi tahu saya.
Kevin Cruijssen
2

Java 10, 211 209 byte

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

Modifikasi jawaban saya untuk tantangan All the single eights .
-2 byte terima kasih kepada @ceilingcat .

Cobalah online.

Penjelasan:

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

Arang , 39 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

WS⊞υι≔⪫υ⸿θPθ

Gabungkan string input dengan \rkarakter dan gambarkan hasilnya ke kanvas.

≔⁰η

Hapus jumlah virii langsung.

Fθ«

Ulangi karakter dalam input.

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

Jika karakter saat ini adalah virus dan tidak ada yang bersebelahan bdalam arah apa pun atau secara aortogonal maka menambah jumlah virii hidup.

ι»

Ulangi dengan karakter berikutnya.

⎚Iη

Kosongkan kanvas dan cetak jumlah total virii hidup.

Neil
sumber
1

Perl ( -00lp), 82 byte

Menggunakan regex untuk mengganti vdengan spasi, lalu hitung vs

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

TIO

Nahuel Fouilleul
sumber