바이러스 대 해독제 코드 골프 [닫기]


12

'v'로 표시되는 바이러스, antidote1은 'a'로 표시되고 antidote2는 'b'로 표시되는 직사각형 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
편집 해 주셔서 감사합니다 @ 그림-또한 좋은 도전 :)
pixma140

2
@KevinCruijssen, 그것은 불규칙한 모양이 아닙니다.
키아라 단

4
"v", "a"및 "b"대신 3 (고유 한) 임의의 값을 사용할 수 있습니까?
attinat

2
안티 바이러스가 줄 바꿈합니까 (즉, 맨 아래 줄의 "a"가 맨 위 줄의 "v"를 제거함)?
Brian

2
@Kiara Dan 나는 문자의 코드 포인트를 사용하여 강요된 영리함뿐만 아니라 도전에 일부 문자를 유지하기 때문에 3 개의 고유 한 값을 허용하지 않는 것이 좋습니다.
lirtosiast

답변:


8

파이썬 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')

온라인으로 사용해보십시오!

Kevin Cruijssen 덕분에 -2 바이트

설명

'b'옆에있는 경우 모든 'v'를 'b'로 바꿉니다. 다음으로 'a'옆에있는 경우 모든 'v'를 'c'로 바꿉니다. 조옮김 된 버전의 어레이를 두 번 반복하면 모든 수직 및 대각선 바이러스가 지워집니다. 마지막으로, 나머지 'v'수를 반환합니다.


더 읽기 쉬운 재귀 함수 (155 바이트)


3
뒤에 공백을 제거 할 수 있습니다 y>1else. 그래도 좋은 접근 방식입니다. 처음에는 이것이 대각선을 어떻게 처리하는지 잘 모르겠지만 b교체로 인해 제대로 작동하는 것 같습니다. :) +1입니다.
Kevin Cruijssen

@KevinCruijssen 감사합니다! 대각선이 'b'옆에 있으면 'v'를 'a'로 바꾸어 처리합니다. 두 번째 반복에서는 인접한 'v'가 제거됩니다.
Jitse

3
다음 입력의 경우, 출력은 3 일,해야하지만 그 4를 반환 : BVB BAV VAB VVV Vvb와 VVV VVV BVA VAV
키아라 댄


1
@KevinCruijssen 더 짧은 것을 찾았지만 제안은 다른 바이트를 절약합니다!
Jitse

5

자바 스크립트 (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실제로 아래에 설명 된 hexa trick을 사용하는 것보다 1 바이트가 짧습니다. ¯ \ _ (ツ) _ / ¯


자바 스크립트 (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

온라인으로 사용해보십시오!

어떻게?

1=(엑스1,와이1)2=(엑스2,와이2)

(1,2)=(엑스2엑스1)2+(와이2와이1)2

정수 좌표를 고려하면 다음과 같습니다.

854585212541145212585458

따라서:

  • 12(1,2)<2
  • 12(1,2)<

28

  • 16810=210
  • 16810=10

댓글

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에게 감사드립니다. 코드도 설명해 주시겠습니까?
Kiara Dan

3
@KiaraDan은 끝났다.
Arnauld

3

05AB1E , 33 30 29 바이트

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

온라인으로 시도 하거나 몇 가지 테스트 사례를 확인하십시오 .

@Jitse 의 Python 3 답변 포트이므로 그를 투표 하십시오! @Jitse
덕분에 -1 바이트 .

설명:

레거시 버전은 압축 할 수있는 장점이있다 / 새 버전이 명시를해야하는 문자열 목록, 트랜스 S그리고 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=> 가 필요하지 않습니다 . 따라서 ( "bvavbaac"의 압축 된 형태) 충분하며 2 바이트를 절약합니다. babvbaavac.•6øнãI•
Grimmy

@Grimy 그러나 마지막 테스트 사례 에서는 3 대신 3이됩니다 .
Kevin Cruijssen

1
대신 세 @KevinCruijssen이 교체 단계를 보인다 트릭을 할 결국
Jitse

@Jitse 감사합니다. 압축 문자열은 2 바이트 더 짧지 만 이제는 .:( :더 이상 존재하지 않을 때까지 모두 교체하십시오 ) 대신 ( 한 번 교체하십시오) 필요합니다 . 그래도 여전히 -1입니다. :) 알려 줘서 고마워.
Kevin 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;}

모든 싱글 여덟 도전에 대한 내 대답의 수정 . @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어떤 방향으로 또는 a직교로 인접한 s 가 없다면 라이브 virii의 수를 늘리십시오.

ι»

다음 문자로 반복하십시오.

⎚Iη

캔버스를 지우고 총 라이브 비리 수를 인쇄하십시오.


1

펄 ( -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.