Покрытие каждый блин

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

Haskell, 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 теперь вам прямо сказал OP ... Я ожидаю изменений в ближайшее время.
Джон Дворак,
10

Python, 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
GRC
источник
Это действительно очень умный способ повернуть вспять. +1
Сохам Чоудхури
Похоже, вы исключаете тарелку из проверки "все сиропообразно". Тебе нужно? Когда все поверхности блинов покрыты, тарелка будет касаться сиропообразной поверхности блинов, поэтому тарелка тоже будет сиропной.
user2357112 поддерживает Monica
@ 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)
XNOR
источник
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
feersum
источник
3

APL, 77

∧/⊃{x[1]+←⍺⌷x←⍵⋄(⌽⍺↑x),⍺↓x}/(⌽1+⎕),⊂1,⎕⍴0
TwiNight
источник
2

Python 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, ...], оканчивающемся новой строкой.

TheSpanishInquisition
источник
интересный подход.
гордый haskeller
Как насчет того, чтобы вместо использования функций для кодирования списка наследований использовать списки, т. е. n%i|i>n=[i]|i<n=[n-i]|0<1=[n,0]вместо foldr($)[].map(n%)have (=<<).(%), это отобразит все наследования и объединит их.
гордый haskeller
Вы заставили меня понять, что я могу начать со стопки [0..]и представлять блины с покрытием как 0 вместо того, чтобы делать блины с ненулевым покрытием. Благодарность!
гордый haskeller