미로를 탈출하십시오!


20

이 5x5 미로에 갇혀 있습니다-각 방에는 1에서 25까지 레이블이 있고 출구는 방 1에 있습니다.

여기에 이미지 설명을 입력하십시오

현재있는 방을 입력으로받습니다. 당신의 임무는 방 1에 도달하는 데 필요한 가장 짧은 이동 순서 (북쪽, 동쪽, 남쪽, 서쪽)를 출력하는 것입니다.

문자를 사용하는 한 원하는 형식 (목록, 문자열, 배열 ...)으로 이동을 출력 할 수 있습니다 n,w,e,s.

모든 테스트 사례는 다음과 같습니다.

1 => empty string/list
2 => w
3 => ww
4 => swwnw
5 => wswwnw
6 => seenwnw
7 => nw
8 => wnw
9 => wwnw
10 => swwnwnw
11 => eenwnw
12 => enwnw
13 => nwnw
14 => wnwnw
15 => wwnwnw
16 => enenwnw
17 => nenwnw
18 => wnenwnw
19 => nwnwnw
20 => wnwnwnw
21 => nenenwnw
22 => enwnenwnw
23 => nwnenwnw
24 => wnwnenwnw
25 => nwnwnwnw

바이트 단위의 최단 답변이 승리합니다!


3
회의실 라벨링 / 입력은 얼마나 유연합니까? 1- 인덱스 대신 0- 인덱스를 사용할 수 있습니까? 방 번호를 캐릭터로 사용할 수 있습니까 (36 쪽과 같이 생각)?
Chas Brown

2
@ Therandomguy 아니요,이 특정 미로를 처리해야합니다.
Arnaud

6
가능하기 때문에 가능한 모든 사례를 테스트 사례에 포함시켜야한다고 생각합니다.
Jonathan Frech

1
@UnrelatedString이 질문은 1 개의 입력을 받아서 입력에 따라 다른 경로를 출력합니다. 이 요구 사항이 kolmogorov-complexity 태그에 맞지 않는다고 생각합니다 .
tsh

2
누군가는 미로 에서 답을 제공해야합니다 .
Draco18s

답변:


20

파이썬 2 , 64 바이트

def f(n):d=0x1211252b5375>>2*n-4&3;print"nwes"[d];f(n+d*3+d%2-5)

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

한 줄에 한 방향을 인쇄하여 오류로 종료하는 기능입니다.

상수 0x1211252b5375는베이스 4 d에서 각 방 번호에서 0에서 3까지 이동 하는 방향을 인코딩합니다. 또한 추출 숫자 >>2*n-4&3n=1코드를 종료 할 때 음의 시프트 오류를 ​​발생 시키도록 설계되었습니다 . 우리는 방 번호를 업데이트 n를 통해 오프셋 방향에서 계산의 d같은 d*3+d%2-5매핑 :

d   d*3+d%2-5
0  -> -5
1  -> -1
2  ->  1
3  ->  5 

1
이것이 유효한지 확실하지 않고 함수를 재사용 할 수 있어야 하며이 함수를 호출 한 후 실행을 계속 하려면 오류 트래핑 ( try/ except)이 필요합니다.
Outgolfer Erik


6

05AB1E , 30 29 바이트

소수와 기적의 우연의 일치 덕분에 -1 바이트

[Ð#•θzƶ‰`Ó•4вsè<DˆØ·5-+}'‹™¯è

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

[                      }    # infinite loop:
 Ð                          #  triplicate the room number (initially, the input)
  #                         #  break if room number == 1
   •θzƶ‰`Ó•4в               #  compressed list 202232302231102210202010
             sè             #  use the room number to index into that list
               <            #  decrement
                Dˆ          #  add a copy to the global array
                  Ø         #  nth prime (-1 => 0, 0 => 2, 1 => 3, 2 => 5)
                   ·        #  double
                    5-      #  subtract 5
                      +     #  add that to the room number
'‹™                         # dictionary string "western"
   ¯                        # push the global array
    è                       # index (wraps around, so -1 => n, 0 => w, 1 => e, 2 => s)

1
이것은11 빈 문자열 대신 input을 출력 합니다 (쉬운 수정은 선행을 추가하는 것입니다 õ?). 그 외에도 좋은 대답!
Kevin Cruijssen

1
@KevinCruijssen 그 실수를 지적 해 주셔서 감사합니다! 단일 바이트 수정을 찾았습니다.
그리미

5

루비 , 72 62 바이트

f=->n{n<2?'':' en  sw'[x=4*18139004[n]+6*4267088[n]-5]+f[n+x]}

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

어떻게?

여기서 트릭은 2 개의 상수를 사용하여 각 셀에 대해 다음 단계를 구축 한 다음 재귀 적으로 문제를 해결하는 것입니다.

두 상수 18139004 및 4267088은 각 셀에 대해 두 비트에서 단일 비트를 추출하여 다음 이동 방향을 제공하는 이진 문자열입니다.

"n" = 4*0+6*0-5 = -5
"w" = 4*1+6*0-5 = -1
"e" = 4*0+6*1-5 = +1
"s" = 4*1+6*1-5 = +5

하나의 큰 이진수 IMHO를 이동하고 마스킹하는 것보다 쉽습니다.

방향을 찾으면 문자열 "en sw"에서 해당 문자를 추출합니다.

  1   5
  |   |
" en  sw"
   |   |
  -5  -1

셀 [n + x]에서 재귀 적으로 진행






2

, 43 40 바이트

NθW⊖θ«≔I§”)“⊞x⟧∧⎚⁵2”ιι§nwesι≧⁺⁻⁺﹪ι²×³ι⁵θ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. @ChasBrown과 @xnor의 답변을 모두 기반으로합니다. 설명:

Nθ

방을 입력하십시오.

W⊖θ«

루프 변수 i를 룸 번호보다 하나 작게 설정하고 0이 아닌 동안 반복하십시오.

«≔I§”)“⊞x⟧∧⎚⁵2”ιι

압축 된 문자열에서 방향을 추출하십시오 0113130113220112010102010. (리딩 0은 단지 필러 숫자입니다.)

§nwesι

방향을 인쇄하십시오.

≧⁺⁻⁺﹪ι²×³ι⁵θ

@xnor의 공식을 사용하여 새 방 번호를 계산하십시오.


2

젤리 , 30 29 바이트

“þ&ƊĿñ÷°e’b6Ḥ_5Ż⁸+ị¥ƬI‘ị“®ȯẹ»

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

시작 셀을 가져 와서 지시 사항이있는 문자열을 리턴하는 모나드 링크.

그것에 색인과 함께이 때문에 나는 젤리의 사전이 여기에 사용 된 '케네 소'(애틀랜타의 도시 북서쪽, 조지아)와 같은 단어를 가지고 있다는 사실을 사랑 [5, 1, -5, -1] + 1제공nesw !

설명

“þ...e’                    | Base-250 integer 1962789844189344852  
       b6                  | Convert to base 6 (2, 2, 5, 2, 5, 0, 2, 2, 5, 3, 3, 0, 2, 2, 3, 0, 2, 0, 2, 0, 3, 0, 2, 0)
         Ḥ                 | Double
          _5               | Subtract 5
            Ż              | Prepend 0
             ⁸  ¥Ƭ         | Using this as the right argument and the original link argument as the left argument, loop the following as a dyad until there is no change, collecting up results
              +            | - Add the left argument to:
               ị           |   - The left argument indexed into the right argument
                  I        | Differences between consecutive numbers
                   ‘       | Increment by 1
                    ị“®ȯẹ» | Index into "Kennesaw"

2

PHP , 110 바이트

Chas Brown의 훌륭한 답변 이나 xnor의 훌륭한 답변 항구가 아닌 솔루션 . 나는 이것이 더 길다는 것을 알고 있지만 다른 해결책을 원했습니다!

for($n=$argn;$n>1;$n=ord($s[$n*2+1])%30)echo($s='0000w<w sEw"s)n w%w&s-e*e+n&w+w,e/n*w/n,w1n.e5n0w5n2')[$n*2];

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

보드의 모든 셀에 2 문자를 갖는 매핑 문자열을 만들었습니다. 각 셀의 첫 번째 문자는 이동 (n / e / s / w) 또는0 두 번째 문자의 ASCII 코드 mod 30은 셀을 종료 할 때까지 재귀 모드에서 이동해야하는 다른 셀 번호를 반환합니다 ( cell < 2).

예를 들어 8을 입력하는 경우

  • 셀의 경우 2 자 8 는 다음과 같습니다.w%
  • 인쇄를 의미합니다 w 세포의 움직임을 하고 계속하는%
  • ASCII 코드 % 는 37이며 mod 30은 7이되므로 다음 셀은 7입니다.
  • 셀의 경우 2 자 7 에 : n (마지막 문자는 공백, ASCII 코드 = 32)
  • 인쇄를 의미합니다 n 32 모드 30의 셀에 대한 를 계속하고를2 합니다.
  • 셀의 경우 2 자 2 는 다음과 같습니다 w<(마지막 문자 ASCII 코드 = 60).
  • 그것은 w60 모드 30의 셀에 대한 인쇄 를 계속하고 이동을 의미합니다.0 합니다.
  • 셀 번호가 작은 경우 2 루프가 중지됩니다!
  • 최종 인쇄 결과 : wnw

PHP , 75 바이트

이 버전은 Grimy 에 의해 작성되었으며 똑똑하기 때문에 원래의 답변보다 35 바이트 짧습니다! Grimy의 의견 : "4 * 25 <256이므로 셀당 1 바이트 만 필요하며 2 개는 필요하지 않습니다"

for($n=$argn;$n=ord("0\0~f;6o4R:s%ql&rup*@^tIDbx"[$n%25]);)echo news[$n%4];

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


PHP , 71 바이트

Arnauld의 답변 포트는 xnor의 답변 포트 이지만 재귀 함수 대신 루프로 PHP에서 더 짧아지기 때문에 루프로 사용됩니다.

for($n=$argn;--$n;$n+=$d*3+$d%2-4)echo nwes[$d=79459389361621/4**$n&3];

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


2
4 * 25 <256이므로 2 개가
그리미

1
@Grimy, amazing, 별도의 답변으로 게시해야한다고 생각합니다. 충분합니다.
밤 2

1
나는 그것을하지 않을 것이므로, 당신은 당신의 답변에 그것을 포함 시킬지 아니면 단지 의견으로 남겨 둘지를 선택합니다.
그리미

1
@Grimy, 이름으로 버전을 추가했습니다. 어쨌든 고마워.
Night2

2

C (클랑) , 81 바이트

v;f(p){p-1&&putchar(v="00wwswsnwwseenwwenwnwnenwn"[p])+f(p+=v%5?6-v%8:v%2?5:-5);}

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

@ Tommylee2k 제안 -8 덕분에! + 재귀 호출

C (클랑) , 90 바이트

v;f(p){for(char*l="00wwswsnwwseenwwenwnwnenwn";p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v=l[p]);}

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

압축되지 않은 모든 솔루션과 유사합니다.


1
단축 될 수 있습니다 :v;f(p){for(;p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v="00wwswsnwwseenwwenwnwnenwn"[p]);}
Tommylee2k

1

05AB1E , 45 43 바이트

õ?[Ð#.•DUo¢ê`Ω÷‰₂¡)R€ûK•¦sè©?Ž₁9₂в6-'€Ã®kè+

@ChasBrown 의 Python 2 답변 포트 .

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

설명:

õ?               # Output an empty string
                 # (to overwrite the implicit output if the input is 1)
[                # Start an infinite loop:
 Ð               #  Triplicate the top of the stack
                 #  (which is the (implicit) input in the first iteration)
  #              #  If it's exactly 1: stop the infinite loop
  .•DUo¢ê`Ω÷‰₂¡)R€ûK
                 #  Push compressed string "a  wwswsnwwseenwwenwnwnenwn"
   ¦             #  Remove the first character
    sè           #  Swap to get the number, and use it to index into the string
      ©          #  Store it in variable `®` (without popping)
       ?         #  Print it without trailing newline
  Ž₁9            #  Push compressed integer 22449
     ₂в          #  Convert to base-26 as list: [1,7,5,11]
       6-        #  Subtract 6 from each: [-5,1,-1,5]
         '€Ã    '#  Push dictionary string "news"
            ®k   #  Get the index in this string of character `®`
              è  #  And use that to index into the integer-list
               + #  And add it to the originally triplicated integer

내 (전 4 절)이 05AB1E 팁을 참조하십시오 이유를 이해하기 위해 .•DUo¢ê`Ω÷‰₂¡)R€ûK•입니다 "a wwswsnwwseenwwenwnwnenwn"; Ž₁9이다 22449; Ž₁9₂в이다 [1,7,5,11]; 하고 '€Ã있다 "news".


1
그 편리한 사전 문자열은 좋은 소식이었을 것입니다!

@Neil 확실히. :) 분명히 사전 문자열 western이 더 좋습니다. ; p
Kevin Cruijssen

1

세게 때리다 , 120 바이트

S=__wwswsnwwseenwwenwnwnenwn
N=n-5w-1s05e01
for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

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

문자열을 니블로 비트 패킹하려고 시도하면서 잠시 놀았 지 만 디코딩에는 저장된 수보다 많은 문자가 필요합니다.

작동 방식 :

S=__wwswsnwwseenwwenwnwnenwn

문자열 $ S는 각 방에 단일 문자 (n, w, s, e)를 보유하여 한 방을 출구쪽으로 이동하기 위해 어느 방향으로 이동해야하는지 보여줍니다.

N=n-5w-1s05e01

문자열 $ N에는 각 방향 변경 (n : -5, w : -1, s : +5, e : +1)에 대해 현재 회의실 번호에 더하거나 뺄 델타가 있습니다.

for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

명령 행에 주어진 방 번호와 같은 $ i로 시작하십시오 ($ 1). 문자열 $ S에서 인덱스 $ i의 문자를 $ d에 지정하십시오. 다음 방으로가는 방향에 대해 $ N에서 델타 값을 검색하여 $ j에 지정하십시오.

다음 방향으로 인쇄하여 $ d를받습니다.

$ j에서 $ i에 델타를 더하거나 빼십시오.

우리가 2 번 방을 떠날 때까지 반복합니다 ($ i> 1 동안).



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