Покриття кожного млинця


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
Це дуже-дуже приємний виклик. ;)
Сохам Чоуддурі

це функція, яка отримує список і повертає булеву помилку?
гордий haskeller

9
Має бути бонус, якщо хтось може реалізувати його на цій мові .
grc

3
@grc Зараз є щедрість за це!
Хобі Кальвіна

2
Ось мій розчин у Put syrup on the pancakes!
млинчиковій стеці:;

Відповіді:


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.
Інго Бюрк

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

це рішення працює, представляючи купу млинців за списком сторін, коли сусідні млинці мають ту саму сторону. кожна сторона є числом, а сторона покрита, якщо вона має нульове значення.

працювати як:

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

1
+1 за не використання Python 2;)
Захоплення Кальвіна

@ Calvin'sHobbies lol
гордий haskeller

Боюся, потрібна повна програма ...
Джон Дворак

1
@JanDvorak Я цього не бачив ... Я просто запитав, чи нормально функція в коментарях до питання. якщо це не так, я його зміню
гордий haskeller

@proudhaskeller зараз вам явно сказали ОП ... Я очікую зміни незабаром.
Джон Дворак

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 підтримує Monica

@ user2357112 Так, ти маєш рацію. Спасибі!
grc

8

Пітон 2: 75

Спрощення рішення grc та феруму.

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

Python 2, 93 байт

Спочатку я збирався опублікувати свою відповідь, але потім grc вже опублікував дуже подібну хвилину раніше. Тому я спробував придумати деякі вдосконалення. Єдине, що я міг знайти, це використовувати порівняння лексикографічного списку замість 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



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 замість того, щоб робити ненульові млинці з покриттям. Спасибі!
гордий haskeller
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.