Ricoprire ogni pancake


35

Hai una pila di pancake su un piatto con sopra un globo di sciroppo così denso che non può scorrere lungo i lati. Non sarai felice di mangiare fino a quando entrambe le facce di ogni pancake non avranno toccato almeno lo sciroppo, ma in questo momento solo una faccia del pancake superiore ha.

Sai che lo sciroppo non si impregnerà mai nemmeno attraverso un pancake, ma può essere trasferito indefinitamente tramite il contatto faccia a faccia tra due pancake. Una volta che una faccia di un pancake ha toccato lo sciroppo, viene considerata ricoperta di sciroppo per sempre e renderà rivestita anche qualsiasi faccia non sciroppata che lo tocca. È possibile trasferire anche lo sciroppo da e verso il lato superiore della piastra.

Si procede a ricoprire ogni faccia di pancake con lo sciroppo inserendo una spatola sotto una o più frittelle e capovolgendole dappertutto, esattamente come avviene nello smistamento dei pancake . (Sfortunatamente questa spatola è resistente allo sciroppo e non aiuta a distribuire lo sciroppo toccando le facce del pancake.) Purtroppo perdi traccia di quali facce del pancake hanno toccato lo sciroppo, ma ricordi i colpi che hai fatto.

Dati i tuoi precedenti salti, puoi determinare se i tuoi pancake sono ancora tutti ricoperti di sciroppo?

Sfida

Scrivi un programma che includa un numero intero positivo N per il numero di pancake e un elenco di numeri interi positivi (tutti <= N) per i lanci che hai fatto finora. Ogni numero nell'elenco rappresenta il numero di pancake che sono stati capovolti. Emetti un valore veritiero se i pancake sono stati rivestiti e un valore falso in caso contrario. ( definizione di verità / falsa )

L'input dovrebbe provenire da stdin o dalla riga di comando e l'output dovrebbe passare a stdout (o alle alternative più vicine). Va bene se il tuo input ha bisogno di un po 'di formattazione extra: ad esempio [1, 1, 2, 2]invece che 1 1 2 2per l'elenco.

Esempi

Assumi N = 2, quindi abbiamo una pila di due pancake su un piatto, iniziando con lo sciroppo in cima.

Se l'elenco è 1 1 2 2, ciò significa che ...

  • capovolgi il pancake superiore - rivestendo la parte superiore del pancake inferiore
  • capovolgi di nuovo la parte superiore - rivestendo la faccia inferiore originale del pancake superiore
  • capovolgi entrambi - rivestendo la piastra
  • capovolgi di nuovo entrambi - rivestendo la parte inferiore originale del pancake inferiore

Poiché tutte e quattro le facce sono rivestite, l'output sarebbe simile a Trueo 1.

Se l'elenco è 1 2 2 1, ciò significa che ...

  • capovolgi il pancake superiore - rivestendo la parte superiore del pancake inferiore
  • capovolgi entrambi - non rivestendo nulla
  • capovolgi entrambi - non rivestendo nulla
  • capovolgi di nuovo la parte superiore - rivestendo la faccia inferiore originale del pancake superiore

Poiché la faccia che tocca la piastra è ancora priva di sciroppo, l'uscita sarebbe simile Falseo 0.

Gli appunti

  • L'elenco di fogli mobili può essere arbitrariamente grande e può essere vuoto, nel qual caso l'output è errato.
  • La piastra funge da portatore di sciroppo ma non importa se viene rivestita o meno. (In realtà qualsiasi soluzione vibrazione volontà rivestire la piastra perché la faccia pancake tocca deve essere rivestito, ma indipendentemente.)
  • La piastra non può essere capovolta.
  • Puoi presumere che questi pancake siano dischi di unità senza lati di cui parlare, solo due facce opposte.

punteggio

Questo è code-golf. Vince la soluzione più breve in byte .


4
Questa è una sfida molto, molto bella. ;)
Soham Chowdhury il

è una funzione che ottiene un elenco e restituisce un valore booleano va bene?
orgoglioso haskeller il

9
Dovrebbe esserci un bonus se qualcuno può implementarlo in questa lingua .
grc,

3
@grc Ora c'è una taglia per questo!
Calvin's Hobbies,

2
Ecco la mia soluzione in Pancake Stack Put syrup on the pancakes!
:;

Risposte:


9

CJam, 32 30 29 byte

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

Provalo online.

Casi test

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

Come funziona

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? Più come CRup.
Ingo Bürk,

12

Haskell, 92 90 86 84 114 110 99 98

il requisito di un programma completo è così fastidioso. Mi chiedo perché qualcuno dovrebbe richiedere questo.

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

questa soluzione funziona rappresentando la pila di pancake da un elenco dei lati, quando i pancake adiacenti condividono lo stesso lato. ogni lato è un numero e un lato è rivestito se ha un valore zero.

correre come:

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

1
+1 per non usare Python 2;)
Calvin's Hobbies

@ Calvin'sHobbies lol
haskeller orgoglioso

Temo che sia richiesto un programma completo ...
John Dvorak,

1
@JanDvorak Non ho visto che ... Ho solo chiesto se una funzione è ok nei commenti della domanda. se non lo è, lo cambierò
orgoglioso haskeller il

@proudhaskeller ora ti è stato detto esplicitamente dall'OP ... mi aspetto un cambiamento presto.
John Dvorak,

10

Python, 92 byte

Penso che funzioni:

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)

Usa un elenco di facce da pancake (piastra inclusa) per ricordare quali sono ricoperte di sciroppo. I pancake vengono capovolti invertendo parte dell'elenco, ma ogni sciroppo viene prima trasferito tra la faccia superiore e la faccia appena rivelata.

Uso:

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

Questo è un modo davvero molto intelligente per invertire. +1
Soham Chowdhury,

Sembra che tu stia escludendo il piatto dal controllo "è tutto sciropposo". È necessario? Quando tutte le facce del pancake sono rivestite, la piastra toccherà una faccia del pancake sciropposa, quindi anche la piastra sarà sciropposa.
user2357112 supporta Monica il

@ user2357112 Sì, hai ragione. Grazie!
grc,

8

Python 2: 75

Una semplificazione della soluzione di grc e 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)

La memorizzazione dello stato di sciroppo dei 2*n+1bordi del pancake è ridondante perché i bordi a contatto sono sempre gli stessi. Questo invece ricorda lo stato di ciascuna delle n+1giunzioni del pancake. In questo modo, il trasferimento dello sciroppo viene automaticamente contabilizzato.

L'unico aggiornamento necessario è quello di preservare lo sciroppo alla xgiunzione quando una vibrazione lo taglia. Questo viene fatto inserendo lo sciroppo post-flip 0in x.

Prendere input due volte non influisce sul conteggio dei personaggi.

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

Inizialmente stavo per pubblicare la mia risposta, ma poi grc ne aveva già postata una molto simile un minuto prima. Quindi ho provato a trovare alcuni miglioramenti. L'unico che sono riuscito a trovare è utilizzare un confronto elenco lessicografico anziché all().

Modifica: risolto un errore introdotto tentando senza successo diversi metodi di input che non cambia il conteggio dei caratteri.

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

Input / output di esempio:

2, [1, 1, 2]

 

False

3

APL, 77

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

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

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

Probabilmente non ancora completamente giocato a golf, ma funziona senza manipolare un elenco di lati rivestiti. Invece, si fa strada all'indietro per capire se un dato lato di un determinato pancake è mai entrato in contatto con qualcosa che era il lato superiore all'inizio. foldrattraversa efficacemente l'elenco di lanci all'indietro, quindi non esiste reverse.

Quindi ecco l'algoritmo: mappiamo su tutti i lati rilevanti ( [0..m]) e creiamo un elenco di lati da cui il nostro lato eredita lo sciroppo da ogni passaggio, a partire dal retro: inizialmente l'elenco è giusto [i], ma con una capatina di npancake, ogni voce diventa [n-i]if i<n, [n,0]if i==ne [i]if i>n. Il lato in questione è stato rivestito se e solo se l'elenco risultante dopo tutti i lanci contiene un 0( any (<1)). allfa il resto e mainconverte tutto questo in un programma eseguibile.

Il programma prende il suo input stdinsotto forma di [n_pancakes, flip1, flip2, flip3, ...], terminato da una nuova riga.


approccio interessante.
orgoglioso haskeller il

che ne dici invece di usare le funzioni per codificare la lista degli erediti per usare le liste, cioè n%i|i>n=[i]|i<n=[n-i]|0<1=[n,0]e invece di foldr($)[].map(n%)avere (=<<).(%), che mapperà tutte le eredità e le unirà a loro.
orgoglioso haskeller il

mi hai fatto capire che posso iniziare con una pila di [0..]e rappresentare un pancake rivestito come 0 invece di fare pancake non zero ricoperti. Grazie!
orgoglioso haskeller il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.