Risolvi un gioco di fisarmonica


13

La fisarmonica è un gioco di carte solitario di recente in cui mi sono imbattuto in quasi tutti i layout, ma incredibilmente difficile. Puoi giocarci qui .

Regole

52 carte scoperte vengono piazzate scoperte in ordine casuale. Ad ogni turno, sostituisci una carta con una carta successiva, dove le due carte :

  • Condividi un seme o un numero e
  • Sono ad una distanza di 1 (adiacente) o 3 (due carte in mezzo).

Il gioco si vince quando rimane solo 1 carta . Si può presumere che ogni input sia risolvibile. La carta sostituita deve sempre precedere la carta sostitutiva.

Esempio

Ad esempio, considera il seguente layout:

2H,2S,1S,2D  (H: Hearts, S: Spades, D: Diamonds)

Ci sono 3 possibili mosse qui:

  1. Sostituisci il 2Hcon l'adiacente 2S, quindi finiamo con2S,1S,2D
  2. Sostituisci il 2Scon l'adiacente 1S, quindi finiamo con2H,1S,2D
  3. Sostituisci 2Hcon 2D(a una distanza di 3), quindi finiamo con2D,2S,1S

Di quelle 3 mosse, solo l'ultima ha la possibilità di vincere (vinci sostituendo 2D <- 2S, quindi 2S <- 1S).

Input Output

Il tuo compito è scrivere un risolutore di fisarmoniche . Hai superato un elenco di carte e devi restituire un elenco di mosse per risolvere il gioco.

Viene passato un elenco di carte come una stringa delimitata da virgole, in cui ogni carta viene passata come numero intero che rappresenta il loro valore numerico, quindi un personaggio che rappresenta il loro seme.

È necessario restituire un elenco di sostituzioni come stringa delimitata da virgole, in cui ogni sostituzione è nel formato Card <- Card(seguendo il formato della scheda sopra descritto). La prima carta di ogni coppia è la carta che viene sostituita.

Casi test:

5H,1C,12S,9C,9H,2C,12C,11H,10C,13S,3D,8H,1H,12H,4S,1D,7H,1S,13D,13C,7D,12D,6H,10H,4H,8S,3H,5D,2D,11C,10S,7S,4C,2H,3C,11S,13H,3S,6C,6S,4D,11D,8D,8C,6D,5C,7C,5S,9D,10D,2S,9S
5H,9C,11H,7S,7D,12D,6H,10S,3H,4D,12C,2S,3C,5C,7H,6S,1H,8S,2H,11S,4C,10D,12H,9H,2D,4H,6C,13H,11C,2C,10H,8C,1S,11D,3S,12S,7C,5D,13S,8D,4S,6D,13C,3D,8H,13D,1D,9D,9S,1C,5S,10C
7H,11C,8C,7S,10D,13H,4S,10C,4D,2C,4H,13D,3C,2H,12C,6C,9H,4C,12H,11H,9S,5H,8S,13S,8H,6D,2S,5D,11D,10S,1H,2D,5C,1C,1S,5S,3H,6S,7C,11S,9C,6H,8D,12S,1D,13C,9D,12D,3D,7D,10H,3S

Mentre questa competizione è un , sono particolarmente interessato a soluzioni efficienti in termini di tempo e probabilmente ricompenserò soluzioni ingegnose con taglie. Detto questo, le soluzioni che richiedono tempi astronomici sono ancora accettabili (consiglierei di provare con un mazzo più piccolo, come un mazzo da 16 carte, 4 semi).


Le tue regole menzionano che le mosse possono essere fatte solo in una direzione?
feersum,

6
Ogni carta sul tavolo ha in media circa 0,25 + 0,25 = 0,5 mosse legali. Pertanto lo spazio di ricerca è di circa 52! * 0,5 = 4E67. La sfida scritta (con tag golf code) può essere interpretata solo come richiesta per cercare l'intero spazio e riportare qualsiasi soluzione (o "nessuna" se esaurita), che lascia poco spazio all'ingegnosità e richiede tempi astronomici. Ti suggerisco di renderlo una sfida del codice, considerando la percentuale e il tempo di successo, e ridurre l'influenza della lunghezza del codice sul punteggio o eliminarlo del tutto.
Level River St

1
@ Pietu1998 e qui sta il problema. Presumo che il memorizzatore ti stia costando byte, quindi dovresti inviare la versione senza il memorizzatore come versione golfata, ma diventa impossibile testare su un mazzo da 52 carte. Codegolf non funziona bene come sistema di punteggio su problemi con ampi spazi di ricerca.
Level River St

3
Sono d'accordo con i runtime astronomici per coloro che vogliono essere competitivi nel code-golf. Tuttavia, le persone sono certamente in grado (e incoraggiate) a pubblicare risposte che non sono competitive e riguardano il tempo di esecuzione.
Nathan Merrill,

4
Inoltre, se si desidera testare una soluzione di code-golf, non è necessario un mazzo da 52 carte. Un mazzo di 16 carte (4 semi) dovrebbe fornire brevi tempi di autonomia e verificare la correttezza.
Nathan Merrill,

Risposte:


5

Python 3, 274 272 271 byte

2 byte salvati grazie a @orlp .

def g(p):
 q=lambda a:[[i,a]for i in range(len(p)-a)if p[i][:-1]==p[i+a][:-1]or p[i][-1]in p[i+a]]
 for n in q(1)+q(3):
  s=sum(n);c=p[:s]+p[s+1:];c[n[0]]=p[s]
  if g(c):return p[n[0]]+' <- '+p[s]+','+g(c)
 return' 'if len(p)<2else[]
print(g(input().split(','))[:-2]or'')

Questo è estremamente lento. Tuttavia, puoi provarlo con un memoize . Questo ha un qualche extra list- tupleconversioni, ma è comunque equivalente.

import functools
@functools.lru_cache(maxsize=None)
def g(p):
 q=lambda a:[[i,a]for i in range(len(p)-a)if p[i][:-1]==p[i+a][:-1]or p[i][-1]in p[i+a]]
 for n in q(1)+q(3):
  s=sum(n);c=list(p[:s]+p[s+1:]);c[n[0]]=p[s]
  if g(tuple(c)):return p[n[0]]+' <- '+p[s]+','+g(tuple(c))
 return' 'if len(p)<2else[]
print(g(tuple(input().split(',')))[:-2]or'')

Anche questo è astronomicamente lento con determinati input.

Il codice utilizza stringhe, non numeri, quindi supporta anche la notazione come KHanziché 13H.

Esempio:

$ python accordion.py
5H,9C,11H,7S,7D,12D,6H,10S,3H,4D,12C,2S,3C,5C,7H,6S,1H,8S,2H,11S,4C,10D,12H,9H,2D,4H,6C,13H,11C,2C,10H,8C,1S,11D,3S,12S,7C,5D,13S,8D,4S,6D,13C,3D,8H,13D,1D,9D,9S,1C,5S,10C
7S <- 7D,7D <- 12D,3C <- 5C,12H <- 9H,11C <- 2C,3S <- 12S,13D <- 1D,1D <- 9D,9D <- 9S,2S <- 6S,7H <- 1H,6S <- 8S,1H <- 2H,8S <- 11S,2H <- 9H,10D <- 2D,9H <- 4H,4H <- 4C,5C <- 4C,4D <- 4C,4C <- 12C,10S <- 11S,11H <- 11S,6H <- 3H,12D <- 2D,12C <- 2C,2C <- 6C,6C <- 8C,12S <- 13S,5D <- 6D,6D <- 8D,8D <- 3D,4S <- 9S,13S <- 9S,11D <- 3D,7C <- 1C,1S <- 1C,1C <- 13C,8C <- 13C,13C <- 13H,13H <- 10H,2D <- 3D,3D <- 3H,3H <- 8H,8H <- 10H,11S <- 5S,5H <- 10H,5S <- 9S,10H <- 10C,10C <- 9C,9C <- 9S

Usa functools.lru_cacheinvece di scrivere il tuo.
orlp,

@orlp lo farei, ma dato listche non è lavabile non funziona.
PurkkaKoodari,

Quindi usa le tuple.
orlp,

@orlp OK, ma ciò richiederebbe modifiche al codice (es. str.splitritorni list). Preferirei che i due programmi fossero funzionalmente equivalenti.
PurkkaKoodari,

Si potrebbe fare h=lambda p:lru_cache(None)(g)(''.join(p)).
orlp,
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.