빌 게이츠를 능가 할 수 있습니까?


13

팬케이크 정렬은 주걱을 스택의 어느 지점 에나 삽입 할 수 있고 그 위의 모든 팬케이크를 뒤집는 데 사용할 수있을 때 무질서한 팬케이크 스택을 크기 순서대로 정렬하는 수학 문제에 대한 구어체 용어입니다. 팬케이크 번호 P (n)n 팬케이크에 필요한 최소 플립 횟수입니다 . 1

1979 년에 빌 게이츠와 크리스토스 파파 디미트리 우 (Christos Papadimitriou)는 P (n) = (5n + 5) / 3 의 상한을 입증하는 논문을 썼습니다 . 2

Gates (및 / 또는 Papadimitriou)가 개발 한 알고리즘 (1979 년 이후)을 사용하여 팬케이크 정렬을 수행하는 프로그램을 작성했다고 가정하는 것이 안전하다고 생각합니다. 게이츠는 숙련 된 프로그래머 였기 때문에이 코드를 최대한 활용하려고 시도했지만 소스 코드의 크기는 공개적으로 제공되지 않습니다 (AFAIK).

도전:

최대 플립 수가 Gates 및 Papadimitriou가 찾은 범위를 초과하지 않는 팬케이크 정렬을 수행하는 기능 / 프로그램을 만듭니다. 3 목록이 일치하는 한 목록을 오름차순 또는 내림차순으로 선택할 수 있습니다.

n <50 이라고 가정 할 수 있습니다 . 따라서 플립 수를 (임의로 선택한 n 값으로 ) 제한해야합니다 .

 n   P(n)
38   65
49   83
50   85

출력은 각 플립 전에 주걱의 위치 여야합니다. 출력은 0 또는 1 인덱싱 될 수 있으며 상단 또는 하단에서 계산할 경우 선택할 수 있습니다.

추가 규칙 :

  • 런타임은 결정적이어야합니다.
  • 고정 된 시간 제한은 없지만 50 개의 요소가있는 목록의 출력을 제공 할 수 있어야합니다.

테스트 목록 :

나는 가장 어려운 목록을 제공 할 수 없다 (그렇다면 도전 과제가 아닌 논문을 쓰겠 다). 따라서 함수 / 프로그램을 테스트 할 수있는 임의의 숫자 목록을 제공 할 것이다. 이 목록이 "쉬운"것으로 밝혀지면 다른 사람을 추가 할 수 있습니다.

9, 63, 62, 75, 45, 78, 59, 75, 69, 3, 28, 94, 51, 10, 45, 93, 97, 80, 72, 36, 80, 88, 30, 93, 84, 80, 17, 31, 6, 80, 76, 91, 9, 76, 38, 33, 22, 15, 45, 46, 15, 98, 2, 56, 90, 27, 27, 26, 69, 25
...
74, 89, 57, 52, 70, 96, 16, 5, 77, 84, 54, 13, 90, 64, 31, 80, 3, 25, 13, 19, 13, 34, 1, 79, 35, 43, 4, 19, 82, 29, 48, 95, 97, 28, 45, 62, 64, 82, 70, 34, 38, 15, 51, 83, 21, 66, 4, 42, 74, 84
...
62, 73, 7, 90, 83, 18, 12, 35, 72, 71, 99, 67, 87, 62, 65, 70, 14, 72, 55, 92, 87, 3, 7, 4, 4, 95, 49, 25, 4, 18, 49, 39, 26, 1, 45, 64, 23, 66, 39, 17, 33, 24, 58, 72, 77, 46, 99, 71, 10, 21

빌 게이츠와 파파 디미트리 우가이 도전을보고 그들의 코드를 제공 할 수 있기를 바랍니다.

3 더 나은 상한이 발견되었지만 그에 대해 신경 쓸 필요는 없습니다.


관련 이지만 중복되지는 않습니다. 거기에 대한 답변은 여기서 작동하지 않습니다.
Stewie Griffin

그때 저의 솔루션에 BFS를 사용했지만 최소한의 플립으로 솔루션을 찾기 위해 여전히 약간의 업데이트로 작동해야합니다.
마일

@ 마일즈는 자유롭게 게시하십시오. 나는 모든 대답을 자세하게 다루지 않았지만 대부분 순진한 접근 방식을 사용했습니다.
Stewie Griffin

답변:


4

파이썬 2 (PyPy) , 238 (235) 222 바이트

a=input();n=len(a);r=range(n);a=zip(a,r);a=map(sorted(a).index,a)+[n]
def s(u,m):
 if m<1:return[0]
 for k in r:
  v=u[k::-1]+u[k+1:]
  if sum(1<abs(v[i]-v[i+1])for i in r)<m:
   p=s(v,m-1)
   if p:return[k]+p
print s(a,5*n/3)

* (2 칸 = 탭)

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

목록 순위 지정 방법을 빌리는 13 바이트를 절약했습니다 .

플립이 분류시 인접 할 "팬케이크"쌍을 분리하는지 여부를 확인하는 간단한 휴리스틱이있는 DFS. 오름차순으로 정렬합니다. 출력은 왼쪽에서 0으로 색인화되며 여기서 0은 처음 2를 뒤집습니다. 사용 된 이동의 수이다 (5/3)*n+1 < 5/3*(n+1)(18/11)*n < (5/3)*n+1 < 5/3*(n+1)(18/11)*n의 엄격한 상한 발견 2,009 .

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