장애물 코스는 얼마나 다양합니까?


21

배경

직사각형 방에 박스를 놓아 간단한 장애물 코스를 만들었습니다. 이제 해결할 수있는 근본적으로 다른 방법의 수를 세고 싶습니다. 그 프로그램을 작성해주세요.

입력

입력은 비어 있지 않은 직사각형 문자 배열입니다 .#. 점 .은 빈 공간이며 #장애물입니다.

장애물 코스를 통과 하는 경로 는 왼쪽 상단에서 시작하여 오른쪽 하단에서 끝나며 오른쪽 또는 아래쪽으로 만 진행됩니다. 또한 유효한 경로는 장애물을 통과 할 수 없습니다. 다음은- +문자로 그려진 몇 가지 예입니다 .

Valid path  Invalid path  Invalid path  Invalid path
++........   ++........    +++++.....    ..+.......
.++++++#..   .+.....#..    ....+++#++    ..++...#..
......+#..   .+.++++#..    .......#.+    ...+++.#..
....#.++++   .+++#.++++    ....#....+    ....#+....

한 번 에 하나씩 이동하여 하나 를 다른 것으로 바꿀 수있는 경우 두 경로는 본질적으로 1 과 유사+ 합니다. 중간 경로도 유효해야하므로 장애물 위의 경로를 구부릴 수 없습니다. 예를 들어, 여기에서 처음 두 경로는 본질적으로 비슷하지만 세 번째 경로는 두 가지 장애물을 뒤흔들 수 없기 때문에 본질적으로 다릅니다.

++........   +.........   +++++++++.
.+++++.#..   ++.....#..   .......#+.
.....+.#..   .++++++#..   .......#++
....#+++++   ....#.++++   ....#....+

산출

당신의 결과는 장애물 코스를 통해 본질적으로 다른 경로의 수입니다. 다시 말해, 모든 유효한 경로가 본질적으로 유사한 경로의 클래스로 나뉘어 진 경우 출력은 클래스 수입니다. 유효한 경로가 없으면이 숫자는 0 일 수 있습니다.

규칙과 득점

전체 프로그램이나 함수를 작성할 수 있습니다. 가장 낮은 바이트 수가 이기고 표준 허점은 허용되지 않습니다. 제출하기 전에 모든 테스트 케이스에서 프로그램을 평가해야한다는 점을 제외하고는 시간 제한이 없습니다.

테스트 사례

....
....
.... => 1

...#
....
...# => 0

#..#
..#.
.... => 0

......
......
..##..
......
...... => 2

......
...#..
......
..#...
#..... => 3

......
..#...
......
....#.
#..... => 4

.......
##.....
....###
...#...
..##.#.
#....#.
..#.... => 0

......#.
..##....
...#....
.......#
....#...
.##...#.
....#...
##...... => 7

.........
.#.#.#.#.
.........
#.#...#.#
.........
.#.#.#.#.
......... => 17

..........
.#........
..........
.....#....
#.........
........#.
......#...
.......... => 10

.........
.#.......
.........
...#.....
.........
.....#...
.........
.......#.
......... => 16

1 올바른 기술 용어는 "homotopic" 입니다.


1
" 한 번 +에 하나씩 이동 "한다는 것은 무엇을 의미 합니까? 이것은 본질적으로 유사한 경로의 길이가 같아야 함을 의미합니까?
피터 테일러

3
@PeterTaylor 모든 경로는 아래쪽과 오른쪽으로 만 이동할 수 있으므로 길이는 같습니다. "하나 이동 +"은 본질적으로 경로의 한쪽 모서리가 반대 방향의 모서리로 반전됨을 의미합니다.
Zgarb

1
@Peter : 오른쪽 또는 아래쪽으로 만 이동할 수 있으므로 모든 경로의 길이가 같습니다.
Deusovi

답변:


8

달팽이 , 53 49 바이트

A^
\.+d!{.l\.+a3(.|~c!~}\.+r!(.u\.+e(.|~},\.,=~d~

한 번, 나는 t끔찍한 순간 이동 명령 을 사용할 필요가 없었습니다 . 결과적으로 테스트 케이스는 이온을 복용하는 대신 즉시 완료됩니다.

언 골프 드 :

A^
r\.+
{
    d\.+
    !{ r\.u \.+ a3 (.|~)}
    r\.+
    !{ d\.l \.+ a3 (.|~)}
},
d\.,
!(dr .)

옵션 A^은 왼쪽 상단에서 시작하여 일치하는 모든 경로를 계산합니다. 주요 아이디어는 경로의 캐논 성 조건을 확인하는 것입니다. 나는 솔직히 그것이 효과가 있다고 기대하지는 않았지만 테스트 사례를 못 박았습니다 .... 확인하려는 것은 현재 경로 내에서 가장 탐욕스러운 경로가 선택되었다는 것입니다. 장애물을 넘지 않고 가능한 한 많이 내리십시오. 이것은 1 번 이상 오른쪽으로 이동 한 다음 1 번 이상 아래로 이동 한 후 이전 오른쪽 세그먼트에서 한 번 더 오른쪽으로 이동하여 다음 정사각형 (오른쪽에 있어야 함)에 도달 할 수 없는지 확인하여 수행됩니다. 오른쪽과 아래로 이동 한 후에도 유사한 조건이 점검됩니다.


직업에 적합한 언어에 대해 이야기하십시오!
찰스가

10

파이썬 2, 170 131 112 바이트

def f(C,t=1):i="#".join(C).find("#")+1;return([]<C)*(i<1or(i<t
and f([r[i:]for r in C],t-i))+(i>1)*f(C[1:],i-1))

f장애물 코스를 행 목록으로 가져와 본질적으로 다른 경로의 수를 반환 하는 함수 .

설명

기본 개념은 다음과 같습니다. 상자 경계 o 와 왼쪽 상단 모서리에 다른 장애물이 없도록 특정 장애물 o를 선택합니다 .

+--+....
|..|....  
+--#<==== o
.....#..
.#......
........

그런 다음 o 의 동쪽과 남쪽에있는 두 개의 하위 코스를 고려합니다 . o 가 실제로 그들로 이어지는 방향, 즉 북쪽에서 동쪽으로 가려면 서쪽에서 남쪽으로 가려면 방향을 넘어갈 수있는 경우에만이 하위 과정 중 하나만 고려 하십시오. 선택한 각 하위 코스의 문제를 해결하고 결과의 합계를 반환합니다. 횡단 할 때이 번호는 본질적으로 상이한 경로의 수에 대응 O를 왼쪽과 오른쪽에 각각 따라서 경로의 두 가지 세트의 결과는 본질적으로 다르다. 시작점과 o 사이에 장애물이 없으므로, 시작 지점과 각 지역으로의 진입 지점 사이에 경로가 있으며 동일한 지점으로 이어지는 모든 경로는 본질적으로 유사하므로 위의 합계는 전체 과정에서 본질적으로 다른 경로의 전체 수입니다.

                               A
_
........       ...|////      |....
........       ...|////      |....
...#....  -->  ...#////  -->  ....
.#....#.       .#..//#/       ..#.
........       ....////       ....

   |                           |
   v                           v
                  B
........       ___
........       .#....#.
___#....  -->  ........  -->   +
/#////#/       
////////       

장애물 코스만으로 필요한 모든 정보를 전달할 수는 없기 때문에 상황이 약간 복잡합니다. 예를 들어, 위 다이어그램에서 B 코스를 고려 하십시오. 자체적으로 취해지면 각 장애물을 북쪽에서 건너 뛸 수 있는지 여부를 결정할 수 없습니다. 경우 B는 모든 경로가 왼쪽 상단 모서리에서 시작하기 때문에 우리가 도달 할 수 있기 때문에 입력은 물론, 다음, 어느 쪽도 아니 장애물, 북쪽에서 넘어,하지만 수 있었다이었다 B를 교차 할 때 왼쪽 장애물의 양쪽에서 O를 동쪽에서 우리는이 장애물을 코스를 풀 때 북쪽에서 건너 갈 수있는 것처럼 취급해야합니다. 그러나 같은 방향으로 올바른 장애물을 잡을 수는 없지만이 방향에서 벗어날 수는 없습니다.

우리는 장애물 코스와 함께 첫 번째 행을 따라 왼쪽부터 시작하여 경로를 시작할 수있는 문자 수를 지정하여이 추가 정보를 제공합니다. 위의 다이어그램에서 이는 각 코스 옆에 실선으로 표시됩니다. 기술적으로 하위 코스 A 의 경우와 같이 경로가 시작할 수있는 첫 번째 열에 해당하는 문자 수를 지정해야하지만 실제로는 항상 가장 높은 장애물을 선택했기 때문에이 정보는 필요하지 않습니다. .

o 의 실제 선택은 다음과 같습니다. 우리는 마지막 행 이외의 각 행 다음에 장애물이있는 것으로 가정하고 (즉, 이에 #추가 된), 결과 코스에서 첫 번째 장애물을 읽기 순서로 선택합니다. 원래 장애물이 없었던 행 (마지막 이외의 행)의 경우, 이는 실제로 행을 건너 뛰는 것을 의미합니다 (아래 경로는 맨 위 행의 모든 ​​문자에서 시작할 수 있음). 결국 우리는 장애물이없는 단일 행이있는 코스로 끝납니다. 가능한 경로는 하나뿐입니다.


이것은 내가 고려했던 해결책과 거의 같습니다. 나는 기회를 갖기 전에 누군가가 그것을 게시 할 것이라는 것을 알았다.
quintopia

6

CJam, 85 84 82 81 80 79 바이트

qN/:Q,(Qz,(:R_T]2/e~e!{'#Qs@{\(\@>}%s-},{_}{(a\L{@+_@\-_{2$\f.=0fe=2&},}h;}w;],

온라인으로 사용해보십시오. 또는 전체 테스트 스위트를 실행하십시오.

이 솔루션의 효율성은 아마도 끔찍하지만 몇 초 안에 각 테스트 사례를 해결합니다.

설명

나중에 코드의 전체 분석을 추가해야하지만 알고리즘 아이디어는 다음과 같습니다.

  • 그리드의 너비와 높이를 각각 WH로 설정하십시오.
  • 우리는 가능한 모든 경로를 W-1사본 0H-1사본의 구별 순열 W-1( 0수평 단계와 W-1수직 단계를 나타냄)로 생성합니다. 그리드의 첫 번째 요소를 반복적으로 가져온 다음 step셀을 읽기 순서 ( 또는 위치 step) 에서 건너 뛰어 해당 경로를 모두 걸습니다 . 를 포함하는 모든 경로를 버립니다 .0W-1#
  • 그런 다음 유사한 경로의 한 그룹을 반복적으로 제거합니다 (모든 나머지 경로는 나머지 경로 중 첫 번째와 유사 함). 비슷한 경로를 확인하면 경로가 약간 완화되어 조금 더 쉬워집니다. 경로가 x이동 했는지 확인하는 대신 경로가 정확히 두 곳에서 다른지 확인합니다. 이 경우 두 장소는 수직 및 수평 이동으로 바뀝니다. 이로 인해 이동 사이의 전체 세그먼트가 하나의 셀만큼 대각선으로 이동합니다. 그러나 두 경로가 모두 유효한 경우 경로의 일부를 대각선으로 하나의 셀만큼 이동하면 장애물을 통과 할 수 없으므로 서로 비슷합니다. 우리는 여전히 전 이적 폐쇄를 찾아야하므로 다음 그룹으로 넘어 가기 전에 더 이상 유사한 길을 찾을 때까지 계속 그렇게합니다.
  • 마지막으로 찾은 그룹을 세어 스택 맨 아래에 남았습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.