ウイルス対解毒剤コードゴルフ[終了]


11

「v」で示されるウイルス、「a」で示されるantidote1、および「b」で示されるantidote2を含む長方形の2D配列があります(「v」、「a」、および「b」以外の値はありません)。

Antidote1は水平方向と垂直方向の隣接ウイルスのみを殺すことができますが、antidote2は水平方向、垂直方向、対角線方向の隣接する(もしあれば)ウイルスを殺すことができます。

解毒剤が有効になったら、最後にいくつのウイルスが残りますか?

例:

入力:

vv
vv

出力:4

入力:

av
vv

出力:1

入力:

vvv
vbv
vvv

出力:0

入力:

bvb
bav
vab
vvv
vvb
vvv
vvv
bva
vav

出力:3


2
@Grimyの編集に感謝します-また素晴らしいチャレンジ:)
— pixma140

2
@KevinCruijssen、不規則な形ではありません。
— キアラダン

4
「v」、「a」、「b」の代わりに3つの(異なる)任意の値を取ることができますか?
— attinat

2
アンチウイルスは折り返しますか(つまり、下の行の「a」は上の行の「v」を削除します)?
— ブライアン

2
@Kiara Dan 3つの異なる値を許可しないことをお勧めします。これは、チャレンジでキャラクターを保持するだけでなく、文字のコードポイントを使って強制的に賢くするためです。
— リトシアスト

回答:


8

Python 3、135バイト

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

オンラインでお試しください!

-2バイト、Kevin Cruijssenのおかげ

説明

「b」の横にある場合、すべての「v」を「b」に置き換えます。次に、「a」の横にある場合、すべての「v」を「c」に置き換えます。配列の転置バージョンでの2回目の反復により、すべての垂直ウイルスと対角ウイルスがクリアされます。最後に、残りの「v」の数が返されます。


より読みやすい再帰関数として(155バイト)


3
後にスペースを削除できy>1elseます。いいアプローチだ。最初はb、これが対角線をどのように扱うのかわかりませんでしたが、それはあなたの置き換えのためにうまくいくようです。:)私からの+1。
— ケビンCruijssen

@KevinCruijssenありがとう!対角線は、「b」の隣にある場合、「v」を「a」に置き換えることで処理されます。2回目の反復では、隣接する「v」が削除されます。
— Jitse

3
次の入力では、出力は3である必要がありますが、4を返します:bvb bav vab vvv vvb vvv vvv bva vav
— Kiara Dan


1
@KevinCruijssenさらに短いものを見つけましたが、あなたの提案は別のバイトを節約します!
— Jitse

5

JavaScript(ES7)、108バイト

入力を文字のマトリックスとして受け取ります。

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

オンラインでお試しください!

私の元の答えに似ていますが、V>'a'>(x-X)**2+y*y-2実際に行うことは、以下で説明するヘキサトリックを使用するよりも1バイト短くなります。¯\ _(ツ)_ /¯


JavaScript(ES7)、109バイト

入力を文字のマトリックスとして受け取ります。

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

オンラインでお試しください!

どうやって?

quadrance 2点のと次のように定義されます。A1=(x1,y1)A2=(x2,y2)

Q(A1,A2)=(x2−x1)2+(y2−y1)2

整数座標を考慮すると、次のようになります。

854585212541∙145212585458

したがって:

  • あるタイプA解毒剤は、場合、あるウイルスを殺すことができます。A1A2Q(A1,A2)<2
  • あるタイプBの解毒剤は、場合、あるウイルスを殺すことができます。A1A2Q(A1,A2)<3

便利なことに、この排他的な上限(または)は、解毒文字を16進数から10進数に変換し、を減算することで取得できます。238

  • A16−810=210
  • B16−810=310

コメント済み

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に感謝します。コードも説明できますか?
— キアラダン

3
@KiaraDan完了。
— アーナルド

3

05AB1E、33 30 29 バイト

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

オンラインそれを試してみたり、さらにいくつかのテストケースを検証します。

@JitseのPython 3回答のポートです。必ず彼に賛成してください!@Jitseの
おかげで-1バイト。

説明:

従来のバージョンには、文字列リストを圧縮/転置できるという利点があります。新しいバージョンでは、文字リストでのみ機能するため、明示的なSand が必要になりJます。ただし、新しいバージョンは€Â、短い圧縮文字列と組み合わせて使用することにより、まだ3バイト短くなっています。従来のバージョンで€は、マップ内のスタックの最後の値のみを保持していましたが、新しいバージョンでは、マップ内のスタックのすべての値を保持します。

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

この05AB1E鉱山の先端を参照してください(セクション圧縮文字列の辞書の一部ではないにどのように?)理由を理解すること.•s¯}˜?•です"vbvabbca"。


=>の前に=> を適用する場合、bc=> は不要baです。したがって、(「 "bvavbaac"の圧縮形式」)で十分であり、2バイトを節約できます。bvbaavac.•6øнãI•
— グリムミー

@Grimy ただし、最後のテストケースでは3ではなく1になります。
— ケビンCruijssen

1
代わりに3の@KevinCruijssen 2つの置換手順は、ように見えるトリックを行うすべての後に
— Jitse

@Jitseありがとう。圧縮文字列は2バイト短くなっていますが、.:(すべてが一度:存在しなくなるまですべて置換し続ける)の代わりに(すべて一度置換する)必要になりました。それでも-1。:) 知らせてくれてありがとうございます。
— ケビンCruijssen

2

Java 10、211 209バイト

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

All the single eightsチャレンジに対する私の答えの修正。@ceilingcatの
おかげで-2バイト。

オンラインでお試しください。

説明:

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

炭、39バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

WS⊞υι≔⪫υ⸿θPθ

入力文字列を\r文字で結合し、結果をキャンバスに描画します。

≔⁰η

ライブviriiの数をクリアします。

Fθ«

入力内の文字をループします。

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

現在のキャラクターがウイルスでb、どの方向にもasが直交して隣接していない場合、ライブviriiの数を増やします。

ι»

次の文字で繰り返します。

⎚Iη

キャンバスをクリアし、ライブviriiの総数を印刷します。


1

Perl(-00lp)、82バイト

正規表現を使用vしてスペースで置き換えてから、vsをカウントする

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

TIO

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.