인생은 미로이다 : 우리는 걷는 법을 배우기 전에 잘못된 길을 택한다


30

입력:

문자가 포함 된 미로 :

  • -- (가로 벽);
  • | (세로 벽);
  • + (연결);
  • (도보 공간);
  • I (입구);
  • U (출구).

즉, 입력은 다음과 같습니다.

 +--+--+--+--+--+--+--+--+--+--+ 
I               |     |        | 
 +  +--+--+--+  +  +  +  +--+  + 
 |           |     |  |  |     | 
 +--+--+--+  +--+--+  +  +  +--+ 
 |           |     |     |     | 
 +  +--+--+  +  +--+--+  +--+  + 
 |     |     |     |     |     | 
 +--+  +  +--+--+  +--+--+  +  + 
 |     |        |        |  |  | 
 +  +--+--+--+  +--+--+  +  +  + 
 |     |     |     |        |  | 
 +--+  +  +--+--+  +--+--+--+--+ 
 |  |  |                 |     | 
 +  +  +--+--+--+  +--+  +  +  + 
 |     |        |  |  |  |  |  | 
 +--+--+  +  +--+  +  +  +--+  + 
 |        |     |     |  |     | 
 +  +--+--+--+  +  +  +  +  +--+ 
 |           |     |  |         U
 +--+--+--+--+--+--+--+--+--+--+ 

산출:

가장 효율적인 걸을해야 경로는 오른쪽, 위, 아래, 왼쪽 나타내는 문자로 표시 (미로를 통해) 미로의 출구, 입구에서 얻을 수 있습니다 (예 >; <; ^; v).

도전 규칙 :

  • 합리적인 형식으로 입력 할 수 있습니다. 문자열 배열, 줄 바꾸기가 포함 된 단일 문자열, 2D 문자 배열 등이 모두 가능한 입력 형식입니다.
  • 출력은 4 개의 다른 문자로 구성 될 수 있습니다. 즉 ><^v; →←↑↓; ⇒⇐⇑⇓; RLUD; 0123; ABCD; 기타.).
  • 원하는 경우 출력에 공백 또는 후행 줄 바꾸기를 추가 할 수 있습니다. 이것은 선택 사항입니다.
  • 단계는 +문자 당이 아니라 제곱 당 계산됩니다 (제곱에 대한 네 개의 기호 참조 ).
  • 미로는 크기가 5x5에서 15x15 사이 일 수 있으며 항상 정사각형입니다 (따라서 5x10 미로에 대한 테스트 사례는 없습니다).
  • 모든 미로는 시작부터 끝까지 하나 이상의 유효한 경로를 가지고 있다고 가정 할 수 있으며 항상 가장 짧은 출력을합니다 (테스트 사례 4 및 5 참조).
  • 길이가 동일한 경로가 여러 개인 경우 출력 할 경로를 선택할 수 있습니다 (테스트 사례 6 참조).
  • 당신은 미로의 경계 밖으로 '걷지'수 없습니다 (테스트 사례 7과 8 참조).

일반적인 규칙:

  • 이것은 이므로 바이트 단위의 최단 답변이 이깁니다.
    코드 골프 언어가 코드 골프 언어 이외의 언어로 답변을 게시하지 못하게하십시오. '모든'프로그래밍 언어에 대한 가능한 한 짧은 대답을 생각해보십시오.
  • 표준 규칙이 답변에 적용 되므로 STDIN / STDOUT, 적절한 매개 변수가있는 기능 / 방법, 전체 프로그램을 사용할 수 있습니다. 당신의 전화.
  • 기본 허점 은 금지되어 있습니다.
  • 가능하면 코드 테스트 링크를 추가하십시오.
  • 또한 필요한 경우 설명을 추가하십시오.

테스트 사례 :

1. Input:
 +--+--+--+--+--+--+--+--+--+--+ 
I               |     |        | 
 +  +--+--+--+  +  +  +  +--+  + 
 |           |     |  |  |     | 
 +--+--+--+  +--+--+  +  +  +--+ 
 |           |     |     |     | 
 +  +--+--+  +  +--+--+  +--+  + 
 |     |     |     |     |     | 
 +--+  +  +--+--+  +--+--+  +  + 
 |     |        |        |  |  | 
 +  +--+--+--+  +--+--+  +  +  + 
 |     |     |     |        |  | 
 +--+  +  +--+--+  +--+--+--+--+ 
 |  |  |                 |     | 
 +  +  +--+--+--+  +--+  +  +  + 
 |     |        |  |  |  |  |  | 
 +--+--+  +  +--+  +  +  +--+  + 
 |        |     |     |  |     | 
 +  +--+--+--+  +  +  +  +  +--+ 
 |           |     |  |         U
 +--+--+--+--+--+--+--+--+--+--+ 

1. Output:
>v>>>vv<v>>v>v>>vvv>>>

2. Input:
 +--+--+--+--+--+ 
I   |        |  | 
 +  +--+--+  +  + 
 |        |  |  | 
 +  +--+  +  +  + 
 |  |  |     |  | 
 +  +  +--+  +  + 
 |        |     | 
 +--+  +  +--+--+ 
 |     |         U
 +--+--+--+--+--+ 

2. Output:
>vvv>>v>>>

3. Input:
 +--+--+--+--+--+ 
U      |        | 
 +  +  +--+--+  + 
 |  |     |     | 
 +--+--+  +  +--+ 
 |        |     | 
 +  +--+--+--+  + 
 |  |     |     | 
 +  +  +  +  +--+ 
 |     |         I
 +--+--+--+--+--+ 

3. Output:
<<<^<v<^^>>^<^<<

4. Input (test case with two valid paths):
 +--+--+--+--+--+ 
U      |        | 
 +  +  +--+--+  + 
 |  |           | 
 +--+--+  +  +--+ 
 |        |     | 
 +  +--+--+--+  + 
 |  |     |     | 
 +  +  +  +  +--+ 
 |     |         I
 +--+--+--+--+--+ 

4. Output:
<<^>^<^<<^<<     (<<<^<v<^^>>^<^<< is less efficient, and therefore not a valid output)

5. Input (test case with two valid paths):
                               I
+--+--+--+--+--+--+--+--+--+--+  +--+--+--+--+
|     |              |                    |  |
+  +  +  +--+--+--+  +  +--+--+  +--+--+  +  +
|  |     |        |     |        |     |     |
+--+--+--+  +--+  +  +--+--+--+--+  +--+--+--+
|     |  |  |  |     |     |           |     |
+  +  +  +  +  +--+  +  +  +  +--+--+  +--+  +
|  |        |        |  |     |        |     |
+  +--+--+--+  +--+--+  +  +--+  +--+--+  +--+
|  |     |     |        |  |     |     |     |
+  +--+  +  +--+  +--+--+  +--+--+  +  +--+  +
|  |     |        |     |           |        |
+  +  +--+--+--+--+  +  +--+--+--+  +--+  +--+
|     |     |        |        |  |     |     |
+--+--+--+  +  +--+--+  +--+  +  +--+  +--+  +
|              |     |     |        |  |  |  |
+  +--+--+--+--+  +  +  +--+--+--+  +  +  +  +
|     |  |     |  |  |        |        |  |  |
+--+  +  +  +  +  +  +--+--+  +  +  +--+  +  +
|     |     |  |  |  |           |  |     |  |
+--+  +--+--+  +  +  +  +--+--+--+  +  +  +  +
|     |        |  |  |     |        |  |  |  |
+  +--+  +--+--+  +  +--+--+  +  +--+  +  +  +
|        |     |  |     |     |  |     |  |  |
+--+--+--+  +  +  +--+  +  +--+--+  +--+  +  +
|  |        |        |     |        |     |  |
+  +  +--+--+--+--+  +--+--+  +--+--+  +--+  +
|  |              |              |     |     |
+  +  +  +--+--+--+--+--+--+--+--+  +--+  +--+
|     |                                |     |
+--+--+--+--+--+--+--+--+--+  +--+--+--+--+--+
                            U

5. Output:
v<<<v<vv<<v<v>>^>>^^>vvv>>>v>vv<vv<<v<v<^<^^^^<vvvvv<^<v<<v>v>>>>>>>v     (v<<<v<vv<<v<v>>^>>^^>vvv>>>v>vv<vv<<v<v<^<^^^^<vvvvv>v>>>^>>^>^^>vvv<v<v<<v is less efficient, and therefore not a valid output)

6. Input:
 +--+--+--+--+--+
I               |
 +  +  +  +  +  +
 |              |
 +  +  +  +  +  +
 |              |
 +  +  +  +  +  +
 |              |
 +  +  +  +  +  +
 |               U
 +--+--+--+--+--+

6. Output:
>>v>v>v>v> or >v>v>v>v>> or >>>>>vvvv> or etc. (all are equally efficient, so all 10-length outputs are valid)

7. Input:
 I  U
+  +  +--+--+--+
|  |        |  |
+  +--+--+  +  +
|     |     |  |
+--+  +  +--+  +
|        |  |  |
+  +--+  +  +  +
|     |        |
+--+  +--+--+  +
|     |        |
+--+--+--+--+--+

7. Output:
vv>v>^>^<<^

8. Input:
 +--+--+--+--+--+
 |     |        |
 +  +--+  +--+  +
I   |     |  |  |
 +  +  +--+  +  +
U   |     |  |  |
 +--+--+  +  +  +
 |     |     |  |
 +  +--+--+--+  +
 |               
 +--+--+--+--+--+

8. Output:
>v<

이 도구를 사용하여 생성 된 미로 (일부 경우 약간 수정 됨).


10
세 번째 테스트 사례에 대한 더 짧은 솔루션을 찾았습니다! v<<<<<<^^^^^(항상 상자 밖에서 생각)
Leo

2
시간과 메모리가 충분하다면 코드가 가장 짧은 솔루션을 제공한다는 것을 증명할 수 있다면 경쟁이 되나요? 정말 긴 실행 시간 (우주 패션의 끝)의 경우에도?
Yytsi

1
@JackBates 농담입니다. 그는 문자 그대로 박스 주위를 걸어 출구로 나옵니다. :
Yytsi

1
첫 번째 테스트 사례가 잘못되었다고 생각합니다 >v>>>vv<v>>v>v>>vvv>>>.
smls

1
@KevinCruijssen 예를 들어, "v ^ <>"의 각 조합을 미로 내부의 빈 상자 크기까지 테스트하는 솔루션입니다. 올바른 솔루션이 있지만 계산하는 데 천문학적 시간이 걸립니다.
Yytsi

답변:


7

망막 , 338 281 275 273 261 바이트

¶U
¶&
+`·(\w.+)$
|$1
((.)+I.+¶.+¶(?<-2>.)+)·
$1v
+`((.)*)\+(.).*(¶(?<-2>.)*.)((\w)|·)·?
$1$4$.4$3$6
·v
-v
G`1
·U
&
{`\B·\d+.(\w+)
$1K$&
(\w+)·\d+.\B
$&$1r
(?<=\D\2.(\w+).+?¶.*\D(\d+)[·&])\B
$1v
)`\D(\d+).\B(?=.+¶.*\D\1·(\w+))
$&$2A
^.+\d·(\w+)
&$1A
M!`&\w+
I|&

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


노트

  • 공백이 많기 때문에이 답변과 TIO 링크에서 모든 공백 ( 0x20)이 펑크 ( ·) 로 바뀝니다 . 공간이 복원되면 프로그램이 제대로 작동합니다.
  • 용도 AvKr최대위한, 아래쪽, 오른쪽 각각 왼쪽합니다. 을 제외한 다른 문자 로 바꿀 수 있습니다 I.
  • 15 × 15 테스트 케이스의 경우 TIO에서 약 40 초가 소요됩니다. 인내심을 가지십시오. 경로가 출구에 도달하면 최단 경로를 찾기 위해 부품을 재 작업했습니다. 시간이 많이 걸린다는 것이 밝혀졌습니다.
  • 폭이 66 개 이상인 미로에서는 완전히 파손될 수 있지만 임의의 높이의 미로를 처리 할 수 ​​있습니다. 임의 너비의 수정에는 +1 바이트가 필요합니다.

설명

이 프로그램은 3 단계로 구성됩니다.

  • 작업하기 쉬운 미로를 컴팩트 한 형식으로 변환 하는 구성 단계 입니다 (자세한 내용 참조).
  • 홍수 채우기 알고리즘을 사용하여 실제로 미로를 해결하기 위한 채우기 단계 .
  • 출구에서 가장 짧은 경로를 반환 하는 반환 단계 입니다.

체재

원래 미로 형식은 다루기 힘들 기 때문에 프로그램의 첫 부분은 다른 형식으로 변환합니다.

세포

원래 형식에서 각 셀은 2x3 영역으로 표시됩니다.

+               <top wall>      <top wall>
<left wall>     <data/space>    <space>

오른쪽 열에는 정보가 없으므로 프로그램은 셀을 +왼쪽 상단에 2x2 영역으로 식별합니다 .

이것은 우리에게 3 가지 종류의 세포를 남깁니다.

  • I 세포 : 미로 내부에있는 세포.
  • R 세포 : 미로의 오른쪽에있는 세포. 이들은 입구 또는 출구를 수용하는 데 사용되는 패딩에 의해 생성됩니다. 예를 들어 U테스트 사례 1 의 이탈 은 R-Cell에 있습니다.
  • B 세포 : 미로 아래에있는 세포. R-Cell과 마찬가지로 이들은 패딩으로 생성됩니다.

새로운 형식에서 셀은 가변 길이 문자열로 표시됩니다.

<left wall> <column number> <top wall/exit marker> <path>

왼쪽 및 상단 벽은 원래 형식에서 복사됩니다. 열 번호는 셀의 가로 위치를 기준으로하며 정렬에 사용됩니다 (셀을 서로 바로 위 / 아래에서 직접 식별). 경로는 해당 셀에 도달하기위한 최단 경로를 저장하기 위해 채우기 단계에서 사용되는 알파벳 문자열입니다. 경로 및 종료 마커에 대해 더 설명합니다.

반쪽 세포

미로의 대부분은 셀이지만 미로에는 셀이 아닌 영역이 있습니다.

  • R 반쪽 셀 : 오른쪽 패딩이 없으면 +오른쪽 벽을 따라 s가 마지막 열에 있으므로 셀을 형성하지 않습니다.
  • L 반쪽 셀 : 왼쪽 패딩이 있으면 왼쪽에 셀이 없기 때문에 셀을 만들 수 없습니다 +. 예를 들어 I테스트 사례 1 의 입구 는 L 하프 셀에 있습니다.

기술적으로 미로 위에 T 반쪽 셀 (상단 패딩이있는 경우)과 B 반쪽 셀 (하단 패딩이없는 경우 하단 벽을 따라)이 있지만 새로운 형식으로 표시되지는 않습니다.

반쪽 셀의 맨 위 행은 동일한 행에 전체 셀을 구성하는 과정에서 제거되므로 반쪽 셀은 다음과 같이 새로운 형식으로 표시됩니다.

<wall/exit marker>? <path>

R 반쪽 셀은 단지 |입니다. L 반쪽 셀은 I경로와 마찬가지로 종료 표시기 및 빈 경로 또는 빈 벽을 갖습니다.

출입구

입구가 미로의 왼쪽, 오른쪽 또는 아래쪽에있는 경우 입구 마커 I는 자연스럽게 (하프) 셀에 경로로 포함되며 최종 경로를 반환 할 때 제거 할 수 있습니다.

입구가 미로 위에있는 경우, 건설 중에 T 반쪽 셀이 제거되므로 첫 번째 (아래쪽) 단계가 건설 단계에서 수행됩니다. 이렇게하면 전체 셀에 실행 가능한 경로가 유지됩니다. 상단 벽은 나중에 닫힙니다.

출구가 미로의 왼쪽, 오른쪽 또는 아래쪽에 U있으면 자연스럽게 (하프) 셀에 포함됩니다. 경로로 착각하지 않기 위해 비 알파 늄 이탈 마커 &가 대신 사용됩니다 U. 엑시트 마커는 셀 또는 하프 셀에 내장됩니다 (위에 지정된대로).

출구가 미로 위에 있다면, 그것은 입구의 구멍이 이미 닫혀 있기 때문에 세포의 맨 위 줄 위로 갈 수있는 유일한 구멍 일 것입니다. 그 구멍에 도달하는 모든 경로는 위로 올라가면 미로를 빠져 나갈 수 있습니다.

마지막으로, 입구 또는 출구를 포함하는 모든 B 셀은 B 셀을 따라 미로를 "해결"하지 못하도록 왼쪽 벽을 닫아야합니다. R 셀 또는 L 반쪽 셀의 입구 및 출구는 플러드 필 알고리즘이 수직 이동을 허용하지 않기 때문에 추가 처리가 필요하지 않습니다.

예를 들어 첫 번째 테스트 사례

·+--+--+--+--+--+--+--+--+--+--+·
I···············|·····|········|·
·+··+--+--+--+··+··+··+··+--+··+·
·|···········|·····|··|··|·····|·
·+--+--+--+··+--+--+··+··+··+--+·
·|···········|·····|·····|·····|·
·+··+--+--+··+··+--+--+··+--+··+·
·|·····|·····|·····|·····|·····|·
·+--+··+··+--+--+··+--+--+··+··+·
·|·····|········|········|··|··|·
·+··+--+--+--+··+--+--+··+··+··+·
·|·····|·····|·····|········|··|·
·+--+··+··+--+--+··+--+--+--+--+·
·|··|··|·················|·····|·
·+··+··+--+--+--+··+--+··+··+··+·
·|·····|········|··|··|··|··|··|·
·+--+--+··+··+--+··+··+··+--+··+·
·|········|·····|·····|··|·····|·
·+··+--+--+--+··+··+··+··+··+--+·
·|···········|·····|··|·········U
·+--+--+--+--+--+--+--+--+--+--+·

이다

I·3-·6-·9-·12-·15-|18-·21-|24-·27-·30-|33·
·|3··6-·9-·12-|15··18·|21·|24·|27-·30·|33·
·|3-·6-·9-·12·|15-·18-|21··24·|27··30-|33·
·|3··6-|9-·12·|15··18-|21-·24·|27-·30·|33·
·|3-·6·|9··12-·15-|18··21-·24-|27·|30·|33·
·|3··6-|9-·12-|15··18-|21-·24··27·|30·|33·
·|3-|6·|9··12-·15-·18··21-·24-|27-·30-|33·
·|3··6·|9-·12-·15-|18·|21-|24·|27·|30·|33·
·|3-·6-·9·|12··15-|18··21·|24·|27-·30·|33·
·|3··6-·9-·12-|15··18·|21·|24··27··30-·33&

새로운 형식으로. 여기에서 다른 미로를 변환 할 수 있습니다 .


건설 단계

건설 단계는 프로그램의 처음 13 개 라인을 구성합니다.

¶U
¶&

L 반쪽 셀의 종료를 종료 마커로 변환

+`·(\w.+)$
|$1

B 셀의 입구 및 출구 왼쪽에 벽을 추가합니다.

((.)+I.+¶.+¶(?<-2>.)+)·
$1v

입구가 미로 위에 있으면 첫 걸음을 내딛습니다

+`((.)*)\+(.).*(¶(?<-2>.)*.)((\w)|·)·?
$1$4$.4$3$6

실제 변환을 수행합니다

·v
-v

상단 입구 구멍을 닫습니다

G`1

가있는 줄만 유지합니다 1. 미로는 너비가 5 셀 이상이고 열 번호가 3 씩 증가하므로 새로운 형식의 셀이있는 행의 열 번호는 10과 19 사이 여야합니다.

·U
&

R 셀 또는 B 셀의 종료를 종료 마커로 변환


충전 단계

채우기 단계는 프로그램의 다음 8 줄을 구성합니다. 플러드 필 알고리즘을 사용하여 모든 셀을 가장 짧은 경로로 채워서 입구에서 도달합니다.

{`

전체 미로를 채우기 위해 전체 채우기 단계를 루프에 놓습니다.

\B·\d+.(\w+)
$1K$&

왼쪽으로 이동할 수있는 각 셀이 그렇게합니다. 다음과 같은 경우 셀이 왼쪽으로 이동할 수 있습니다

  1. 비어 있지 않은 경로가 있습니다
  2. 빈 왼쪽 벽이 있습니다. 과
  3. 왼쪽의 셀 또는 L 반쪽 셀에 빈 경로가 있습니다.
(\w+)·\d+.\B
$&$1r

그런 다음 오른쪽으로 이동할 수있는 각 셀이 그렇게합니다. 셀은 다음과 같은 경우 오른쪽으로 이동할 수 있습니다

  1. 비어 있지 않은 경로가 있습니다
  2. 오른쪽의 칸에는 빈 왼쪽 벽이 있습니다. 과
  3. 오른쪽의 셀에 빈 경로가 있습니다
(?<=\D\2.(\w+).+?¶.*\D(\d+)[·&])\B
$1v

그런 다음 아래로 이동할 수있는 각 셀이 그렇게합니다. 셀이 아래로 이동하면

  1. 비어 있지 않은 경로가 있습니다
  2. 오른쪽에 하나 이상의 셀 또는 반쪽 셀이 있습니다 (즉, R 셀이 아님).
  3. 그 아래의 셀 (즉, 같은 열 번호를 가진 다음 줄의 셀)은 상단 벽이 비어 있거나 종료 마커가 있습니다. 과
  4. 그 아래의 셀에는 빈 경로가 있습니다.

L 반쪽 셀에는 열 번호가 없으므로 아래로 이동할 수 없습니다.

\D(\d+).\B(?=.+¶.*\D\1·(\w+))
$&$2A

그런 다음 위로 이동할 수있는 각 셀이 그렇게합니다. 셀은 다음과 같은 경우 위로 이동할 수 있습니다

  1. 비어 있지 않은 경로가 있습니다
  2. 빈 상단 벽이 있습니다
  3. 그 위의 셀은 그 오른쪽에 적어도 하나의 셀 또는 하프 셀을 가지고; 과
  4. 위의 셀에는 빈 경로가 있습니다.

귀환 단계

리턴 단계는 프로그램의 마지막 5 줄을 구성합니다. 이 단계는 엑시트 셀에 채워진 경로를 검색하여 리턴합니다.

출구에서의 경로 패턴은 출구의 위치에 따라 다릅니다.

  1. 출구가 L 반쪽 셀에 있다면 반쪽 셀은 & <path>
  2. 엑시트가 R 셀 또는 B 셀에있는 경우 해당 셀은 <left wall> <column number> & <path>
  3. 출구가 T 반-전지에 있다면, 상기 언급 된 바와 같이, 출구로 이어지는 I 세포 <left wall> <column number> · <path>는 최상단에 있을 것이다 .
^.+\d·(\w+)
&$1A

맨 위 벽이 비어 있고 비어 있지 않은 경로가있는 맨 위 줄에서 셀을 찾습니다. 마지막 단계와 종료 마커를 추가하여 마지막 사례를 처리합니다.

M!`&\w+

이탈 마커 다음에 비어 있지 않은 경로를 일치시키고 반환합니다.

I|&

종료 표시 자와 I경로 의 접두사를 제거합니다 .


AvKr? 그들은 모국어로 위, 아래, 왼쪽 및 오른쪽의 의미가 있습니까? 아니면 특정 문자를 선택한 또 다른 이유가 있습니까?
Kevin Cruijssen

@KevinCruijssen 간단하게 영숫자를 사용해야하기 때문에 영숫자의 AvKr화살표에 가장 가깝습니다.
TwiNight

12

펄 6 , 259 295 바이트

{my \a=S:g/(.)$0+/{$0 x($/.comb+.5)*2/3}/;sub f (\c,\v,*@p) {with (c ne any v)&&a.lines».comb[+c[0];+c[1]] ->$_ {for (/\s/??10011221!!/I/??a~~/^\N*I|I\N*$/??2101!!1012!!'').comb X-1 {f [c Z+$^a,$^b],(|v,c),@p,chr 8592+$++}
take @p if /U/}}
[~] (gather f a~~/(\N+\n)*(.)*I/,[]).min(+*)[1,3...*]}

작동 원리

  1. my \a = S:g/ (.) $0+ /{ $0 x ($/.chars + .5) * 2/3 }/;

이렇게하면 각 셀의 내부가 2x1 공백 문자 대신 1x1이되도록 미로가 압착됩니다.

 +-+-+-+-+-+ +-+-+-+-+-+ 
나는 | | | 나는 | | |
 + +-+-+ + + + +-+-+ + + 
 | | | | | | | |
 + +-+ + + + + +-+ + + + 
 | | | | | -> | | | | |
 + + +-+ + + + + +-+ + + 
 | | | | | |
 +-+ + +-+-+ +-+ + +-+-+ 
 | | U | | 유
 +-+-+-+-+-+ +-+-+-+-+-+

  1. sub f (\c,\v,*@p) {
        with (c ne any v) &&                   # If the coordinate wasn't visited yet
             lines».comb[+c[0];+c[1]] -> $_ {  # and a character exists there...
            for (                          # For each vector...
                 /\s/ ?? 10011221 !!       #  from a cell: (0,-1), (-1,0), (0,1), (1,0)
                 /I/  ?? a~~/^\N*I|I\N*$/
                          ?? 2101          #  from a top/bottom entrance: (1,0), (-1,0)
                          !! 1012          #  from a left/right entrance: (0,-1), (0,1)
                      !! ''                #  otherwise: none
                ).comb X-1 {
                f                       #   Recurse with arguments:
                    [c Z+ $^a, $^b],    #     c plus the vector
                    (|v, c),            #     v with c appended
                    @p, chr 8592 + $++  #     p with the correct Unicode arrow appended
            }
            take @p if /U/
        }
    }

이것은 재귀 경로 찾기 기능입니다. 현재 좌표 c=(y,x), 이미 방문한 좌표 목록 vp지금까지 의 경로 (화살표 문자 목록)의 세 가지 매개 변수가 필요 합니다.

현재 좌표의 문자가 공백이면 네 개의 이웃으로 반복됩니다.
현재 좌표의 문자가 a I인 경우, "가장자리를 따라"있지 않은 두 이웃에 반복되어 솔루션이 미로를 통과하지 않고 미로를 통과하도록합니다.
현재 좌표의 문자가 이면 누적 경로 문자열을 U호출 take합니다.

  1. [~] (gather f a ~~ /(\N+\n)*(.)*I/, []).min(+*)[1,3...*]

재귀 함수는 처음에 문자의 좌표로 호출되며, I정규식을 사용하여 찾습니다.

gather키워드는 모든 값을 수집 take함수 내에서 호출 된 미로를 통해 즉, 모든 유효한 비 순환 경로를.

가장 짧은 경로가 선택되고 두 번째 화살표는 한 셀에서 다음 셀로 이동하기 위해 두 개의 동일한 이동이 필요하고 나머지 화살표는 람다에서 반환되는 문자열을 형성하기 위해 연결됩니다.


먼저 내 도전을 완수하는 데 큰 일을했습니다! :) 실제 이동 / 카운팅을 용이하게하기 위해 두 공간을 하나로 변경 한 방법을 똑똑합니다. 나에게서 +1 어쨌든, 몇 가지 의견 후 두 가지 새로운 테스트 사례가 추가되었습니다. 솔루션에서도 이러한 작업을 확인할 수 있습니까? (또한 Perl 6에는 링크를 추가 할 수있는 TIO 또는 기타 온라인 컴파일러가 있습니까?)
Kevin Cruijssen

@KevinCruijssen : 새로운 테스트 케이스에서 미로를 돌았습니다. :( 지금 코드를 수정했습니다. tio.run은 Perl 6을 지원하지만 어떤 이유로 든 작동하지 않습니다. 아마도 너무 오래된 Perl 6 버전이 있습니까?
smls

코드를 수정하는 훌륭한 직업. 답변을 이미 게시 한 후 미로를 통과해야하는 규칙을 지정해 주셔서 죄송합니다. 그리고 TIO 버전에 대해서는 전혀 모른다. 내 전문 지식은 아닙니다 ..
Kevin Cruijssen

당신이 4 개월 전에 나의 도전에 가장 먼저 대답했기 때문에, 나는 당신에게 현상금을 주었다. :) 그리고 수락은 약간 더 짧은 Retina 답변입니다.
Kevin Cruijssen

5

파이썬 2 : 302 바이트

from re import*
r=lambda x:[''.join(_)for _ in zip(*x)][::-1]
z=',l)for l in s]'
def f(s,b=1,o=0,n=0):
 exec("s=[sub('(..).(?!$)',r'\\1'%s;"%z+"s=r([sub(' I ','+I+'%s);"%z*4)*b+"t=[sub('I  ','@@I'"+z
 if'I U'in`s`or n>3:return`o%4`+n/4*`s`
 return min(`o%4`+f(t,0,o,4*(t==s)),f(r(s),0,o+1,n+1),key=len)

길이가 같은 문자열 배열로 입력을받습니다. 0오른쪽, 1아래쪽, 2왼쪽 및 3위쪽으로 인쇄 합니다.

설명

나는 다른 답변과 다른 접근법을 취했습니다. 일반적인 아이디어 : 직선으로 진행하는 것과 보드를 90도 회전하는 것 사이의 최단 경로를 찾아 재귀 적으로 검색하십시오.

from re import*
r=lambda x:[''.join(_)for _ in zip(*x)][::-1] #Rotates the board counterclockwise
z=',l)for l in s]'    #Suffix for hacky exec golfing
def f(s,b=1,o=0,n=0): #b is 1 on initial call, 0 on every recursion
                      #o is orientation
                      #n is number of rotations
 exec("s=[sub('(..).(?!$)',r'\\1'%s;"%z  #Squeeze the maze
      +"s=r([sub(' I ','+I+'%s);"%z*4)   #Add walls around the I to keep it in the maze
      *b                                 #Only if b is 1
      +"t=[sub('I  ','@@I'"+z            #Attempt to move right

 if'I U'in`s`or n>3:return`o%4`+n/4*`s`  #If the I is next to the U, return the orientation
                                         #If there were 4 rotations, return a long string
 return min(                             #Return the path with the shortest length:
            `o%4`+f(t,0,o,4*(t==s)),       #Moving forward if possible
            f(r(s),0,o+1,n+1),             #Rotating the board
        key=len)

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


3
PPCG에 오신 것을 환영합니다! 이것은 훌륭한 첫 번째 대답이며, 첫 번째로 꽤 어려운 도전을하기로 결정한 것에 깊은 인상을 받았습니다. 또한 I경로가 미로 밖으로 나가는 것을 방지하기 위해 벽을 벽에 두는 방법도 똑똑합니다 . 당신의 체류를 즐기고, 나에게서 +1. :)
Kevin Cruijssen

2

자바 스크립트 (ES6), 356 바이트

a=>(a=a.map(s=>s.filter((_,i)=>!i|i%3)),g=([x,y])=>a[y]&&a[y][x],o=[],c=([x,y],m="",v=[])=>[[0,1],[1,0],[0,-1],[-1,0]].map(([j,k],i)=>(p=[x+j,y+k],!m&(!y|y>a[l="length"]-2)==i%2|v.includes(""+p)||(g(p)<"!"?c(p,m+"v>^<"[i],[...v,""+p]):g(p)=="U"?o.push(m.replace(/(.)\1/g,"$1")):0))),a.map((h,i)=>h.map((k,j)=>k=="I"&&c([j,i]))),o.sort((a,b)=>a[l]-b[l])[0])

입력을 2D 문자 배열로 사용합니다. 각 줄은 시작 / 끝 지점에 관계없이 한 칸씩 왼쪽 여백이 있어야하며 후미 공간이 없어야합니다.

미로를 뭉개고 각 셀을 1x1로 만들고 출력에서 ​​반복되는 화살표를 제거하는 smls의 아이디어 를 사용합니다 .

언 골프 및 설명

a=>(
    a=a.map(s=>s.filter((_,i)=>!i|i%3)),    // squish the maze to 1x1 cells
    g=([x,y])=>a[y]&&a[y][x],               // helper func to get maze value
    o=[],                                   // resulting movesets
    c=([x,y], m="", v=[]) =>                // recursive func to search
                                            // takes current point, moves, and visited spots
        [[0,1],[1,0],[0,-1],[-1,0]].map(([j,k],i)=>(// for each direction
            p=[x+j,y+k],
            !m & (!y | y>a[l="length"]-2) == i%2 |  // if first move, prevent moving out of maze
                v.includes(""+p) || (               // also prevent if already visited
                    g(p)<"!" ?                      // is this a space?
                        c(p, m+"v>^<"[i], [...v,""+p]) // check this spot recursively
                    : g(p)=="U" ?                   // if this the end?
                        o.push(                     // add moves to moveset
                            m.replace(/(.)\1/g,"$1")) // with double arrows removed
                    : 0
                )
        )),

    a.map((h,i)=>h.map((k,j)=>      // find the starting "I" and
        k=="I" && c([j,i])          // begin recursion at that point
    )),

    o.sort((a,b)=>a[l]-b[l])[0]     // get shortest path
)

테스트 스 니펫


1

레티 나 416 바이트

T` `+`^.*| ?¶.|.*$
I
#
{+` (\w)
d$1
+`(\w) 
$1a
+`(¶(.)*) (.*¶(?<-2>.)*(?(2)(?!))\w)
$1s$3
}+m`(^(.)*\w.*¶(?<-2>.)*(?(2)(?!))) 
$1w
^
w¶
w((.|¶)*(¶(.)*#.*¶(?<-4>.)*(?(4)(?!))(s)|#(d)|(a)#))
$4$5$6¶$1
{`^(.*d)(¶(.|¶)*)#(\w)
$1$4$2 #
^(.*a)(¶(.|¶)*)(\w)#
$1$4$2# 
^(.*s)(¶(.|¶)*¶(.)*)#(.*¶(?<-4>.)*(?(4)(?!)))(\w)
$1$6$2 $5#
}`^(.*w)(¶(.|¶)*¶(.)*)(\w)(.*¶(?<-4>.)*(?(4)(?!)))#
$1$5$2#$6 
s`U.*

(a|d)\1\1?
$1
ss
s
ww
w

온라인으로 사용해보십시오! 이 질문이 처음 게시되었을 때이 질문을 본 적이 있다면, 아마도 내가 받았을 답변 일 것이므로 Retina에 훨씬 더 나은 답변이 있지만 어쨌든 게시하고 있습니다. 설명:

T` `+`^.*| ?¶.|.*$

테두리를 채우십시오. 이렇게하면 미로 외부를 걷지 않아도됩니다 (예 : 테스트 사례 7).

I
#

알파벳이 아닌 마커를 입구에 놓습니다.

{+` (\w)
d$1
+`(\w) 
$1a
+`(¶(.)*) (.*¶(?<-2>.)*(?(2)(?!))\w)
$1s$3
}+m`(^(.)*\w.*¶(?<-2>.)*(?(2)(?!))) 
$1w

출구에서 입구까지의 홍수 채우기. 각 단계에서 가장 좋은 방향을 알려주는 글자를 사용하십시오. (폐기-이것은 게이머에게 친숙 할 수 있습니다; 나는 또한 hjkl을 고려했지만 너무 혼란 스럽습니다). 또한 동일한 방향을 반복하는 것이 좋습니다. 이렇게하면 세로로 인접한 두 셀 사이에서 왼쪽 / 오른쪽으로 이동하지 않아도됩니다.

^
w¶

첫 번째 단계가 종료되었다고 가정하십시오.

w((.|¶)*(¶(.)*#.*¶(?<-4>.)*(?(4)(?!))(s)|#(d)|(a)#))
$4$5$6¶$1

그러나 입구의 왼쪽 또는 오른쪽에 위의 편지가 있으면 첫 단계로 변경하십시오.

{`^(.*d)(¶(.|¶)*)#(\w)
$1$4$2 #
^(.*a)(¶(.|¶)*)(\w)#
$1$4$2# 
^(.*s)(¶(.|¶)*¶(.)*)#(.*¶(?<-4>.)*(?(4)(?!)))(\w)
$1$6$2 $5#
}`^(.*w)(¶(.|¶)*¶(.)*)(\w)(.*¶(?<-4>.)*(?(4)(?!)))#
$1$5$2#$6 

마커를 마지막 이동 방향으로 이동하고 마커가 이동하는 사각형에서 다음 이동 방향을 읽고 방향 목록에 추가하십시오. 에 U도달 할 때까지이 과정이 반복됩니다 .

s`U.*

더 이상 필요하지 않으므로 지시 후에 모든 것을 삭제하십시오.

(a|d)\1\1?
$1
ss
s
ww
w

원본 그리드는 3 × 2 레이아웃입니다. 수평으로 지그재그로 수직으로 움직이면 플러드 필은 이동을 최적화하고 3n-1 문자 만 수평으로 이동하므로 3으로 나누면 반올림해야합니다. 수직으로 우리는 단지 2로 나눕니다.

또한 실제 정사각형 그리드 솔루션, 즉 선택적 매트릭스가있는 3x2 레이아웃이 아닌 문자 행렬 자체가 정사각형 인 솔루션을 조사했습니다. 아마도이 질문에 부적합하지만, 전치하는 능력은 바이트 수를 350으로 줄였습니다. 온라인으로 시도하십시오!


좋은 대답, +1! TIO 링크 -에서 입구 문자와 출구 문자 주위에 두 개 를 추가 한 것을 알 수 있습니다. 도전은 주로 내가 그것의 벌금을 추측 미로를 통과 관한 것입니다,하지만 난 궁금 이후 : 당신이 아래 위 / 그 벽을 배치하지 않은 경우 문제가 무엇인가 IU? 또한 테스트 케이스 7 에서 측면 대신 IU상단 이 작동하는지 확인할 수 있습니까? TIO가 60 초 제한을 초과하므로 직접 테스트 할 수 없습니다. 처음에는 기본적으로 내려 가려고 시도하는 것에 대한 설명을 읽었지만 제대로 작동한다고 가정합니다.
Kevin Cruijssen

@KevinCruijssen "2 차"답변은 테스트 사례 7에 적용되지만 추가 문자가 필요 합니다. 온라인으로 사용해보십시오! 계속 ...
Neil

@KevinCruijssen "주요"답변은 맨 위 줄의 출구에 전혀 대처할 수없는 버그가있었습니다. 또한 "2 차"답변과 유사한 버그가 있으므로 가능하면 미로 바깥을 걷는 것을 선호합니다. (또한 60 초 한도 근처에는 도착하지 않았습니다.)
Neil

실제로 국경을 채우면 두 가지 대답을 모두 고칠 수 있습니다. 나중에 시간이 있으면 나중에 할게요.
Neil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.