Phủ mỗi bánh kếp


35

Bạn có một chồng bánh kếp trên một cái đĩa với một khối xi-rô trên đầu dày đến nỗi nó không thể chảy xuống hai bên. Bạn sẽ không vui khi ăn cho đến khi cả hai mặt của mỗi chiếc bánh đều ít nhất chạm vào xi-rô, nhưng ngay bây giờ chỉ có một khuôn mặt của bánh kếp hàng đầu.

Bạn biết rằng xi-rô sẽ không bao giờ ngấm qua dù chỉ một chiếc bánh, nhưng nó có thể được chuyển vô thời hạn thông qua tiếp xúc trực diện giữa hai chiếc bánh. Khi một mặt của bánh kếp đã chạm vào xi-rô, nó được coi là được tráng trong xi-rô mãi mãi, và sẽ làm cho bất kỳ mặt nào không có xi-rô chạm vào xi-rô cũng được tráng. Có thể chuyển xi-rô đến và từ phía trên cùng của tấm.

Bạn tiến hành phủ mỗi mặt bánh kếp bằng xi-rô bằng cách chèn một thìa bên dưới một hoặc nhiều bánh kếp và lật chúng lại, chính xác như được thực hiện trong phân loại bánh kếp . (Thật không may, thìa này có khả năng kháng xi-rô và không giúp phân phối xi-rô bằng cách chạm vào mặt bánh kếp.) Thật đáng buồn khi bạn mất dấu vết mà mặt bánh kếp đã chạm vào xi-rô nhưng bạn vẫn nhớ những cú lật bạn đã làm.

Dựa vào những lần lật trong quá khứ của bạn, bạn có thể xác định xem bánh kếp của bạn đã được phủ xi-rô chưa?

Thử thách

Viết chương trình lấy số nguyên dương N cho số lượng bánh kếp và danh sách các số nguyên dương (tất cả <= N) cho các lần lật mà bạn đã thực hiện cho đến nay. Mỗi số trong danh sách đại diện cho số lượng bánh được lật. Xuất ra một giá trị trung thực nếu bánh kếp được hoàn thành và phủ một giá trị giả nếu không. ( định nghĩa trung thực / giả mạo )

Đầu vào phải đến từ stdin hoặc dòng lệnh và đầu ra sẽ đi đến thiết bị xuất chuẩn (hoặc các lựa chọn thay thế gần nhất). Sẽ ổn nếu đầu vào của bạn cần thêm một chút định dạng: ví dụ [1, 1, 2, 2]thay vì 1 1 2 2cho danh sách.

Ví dụ

Giả sử N = 2, vì vậy chúng ta có một chồng hai bánh trên một đĩa, bắt đầu với xi-rô trên đầu.

Nếu danh sách là 1 1 2 2, điều này có nghĩa là chúng tôi ...

  • lật bánh kếp trên cùng - phủ lên mặt trên của bánh kếp dưới
  • lật mặt trên một lần nữa - phủ mặt dưới ban đầu của bánh kếp trên cùng
  • lật cả hai - phủ tấm
  • lật cả hai lần nữa - phủ mặt dưới ban đầu của bánh kếp dưới

Vì tất cả bốn mặt được phủ, đầu ra sẽ giống như Truehoặc 1.

Nếu danh sách là 1 2 2 1, điều này có nghĩa là chúng tôi ...

  • lật bánh kếp trên cùng - phủ lên mặt trên của bánh kếp dưới
  • lật cả hai - không có gì
  • lật cả hai lần nữa - không có gì
  • lật mặt trên một lần nữa - phủ mặt dưới ban đầu của bánh kếp trên cùng

Vì mặt chạm vào đĩa vẫn không có xi-rô, đầu ra sẽ giống như Falsehoặc 0.

Ghi chú

  • Danh sách lật có thể lớn tùy ý và có thể trống, trong trường hợp đầu ra là giả.
  • Tấm này hoạt động như một chất mang xi-rô nhưng không thành vấn đề nếu nó được tráng hay không. (Trong thực tế, bất kỳ giải pháp lật nào cũng sẽ phủ lên tấm vì mặt bánh pancake mà nó chạm phải được phủ, nhưng bất kể.)
  • Các tấm không thể được lật.
  • Bạn có thể giả sử những chiếc bánh này là đĩa đơn vị không có mặt để nói, chỉ có hai mặt đối diện.

Chấm điểm

Đây là mã golf. Giải pháp ngắn nhất trong byte thắng.


4
Đây là một thử thách rất, rất hay. ;)
Soham Chowdhury

Hàm có được danh sách và trả về boolean không?
tự hào

9
Cần có một phần thưởng nếu bất cứ ai cũng có thể thực hiện nó bằng ngôn ngữ này .
grc

3
@grc Bây giờ có một tiền thưởng cho điều đó!
Sở thích của Calvin

2
Đây là giải pháp của tôi trong Pancake Stack : Put syrup on the pancakes!;)
Rodolphito

Câu trả lời:


9

CJam, 32 30 29 byte

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

Hãy thử trực tuyến.

Các trường hợp thử nghiệm

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

Làm thế nào nó hoạt động

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
Thưa ông? Giống như CRup hơn.
Ingo Bürk

12

Haskell, 92 90 86 84 114 110 99 98

yêu cầu của một chương trình đầy đủ là rất khó chịu. Tôi tự hỏi tại sao mọi người sẽ yêu cầu điều này.

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

giải pháp này hoạt động bằng cách biểu diễn đống bánh kếp bằng một danh sách các mặt, khi các bánh kếp liền kề chia sẻ cùng một phía. mỗi bên là một số và một bên được phủ nếu nó có giá trị bằng không.

chạy như:

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

1
+1 khi không sử dụng Python 2;)
Sở thích của Calvin

@ Calvin'sHob sở thích lol
tự hào

Tôi sợ một chương trình đầy đủ là bắt buộc ...
John Dvorak

1
@JanDvorak Tôi không thấy điều đó ... Tôi chỉ hỏi liệu một chức năng có ổn trong các bình luận của câu hỏi không. nếu không, tôi sẽ thay đổi nó
tự hào

@proudhaskeller bây giờ bạn đã được OP nói rõ ràng ... Tôi mong đợi một sự thay đổi sớm.
John Dvorak

10

Python, 92 byte

Tôi nghĩ rằng điều này hoạt động:

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)

Nó sử dụng một danh sách các mặt bánh kếp (bao gồm đĩa) để ghi nhớ được phủ bằng xi-rô. Pancakes được lật bằng cách đảo ngược một phần của danh sách, nhưng bất kỳ xi-rô đầu tiên được chuyển giữa mặt trên và mặt mới được tiết lộ.

Sử dụng:

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

Đó là một cách thực sự, thực sự thông minh để đảo ngược. +1
Soham Chowdhury

Có vẻ như bạn đang loại trừ tấm khỏi kiểm tra "là tất cả mọi thứ xi-rô". Bạn có cần không Khi tất cả các mặt bánh kếp được tráng, tấm sẽ được chạm vào một mặt bánh kếp, vì vậy đĩa cũng sẽ được xi-rô.
user2357112 hỗ trợ Monica

@ user2357112 Vâng, bạn đúng. Cảm ơn!
grc

8

Con trăn 2: 75

Đơn giản hóa giải pháp của grc và frageum.

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

Lưu trữ trạng thái xi-rô của 2*n+1các cạnh bánh kếp là dư thừa vì các cạnh chạm luôn luôn giống nhau. Điều này thay vì ghi nhớ trạng thái của từng n+1nút giao bánh. Bằng cách đó, chuyển xi-rô được tự động chiếm.

Bản cập nhật duy nhất cần thiết là bảo quản xi-rô tại xngã ba khi một cú lật cắt nó. Điều này được thực hiện bằng cách hoặc lấy xi-rô sau lật 0vào x.

Lấy đầu vào hai lần không ảnh hưởng đến số lượng ký tự.

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

5

Python 2, 93 byte

Lúc đầu tôi định đăng câu trả lời của mình, nhưng sau đó grc đã đăng một câu rất giống một phút trước đó. Vì vậy, tôi đã cố gắng đưa ra một số cải tiến. Điều duy nhất tôi có thể tìm thấy là sử dụng so sánh danh sách từ vựng thay vì all().

Chỉnh sửa: Đã sửa lỗi được giới thiệu bằng cách không thành công khi thử các phương thức nhập khác nhau mà không thay đổi số ký tự.

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

Mẫu đầu vào / đầu ra:

2, [1, 1, 2]

 

False

3

APL, 77

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

2

Trăn 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

Haskell, 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

Có lẽ chưa hoàn toàn chơi golf, nhưng nó hoạt động mà không cần thao tác một danh sách các mặt được phủ. Thay vào đó, nó hoạt động theo cách ngược lại để tìm hiểu xem một mặt nhất định của một chiếc bánh kếp nhất định có từng tiếp xúc với bất cứ thứ gì là mặt trên cùng lúc ban đầu hay không. foldrcó hiệu quả vượt qua danh sách lật ngược, do đó không có reverse.

Vì vậy, đây là thuật toán: Chúng tôi ánh xạ qua tất cả các mặt có liên quan ( [0..m]) và lập danh sách các mặt mà phía chúng tôi thừa hưởng xi-rô từ mỗi bước, bắt đầu từ phía sau: ban đầu danh sách chỉ là [i], nhưng với một lần lật nbánh, mỗi mục trở thành [n-i]nếu i<n, [n,0]nếu i==n[i]nếu i>n. Mặt trong câu hỏi đã được phủ nếu và chỉ khi danh sách kết quả sau khi tất cả các lần lật có chứa một 0( any (<1)). allphần còn lại, và mainchuyển đổi tất cả điều này thành một chương trình có thể chạy được.

Chương trình lấy đầu vào của nó từ stdindưới dạng [n_pancakes, flip1, flip2, flip3, ...], kết thúc bởi một dòng mới.


cách tiếp cận thú vị.
tự hào

làm thế nào về thay vì sử dụng các hàm để mã hóa danh sách kế thừa để sử dụng danh sách, nghĩa là n%i|i>n=[i]|i<n=[n-i]|0<1=[n,0]thay vì foldr($)[].map(n%)(=<<).(%), điều đó sẽ ánh xạ tất cả các kế thừa và tham gia chúng.
tự hào

bạn làm cho tôi nhận ra tôi có thể bắt đầu với một chồng [0..]và đại diện cho một chiếc bánh kếp tráng là 0 thay vì làm bánh kếp không phủ. cảm ơn!
tự hào
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.