방화범의 자장가 찾기


26

방화범이 마을을 걸어 다니면서 매우 특정한 패턴에 따라 희생자를 선택 한다고 상상해보십시오 (또는 정원을 날아 다니며 꿀벌이 매우 특정한 패턴에 따라 꽃을 피우는 것을 상상해보십시오 ). 도시가 N × N 행렬 이라고 가정합니다 . 여기서 N2 이상의 정수 입니다. 방화범은 왼쪽 위 모서리에서 시작하여 집 앞에 M 지점을 연속적으로 설정 하고 (여기서 M 은 현재있는 집의 수) 순서대로 각 화재 후 이동 방향을 변경합니다. 동쪽 ⟶ 남쪽 ⟶ 서쪽 ⟶ 북쪽 ⟶ 동쪽 ⟶ 남쪽 ... 등. 자장가방화범의 가치 는 마을을 빠져 나가게하는 M 의 가치이다 . 이것은 예제로 이해하기 쉽습니다. 예를 들어 다음 매트릭스를 사용하십시오.

3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1
  • 우리는 왼쪽 상단에서 시작하므로 M = 3 ( X방화범의 현재 위치와 이전 위치를 표시) :
    X 2 3 2 7
    3 1 4 1 6
    2 5 3 1 1
    4 4 3 2 4
    1 1 1 1
    
  • 알려진 순서에 따르면, 먼저 동쪽 M (3) 지점으로 이동하여 2에 착륙 하므로 M 은 그에 따라 변경됩니다.
    X 2 3 X 7
    3 1 4 1 6
    2 5 3 1 1
    4 4 3 2 4
    1 1 1 1
    
  • 그런 다음 남쪽 2 자리로 가고 M1입니다 .
    X 2 3 X 7
    3 1 4 1 6
    2 5 3 X 1
    4 4 3 2 4
    1 1 1 1
    
  • 이제 서쪽 으로 1 자리 이동 하고 M3 이됩니다 .
    X 2 3 X 7
    3 1 4 1 6
    2 5 XX 1
    4 4 3 2 4
    1 1 1 1
    
  • 북쪽 으로 3 곳 이동 한 후 마을을 빠져 나옵니다! 따라서이 방화범의 자장가는 3 입니다.
        엑스
    X 2 3 X 7
    3 1 4 1 6
    2 5 XX 1
    4 4 3 2 4
    1 1 1 1
    

N × N 행렬이 주어지면 (선택적으로 N 을 입력 으로 취할 수도 있음) 방화범의 자장가를 찾으십시오. 더 많은 테스트 사례를 생성하고 방화범의 경로를 시각화 할 수있는 프로그램을 작성 했습니다. 온라인으로 사용해보십시오!

  • 방화범 에 자장가 있다고 가정 할 수 있습니다 (즉, 실제로 행렬에서 벗어날 수 있음).
  • 이 매트릭스는 단순화를 위해 9 이하의 양의 정수만 포함합니다 . 양의 정수를 처리하는 솔루션은 완전히 환영합니다.
  • 방화범 은 이미 타 버린 지점에 착륙 할 수 있습니다. 이동 방향이 처음과 다른 경우입니다. 이러한 시나리오에서는 해당 요소의 값을 가져와 평소대로 다시 이동하십시오.
  • 모든 프로그래밍 언어로 경쟁 할 수 있으며 표준 방법을 통해 입력을 받고 출력을 제공 할 수 있지만 이러한 허점 은 기본적으로 금지되어 있습니다. 이것은 이므로 모든 언어에 대한 가장 짧은 제출 (바이트)이 이깁니다.

테스트 사례

-------------
9 2 3
1 7 2
8 7 6

자장가 : 9
-------------
2 1 2 1
3 1 1 2
1 2 2 1
1 1 3

자장가 : 2
-------------
3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1

자장가 : 3
-------------
12 2 1 2
12 2 1 2
12 2 1 2
12 2 1 2
12 2 1 2
12 2 1 2

자장가 : 2
-------------
3 2 1 2 1 1 1
2 3 2 3 2 1 1
2 1 1 3 1 2
3 1 1 1 1 1 1
4 5 2 3 1 1 1
12 2 1 2 2
12 2 3 2 1 2

자장가 : 3
-------------

다른 형식의 행렬 :

[[9, 2, 3], [1, 7, 2], [8, 7, 6]]
[[2, 1, 2, 1], [3, 1, 1, 2], [1, 2, 2, 1], [1, 1, 1, 3]]
[[3, 2, 3, 2, 7], [3, 1, 4, 1, 6], [2, 5, 3, 1, 1], [4, 4, 3, 2, 4], [ 1, 1, 1, 1, 1]]
[[1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2]]
[[3, 2, 1, 2, 1, 1, 1], [2, 3, 2, 3, 2, 1, 1], [2, 1, 1, 1, 3, 1, 2], [ 3, 1, 1, 1, 1, 1, 1], [4, 5, 2, 3, 1, 1, 1], [1, 2, 1, 2, 1, 2, 2], [1, 2, 2, 3, 2, 1, 2]]

다섯 번째 테스트 사례는 시각화하는 데 매우 흥미 롭습니다 .


1
이것은 약간 다른 목표를 가지고, 토끼처럼 스킵 을 2 차원 으로 일반화하는 것과 같습니다 . 이 도전의 주제와 제목은 Hozier의 노래
Mr. Xcoder

방화범이 이미 불타고있는 광장에 착륙하면 어떻게됩니까?
Level River St

2
방화범이 실제로 방화범이 아니라 대신 각 장소에서 좋은 일을하고 있다고 가정 할 수 있습니까? 아주 좋은 생각 :) +1
ElPedro

2
@ElPedro Sure, 당신을위한 대체 버전 : 꿀벌이 정원을 날고 꽃을 따서 특정 패턴에 따라 꽃가루를 뽑는다 고 상상해보십시오. : D 행복한 골프!
Mr. Xcoder

1
훨씬 더 좋은 생각입니다. 다시 투표 할 수 있다면 그렇게 할 것입니다.
ElPedro

답변:


11

MATL , 32 바이트

JQ6*`G5thYay&Zj3$)wyJ2@-^*+8M]b&

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

작동 원리

입력 매트릭스는 5 개의 0으로 채워집니다. 예를 들어

3 2 3 2 7
3 1 4 1 6
2 5 3 1 1
4 4 3 2 4
1 1 1 1 1

된다

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 3 2 3 2 7 0 0 0 0 0
0 0 0 0 0 3 1 4 1 6 0 0 0 0 0
0 0 0 0 0 2 5 3 1 1 0 0 0 0 0
0 0 0 0 0 4 4 3 2 4 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0의 프레임은 방화범 꿀벌이 언제 매트릭스를 나왔는지 감지하는 데 사용됩니다 . 0이 5 개인 확장 은 0이 아닌 항목에서 임의의 방향으로 길이 의 모듈 식 변위가 90이 아닌 항목을 감싸지 않고 정확하게 0에 도달합니다.

행렬 좌표에서 벌은 (6,6)확장 된 행렬의 시작 부분에서 시작합니다 . 해당 항목을 읽고 필요한 방향으로 읽기 길이의 (모듈 식) 변위를 적용하여 좌표를 업데이트합니다. 판독 값이 0이 될 때까지 루프에서 반복됩니다 0. 해당 항목 이전에 읽은 항목 (즉, 0이 아닌 마지막 항목)이 출력입니다.

좌표는 실제로 복소수로 저장되므로 예를 들어 (6,6)됩니다 6+6j. 이러한 방식으로, 4 개의 순환 방향은 가상 유닛의 힘으로서 실현 될 수있다. 대응하는 전력 ( j, 1, -j또는 -1) 좌표를 갱신하는 데 사용되는 복잡한 변위를 획득하기 위해 판독 항목에 의해 곱해진다.

연속적으로 읽은 값은 스택에 유지됩니다. 루프가 종료되면 스택에는 0이 아닌 모든 판독 값이 순서대로 포함 된 다음 마지막 판독 값이되며 0가장 최근의 복잡한 좌표가 포함됩니다. 따라서 세 번째 상단 요소는 필요한 출력입니다.


1
매우 혁신적인 접근 방식을 위해 +1.
LastStar007

7

자바 스크립트 (ES6), 70 68 바이트

m=>(g=d=>(n=(m[y]||0)[x])?g(--d&3,x-=d%2*(y+=--d%2*n,L=n)):L)(x=y=0)

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

댓글

m => (                        // given m = input matrix
  g = d =>                    // g = recursive function taking the direction d
    (n = (m[y] || 0)[x]) ?    // let n be the content of the current cell; if it's defined:
      g(                      //   do a recursive call:
        --d & 3,              //     with the next direction (0 = E, 3 = S, 2 = W, 1 = N)
        x -=                  //     update x by subtracting ...
          d % 2 * (           //       ... ((d - 1) % 2) * n
            y += --d % 2 * n, //       and update y by adding ((d - 2) % 2) * n
            L = n             //       save n into L
          )                   //     end of x update
      )                       //   end of recursive call
    :                         // else:
      L                       //   stop recursion and return L
)(x = y = 0)                  // initial call to g() with x = y = d = 0

JS에서 모듈로의 부호가 피제수의 부호라고 가정하면 방향은 다음과 같이 업데이트됩니다.

 d | d' = --d&3 | dx = -(d%2)  | dy = --d%2 | direction
---+------------+--------------+------------+------------------
 0 |     3      | -(-1%2) = +1 | -2%2 =  0  | (+1,  0) = East
 3 |     2      | -( 2%2) =  0 |  1%2 = +1  | ( 0, +1) = South
 2 |     1      | -( 1%2) = -1 |  0%2 =  0  | (-1,  0) = West
 1 |     0      | -( 0%2) =  0 | -1%2 = -1  | ( 0, -1) = North

4

, 25 18 바이트

PS↶WKK«≔ιθ×Iι¶↷»⎚θ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

PS

입력 문자열을 인쇄하되 인쇄 위치를 이동하지 마십시오.

인쇄 방향이 위로 오도록 피벗을 왼쪽으로 돌립니다.

WKK«

인쇄 위치 아래에 문자가있는 동안 반복하십시오.

≔ιθ

문자를 변수에 저장하십시오.

×Iι¶

문자를 숫자로 변환하고 많은 줄 바꿈을 인쇄하십시오. 인쇄 방향이 위로 올라가면 가로로 인쇄됩니다. 결론은 인쇄 위치 아래의 숫자로 주어진 양만큼 인쇄 위치를 원하는 방향으로 이동했다는 것입니다.

↷»

다음 줄 바꾸기가 루프의 다음 패스에 대해 다음 방향으로 인쇄 위치를 시계 방향으로 이동하도록 피벗을 돌립니다.

F⟦ωθ⟧¿ιι⎚

불행히도 우리는 여전히 캔버스를 어지럽히는 입력을 가지고 있으며, 불행히도 캔버스를 지우면 변수도 지 웁니다. 따라서 이것은 약간의 트릭입니다. 빈 문자열 목록과 변수가 반복됩니다. 루프의 첫 번째 패스에서 루프 변수는 비어 있으므로 캔버스와 루프 변수 및 결과 변수가 모두 지워집니다. 그러나 루프는 끝나지 않았습니다! 루프의 두 번째 패스에서 루프 목록에 신중하게 보존 된 변수에 계속 액세스 할 수 있습니다. 인쇄 만하면됩니다.

⎚θ

캔버스를 지우고 저장된 변수를 인쇄하십시오. (Charcoal에 대한 수정은 @ASCII에만 감사합니다.)



2

, 50 49 46 34 33 26 바이트

NθEθSMθ↑WKK«MIι✳⊗Lυ⊞υι»⎚⊟υ

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

자세한 코드 버전으로 연결되는 링크

입력은 자체 행에서 N 이어야 하고 그 후에 배열의 행은 별도 행에 있어야합니다.

나는 Charcoal의 좋은 골퍼가 아니기 때문에 바이트를 녹이는 방법을 환영합니다.

@Neil 덕분에 -12 바이트! @ASCII 전용 덕분에 -1 바이트! @ASCII 전용으로 인해 -7 바이트 ( Clear재설정 변수 를 만드는 버그가 변경됨 )


1

빨강 , 145 바이트

func[b][h:[0 1 0 -1 0]x: y: 1 i: 0
until[y: h/(i: i % 4 + 1) *(t: b/(y)/(x)) + y x: h/(i + 1) * t + x none = b/(y) or(x < 1 or(x > length? b))]t]

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

더 읽기 쉬운 :

f: func[b][
    h: [0 1 0 -1 0]                                ; step lengths (combined for x and y) 
    x: y: 1                                        ; starting coords (1,1)
    i: 0                                           ; step counter 
    until[
        y: h/(i: i % 4 + 1) * (t: b/(y)/(x)) + y   ; next y; t stores the lullaby
        x: h/(i + 1) * t + x                       ; next x
        none = b/(y) or (x < 1 or (x > length? b)) ; until x or y are not valid indices
    ]
    t                                              ; return the lullaby
]


1

클린 , 141 바이트

import StdEnv
d=[0,1,1,0,0,-1,-1,0:d]
$m[x,y]n[a,b:l]#r=size m
#u=x+a*n
#v=y+b*n
|0>u||0>v||u>=r||v>=r=n= $m[u,v]m.[u,v]l
?m= $m[0,0]m.[0,0]d

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

? :: {#{#Int}} -> Intunboxed 정수 배열의 unboxed 배열을 가져 와서 결과를 반환 하는 함수를 정의합니다 .


1

자바 8, 121 바이트

m->{int l=m.length,x=0,y=0,f=0,r=0;for(;x*y>=0&x<l&y<l;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];return r;}

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

동일한 121 바이트의 바이트 수를 가진 대안 :

m->{int l=m.length,x=0,y=0,f=0,r=0;try{for(;;x+=f<1?r:f==2?-r:0,y+=f==1?r:f>2?-r:0,f=++f%4)r=m[y][x];}finally{return r;}}

x,y-coordinate가 여전히 범위 내에 있는지 확인하는 대신 try-finally를 사용 합니다.

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

설명:

m->{                   // Method with integer-matrix parameter and integer return-type
  int l=m.length,      //  Dimensions of the matrix
      x=0,y=0,         //  x,y coordinate, starting at [0,0]
      f=0,             //  Direction-flag, starting at 0 (east)
      r=0;             //  Result-integer
  for(;x*y>=0&x<l&y<l  //  Loop as long as the x,y coordinates are still within bounds
      ;                //    After every iteration:
       x+=f<1?         //     If the direction is east:
           r           //      Increase the `x` coordinate by `r`
          :f==2?       //     Else-if the direction is west:
           -r          //      Decrease the `x` coordinate by `r`
          :            //     Else (it's north/south):
           0,          //      Leave the `x` coordinate the same
       y+=f==1?        //     If the direction is south:
           r           //      Increase the `y` coordinate by `r`
          :f>2?        //     Else-if the direction is north:
           -r          //      Decrease the `y` coordinate by `r`
          :            //     Else:
           0,          //      Leave the `y` coordinate the same
       f=++f%4)        //     Go to the next direction (0→1→2→3→0)
    r=m[y][x];         //   Set `r` to the value of the current cell
  return r;}           //  Return the last `r` before we went out of bounds

0

펄 5 , 92 바이트

sub b{1while eval join'&&',map{/./;map"(\$$_$&=".'$n=$_[$y][$x])'.$',x,'y'}'+<@_','->=0';$n}

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

방법?

중첩 된 맵 세트와 결합은 다음을 생성합니다.

($x+=$n=$_[$y][$x])<@_&&($y+=$n=$_[$y][$x])<@_&&($x-=$n=$_[$y][$x])>=0&&($y-=$n=$_[$y][$x])>=0

루프가 종료되는지 판별하기 위해 평가됩니다. 부울은 왼쪽에서 오른쪽으로 $n평가되므로 평가 중에 실제로 4 배까지 값이 변경됩니다 (최대). 부울 논리는 Perl에서 단락되기 때문에 $n루프가 종료 될 때의 값은 자장가입니다.


0

파이썬 3 , 85 84 바이트

xcoder : -1 (+ ~ 트릭을 기억하지 않습니다)

def f(x):
 r=c=0
 while-1<r:d=x[r][c];r,c=len(x)-c+~d,r;x=[*zip(*x)][::-1]
 return d

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

서로 다른 방향 (E, S, W, N)으로 이동하는 대신이 솔루션은 항상 동쪽으로 이동하고 매 이동 후 그리드를 시계 반대 방향으로 회전시킵니다. 회전 후 마지막 열은 이제 첫 번째 행이므로 행 인덱스가 0보다 작 으면 보드를 벗어난 것입니다.



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.