모든 팬케이크 코팅


35

당신은 접시 위에 팬케이크 를 쌓아 놓고 시럽이 굵어 져서 옆으로 내려갈 수 없습니다. 각 팬케이크의 양쪽 얼굴이 시럽에 적어도 닿을 때까지는 기뻐하지 않지만, 지금은 상단 팬케이크의 한 면만 먹습니다.

시럽은 한 번의 팬케이크까지 담그지 않지만 두 팬케이크 사이의 대면 접촉을 통해 무기한으로 옮길 수 있습니다. 팬케이크의 얼굴이 시럽에 닿으면 시럽으로 영원히 코팅 된 것으로 간주되며 시럽으로 코팅 된 비 시럽으로 코팅 된 얼굴을 만듭니다. 시럽을 플레이트의 상면으로 또는 플레이트의 상측으로 이송 할 수도 있습니다.

팬케이크 정렬 에서와 같이 하나 이상의 팬케이크 아래에 주걱을 삽입하고 뒤집어 모든 팬케이크 얼굴을 시럽으로 코팅 합니다 . (안타깝게도이 주걱은 시럽에 강하며 팬케이크 얼굴을 만져서 시럽을 분배하는 데 도움이되지 않습니다.) 슬프게도 어떤 팬케이크 얼굴이 시럽에 닿았는지 추적하지 못하지만 뒤집힌 부분은 기억합니다.

과거에 뒤집힌 음식이 있다면 팬케이크가 모두 시럽으로 코팅되어 있는지 확인할 수 있습니까?

도전

팬케이크의 수는 양의 정수 N, 지금까지 뒤집은 양수의 정수 목록 (모두 <= N)을 사용하는 프로그램을 작성하십시오. 목록의 각 숫자는 뒤집힌 팬케이크 수를 나타냅니다. 팬케이크 코팅이 완료되면 참 값을, 그렇지 않으면 거짓 값을 출력합니다. ( 진실 / 거짓 정의 )

입력은 stdin 또는 명령 행에서 가져와야하며 출력은 stdout (또는 가장 가까운 대안)으로 이동해야합니다. 입력에 약간의 추가 형식이 필요한 경우가 [1, 1, 2, 2]좋습니다 ( 예 : 1 1 2 2목록 대신) .

N = 2라고 가정하면 시럽이 맨 위에서 시작하여 접시에 두 개의 팬케이크가 쌓입니다.

목록이 1 1 2 2이면, 이는 우리가 ...

  • 상단 팬케이크 뒤집기-하단 팬케이크의 윗면 코팅
  • 상단을 다시 뒤집습니다-상단 팬케이크의 원래 바닥면을 코팅
  • 둘 다 뒤집어-판을 코팅
  • 다시 뒤집어-바닥 팬케이크의 원래 바닥면 코팅

네 얼굴이 코팅되어 있기 때문에 출력은 같은 것 True또는 1.

목록이 1 2 2 1이면, 이는 우리가 ...

  • 상단 팬케이크 뒤집기-하단 팬케이크의 윗면 코팅
  • 둘 다 뒤집기-코팅 없음
  • 다시 뒤집기-아무것도 코팅하지 않음
  • 상단을 다시 뒤집습니다-상단 팬케이크의 원래 바닥면을 코팅

플레이트에 닿는면에 여전히 시럽이 없기 때문에 출력은 False또는 과 같습니다 0.

노트

  • 플립리스트는 임의로 클 수 있으며 비어있을 수 있으며,이 경우 출력이 잘못됩니다.
  • 플레이트는 시럽 운반체 역할을하지만 코팅 여부는 중요하지 않습니다. (실제로 접는 팬케이크면을 코팅해야하지만 어떤 식 으로든 플립 솔루션 플레이트를 코팅합니다.)
  • 플레이트를 뒤집을 수 없습니다.
  • 이 팬케이크는 말할면이없고 두 개의 반대 면만 있는 장치 디스크 라고 가정 할 수 있습니다 .

채점

이것은 코드 골프입니다. 바이트 단위 의 최단 솔루션 이깁니다.


4
이것은 매우 좋은 도전입니다. ;)
Soham Chowdhury

목록을 가져오고 부울을 반환하는 함수는 괜찮습니까?
자랑스러운 Haskeller

9
이 언어로 구현할 수 있다면 보너스가 있어야합니다 .
grc

3
@grc 이제 그에 대한 현상금이 있습니다!
Calvin 's Hobbies

2
팬케이크 스택 내 솔루션은 다음과 같습니다 Put syrup on the pancakes!.;)
rodolphito

답변:


9

CJam, 32 30 29 바이트

q~2@#2b\{)/(W%)1$0=|@]s:~}/:&

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

테스트 사례

$ cjam pancakes.cjam <<< '2 [1 1 2 2]'; echo
1
$ cjam pancakes.cjam <<< '2 [1 2 2 1]'; echo
0

작동 원리

q~                            " N, L := eval(input())                                     ";
  2@#2b                       " P := base(2 ** N, 2)                                      ";
       \{                }/   " for F in L:                                               ";
         )/                   "   P := split(P, F + 1)                                    ";
           (W%)               "   T, U, V := P[1:], reverse(P[0])[:-1], reverse(P[-1])[0] ";
               1$0=|          "   V |= U[0]                                               ";
                    @]s:~     "   P := map(eval, str([U, V, T]))                          ";
                           :& " print and(P)                                              ";

17
CJam? CRup과 비슷합니다.
Ingo Bürk

12

하스켈, 92 90 86 84 114 110 99 98

전체 프로그램의 요구 사항은 매우 성가시다. 왜 누군가가 이것을 요구하는지 궁금합니다.

m(n:s)=all(<1)$foldl(\r@(p:s)n->reverse(take n s)++(p*r!!n):drop n s)[0..n]s
main=readLn>>=print.m

이 솔루션은 인접한 팬케이크가 같은면을 공유 할 때 팬케이크 더미를 측면 목록으로 표시하여 작동합니다. 모든면은 숫자이고면이 0이면면이 코팅됩니다.

다음과 같이 실행하십시오.

*Main> main
[2,1,1,2,2]
True

1
Python 2를 사용하지 않는 경우 +1;)
Calvin 's Hobbies

@ Calvin'sHobbies LOL
자랑스런 하스 켈러

전체 프로그램이 필요합니다 ...
John Dvorak

1
@ JanDvorak 나는 그것을 보지 못했다 ... 나는 질문에 대한 의견에 기능이 괜찮은지 물었다. 그렇지 않은 경우 변경하겠습니다
자랑스런 Haskeller

@proudhaskeller는 이제 OP에 의해 명시 적으로 들었습니다 ... 곧 변경 될 것으로 예상됩니다.
John Dvorak

10

파이썬, 92 바이트

나는 이것이 효과가 있다고 생각한다.

s=[1]+[0,0]*input()
for f in input():x=f*2;s[0]=s[x]=s[0]|s[x];s[:x]=s[x-1::-1]
print all(s)

시럽으로 코팅 된 팬케이크면 (플레이트 포함) 목록을 사용합니다. 팬케이크는 목록의 일부를 뒤집 으면 뒤집어 지지만 시럽은 먼저 윗면과 새로 공개 된면 사이로 옮겨집니다.

용법:

$ python pancakes.py
2
1, 1, 2, 2
True

그것은 정말로, 정말로 영리한 방법입니다. +1
Soham Chowdhury

"모든 것이 시럽입니다"체크에서 플레이트를 제외하고있는 것 같습니다. 당신은해야합니까? 모든 팬케이크면이 코팅되면 플레이트가 시럽 팬케이크면에 닿아 플레이트도 시럽이됩니다.
user2357112는

@ user2357112 네, 그렇습니다. 감사!
grc

8

파이썬 2:75

grc와 feersum의 솔루션의 단순화.

n,b=input()
s=[1]+[0]*n
for x in b:s[:x+1]=s[x::-1];s[x]|=s[0]
print all(s)

2*n+1접촉 가장자리는 항상 동일하므로 팬케이크 가장자리 의 시럽 상태를 저장하는 것은 중복됩니다. 대신 각 n+1팬케이크 접합 의 상태를 기억합니다 . 이렇게하면 시럽 이전이 자동으로 처리됩니다.

필요한 업데이트 x는 플립이 절단 될 때 접합부에 시럽을 보존하는 것입니다. 이 작업은에 포스트 플립 시럽을에 0넣습니다 x.

두 번 입력해도 문자 수에는 영향을 미치지 않습니다.

s=[1]+[0]*input()
for x in input():s[:x+1]=s[x::-1];s[x]|=s[0]
print all(s)

5

파이썬 2, 93 바이트

처음에 나는 대답을 게시하려고했지만 grc은 이미 1 분 전에 비슷한 것을 게시했습니다. 그래서 몇 가지 개선을 시도했습니다. 내가 찾을 수있는 유일한 방법은 대신 사전 편찬 목록 비교를 사용하는 것입니다 all().

편집 : 문자 수를 변경하지 않는 다른 입력 방법을 시도하지 못하여 실수가 발생했습니다.

n,F=input()
L=[1]+2*n*[0]
for f in F:f*=2;L[0]=L[f]=L[0]|L[f];L[:f]=L[~-f::-1]
print[1]*2*n<L

샘플 입력 / 출력 :

2, [1, 1, 2]

 

False

3

APL, 77

∧/⊃{x[1]+←⍺⌷x←⍵⋄(⌽⍺↑x),⍺↓x}/(⌽1+⎕),⊂1,⎕⍴0

2

파이썬 2, 107

d=[1]+[0,0]*input()
for i in input():n=2*i;d[:n]=reversed(d[:n]);d[n]=d[n-1]=d[n]|d[n-1]
print(all(d[:-1]))

2

하스켈, 129 , 125

t(m:l)=all(any(<1).(\i->foldr(\n->foldr($)[].map(n%))[i]l))[0..m]
n%i|i>n=(i:)|i<n=(n-i:)|1>0=(n:).(0:)
main=readLn>>=print.t

아직 완전히 골프는 아니지만 코팅 된면의 목록을 조작하지 않고도 작동합니다. 대신, 주어진 팬케이크의 주어진면이 처음에 맨 위에있는 것과 접촉했는지 여부를 알아 내기 위해 거꾸로 작동합니다. foldr뒤집기 목록을 효과적으로 뒤로 이동하므로이 없습니다 reverse.

알고리즘은 다음과 같습니다. 우리는 모든 관련 측면 ( [0..m])을 매핑 하고 뒷면에서 시작하여 각 단계에서 시럽을 상속하는 측면 목록을 만듭니다. 처음에는 목록은 단지 [i]이지만 n팬케이크 플립 , 각 항목 될 [n-i]경우 i<n, [n,0]경우 i==n, 그리고 [i]경우 i>n. 모든 플립 후 결과 목록에 0( any (<1)) 가 포함 된 경우에만 해당면이 코팅됩니다 . all나머지를 수행 main하고이 모든 것을 실행 가능한 프로그램으로 변환합니다.

프로그램은 개행 문자로 끝나는 stdin형식으로 입력을 [n_pancakes, flip1, flip2, flip3, ...]받습니다.


흥미로운 접근법.
자랑스런 Haskeller

방법에 대한 대신, 코드, 즉 사용 목록에 상속 목록 기능을 사용 n%i|i>n=[i]|i<n=[n-i]|0<1=[n,0]하고 대신 foldr($)[].map(n%)(=<<).(%)모든 상속을지도하고 그들과 합류 것이다.
자랑스러운 haskeller

[0..]0이 아닌 팬케이크를 코팅하는 대신 코팅 된 팬케이크를 쌓아서 0으로 나타낼 수 있다는 것을 깨달았습니다 . 감사!
자랑스런 Haskeller
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.