Winala tavole solitari Mancala


10

Mancala è il nome di una famiglia di giochi da tavolo che di solito coinvolge una serie di tazze piene di perline che i giocatori manipolano. Questa sfida utilizzerà una serie di regole specifiche per una variante del solitario del gioco.

Il tabellone è costituito da un "cestino" ad un'estremità, seguito da un numero infinito di tazze, numerate a partire da 1. Alcune tazze avranno un certo numero di perline. Se la ncoppa contiene esattamente nperline, puoi "seminare" le perline. Seminare significa estrarre tutte le nperle dalla tazza, quindi depositarle una alla volta in ogni tazza verso il cestino. L'ultimo tallone andrà nel cestino. Il giocatore vince quando tutte le perle sul tabellone sono nel cestino.

Chiaramente, ci sono molte schede che non sono vincibili, come se ci fosse esattamente un tallone nella seconda tazza. Non ci sono giochi legali perché tutte le coppe con 0 perline non possono essere seminate e la seconda coppa non ha abbastanza perline da seminare. Questo ovviamente non è divertente, quindi il tuo compito sarà quello di creare board vincibili.

Compito

Dato un numero intero positivo che rappresenta un numero di sfere emette un elenco di numeri interi non negativi che rappresentano il numero di sfere che dovrebbero essere inserite in ogni tazza per creare una scheda vincibile come descritto sopra. Questo elenco non deve contenere zero finali.

Per ogni dato numero di perline, esiste sempre esattamente una configurazione della scheda vincibile.

Dimostrazione

Questa è una dimostrazione di come giocare la tavola vincibile e input di 4. La tavola vincibile è [0, 1, 3]. Iniziamo con l'unica mossa disponibile, seminando le perline dalla terza tazza per ottenere [1, 2, 0]. Ora in realtà abbiamo una scelta, ma l'unica corretta semina la prima tazza, ottenendo: [0, 2, 0]. Quindi seminiamo la seconda tazza cedendo [1, 0, 0]e infine seminiamo di nuovo la prima tazza per ottenere tutte le tazze vuote.

Casi test:

1 => [1]
2 => [0, 2]
3 => [1, 2]
4 => [0, 1, 3]
5 => [1, 1, 3]
6 => [0, 0, 2, 4]
7 => [1, 0, 2, 4]
8 => [0, 2, 2, 4]
9 => [1, 2, 2, 4]
10 => [0, 1, 1, 3, 5]
11 => [1, 1, 1, 3, 5]
12 => [0, 0, 0, 2, 4, 6]
13 => [1, 0, 0, 2, 4, 6]
14 => [0, 2, 0, 2, 4, 6]
15 => [1, 2, 0, 2, 4, 6]
16 => [0, 1, 3, 2, 4, 6]
17 => [1, 1, 3, 2, 4, 6]
18 => [0, 0, 2, 1, 3, 5, 7]
19 => [1, 0, 2, 1, 3, 5, 7]
20 => [0, 2, 2, 1, 3, 5, 7]

Grazie mille a PeterTaylor per aver creato un programma per generare casi di test!


Risposte:


5

CJam (21 byte)

M{_0+0#_Wa*\)+.+}ri*`

Demo online

Spiegazione

Ho derivato in modo indipendente la tecnica "non giocante" menzionata in questo documento . Dimostriamo per induzione che esiste esattamente una tavola vincente per un dato numero di perle.

Caso base: con 0 perline, l'unica tavola vincente è quella vuota.

Fase induttiva: se seminiamo dalla tazza, kalla successiva mossa la tazza ksarà vuota e ogni tazza più vicina al cestino conterrà almeno un tallone. Pertanto, possiamo trovare l'esclusiva tavola vincente con nperline dalla tavola vincente con n-1perline cercando la tazza vuota con il numero più basso, prendendo una perlina dal cestino e una da ogni tazza sotto quella tazza vuota e posizionandole tutte nella tazza vuota.

Dissezione

M           e# Start with an empty board
{           e# Loop
  _0+0#     e#   Find position of first 0 (appending to ensure that there is one)
  _Wa*      e#   Make array of that many [-1]s
  \)+       e#   Append the index plus 1 (since board is 1-indexed)
  .+        e#   Pointwise addition
}
ri*         e# Read integer from stdin and execute loop that many times
`           e# Format for display

9

Python, 42 41 byte

m=lambda n,i=2:n*[1]and[n%i]+m(n-n%i,i+1)

4

JavaScript (ES6), 63 37 byte

f=(n,d=2)=>n?[n%d,...f(n-n%d,d+1)]:[]

Port of @ orlp's Python answer. Spiegazione: considerare il numero totale di perline nella icoppa superiore e superiore. Ogni gioco di una di queste tazze rimuoverà le iperline da quel totale. (Ad esempio, se iè 3 e giochi dalla quinta coppa, riduci il numero di perline in quella coppa di cinque, ma ne aggiungi anche una sia alla quarta che alla terza coppa.) Il totale deve quindi essere un multiplo di i. Ora la i-1coppa non può contenere io più perline, quindi per lasciarne un multiplo ideve contenere il resto del modulo perline i.

Spiegazione precedente (dal link di @ xnor): l'approccio ingenuo è la tecnica del "gioco inverso". Questo utilizza l'osservazione che fare un gioco svuota una tazza, quindi il gioco inverso raccoglie una perlina da ogni tazza e li mette nella prima tazza vuota, in questo modo (63 byte):

f=n=>n?[...a=f(n-1),0].some((m,i)=>(m?a[i]--:a[i]=i+1)>m)&&a:[]

Ora, considera solo le prime itazze. Nel caso in cui uno di essi sia vuoto, la riproduzione inversa si aggiungerà 1al numero totale di perline in quelle tazze, mentre nel caso in cui nessuno di essi sia vuoto, la riproduzione inversa verrà sottratta idal totale, tuttavia ciò equivale all'aggiunta di 1modulo i+1. Dopo che il nrovescio gioca, la somma delle perle nelle prime itazze sarà quindi equivalente al nmodulo . (Si noti che io uso in quanto utilizza meno byte.)i+1 , o in altri termini, il numero di perle nella ith tazza sarà equivalente a nmeno la somma delle perle nelle tazze precedenti, modulo i+1. Ora che la icoppa sia giocabile il numero di perline non può superare i, quindi in effetti sarà uguale al numero di perle rimanenti moduloi+1d=i+1


Hai dimenticato di assegnare la funzione nella versione usando la soluzione di @ orlp, impedendo il funzionamento della ricorsione. Anche per quanto riguarda quella soluzione, la concatenazione di array +non è una cosa in ES6?
Valore inchiostro

@KevinLau Oops, e dopo aver avuto il problema di includerlo anche nel conteggio dei byte! Ma no, + è concatenazione di stringhe, a meno che entrambi i parametri non siano numeri o valori booleani, nel qual caso si tratta di un'aggiunta. Fortunatamente la comprensione degli array semplifica la concatenazione arbitraria.
Neil,

2

Rubino, 36 byte

Una porta della risposta di @ orlp perché è troppo geniale per me pensare a qualcosa di meglio.

m=->n,i=2{n>0?[n%i]+m[n-n%i,i+1]:[]}
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.