Résolvez un jeu d'Accordéon

13

L'accordéon est un jeu de cartes solitaire que j'ai récemment rencontré où presque toutes les mises en page sont résolubles, mais incroyablement difficiles. Vous pouvez y jouer ici .

Règles

52 cartes face sont placées face visible dans un ordre aléatoire. À chaque tour, vous remplacez une carte par une carte ultérieure, où les deux cartes :

  • Partagez un costume ou un numéro et
  • Sont à une distance de 1 (adjacent) ou 3 (deux cartes entre les deux).

La partie est gagnée lorsqu'il ne reste qu'une seule carte . Vous pouvez supposer que chaque entrée est résoluble. La carte remplacée doit toujours précéder la carte de remplacement.

Exemple

Par exemple, considérons la disposition suivante:

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

Il y a 3 mouvements possibles ici:

  1. Remplacez le 2Hpar le adjacent 2S, donc nous nous retrouvons avec2S,1S,2D
  2. Remplacez le 2Spar le adjacent 1S, donc nous nous retrouvons avec2H,1S,2D
  3. Remplacez le 2Hpar 2D(à une distance de 3), nous nous retrouvons donc avec2D,2S,1S

De ces 3 coups, seul le dernier a la possibilité de gagner (Vous gagnez en remplaçant 2D <- 2S, alors 2S <- 1S).

Entrée sortie

Votre travail consiste à écrire un solveur d'accordéon . Vous recevez une liste de cartes et vous devez renvoyer une liste de mouvements pour résoudre le jeu.

Vous recevez une liste de cartes sous forme de chaîne délimitée par des virgules, où chaque carte est transmise sous la forme d'un entier représentant leur valeur numérique, puis d'un caractère représentant leur couleur.

Vous devez renvoyer une liste de remplacements sous forme de chaîne délimitée par des virgules, où chaque remplacement est au format Card <- Card (suivant le format de carte décrit ci-dessus). La première carte de chaque paire est la carte à remplacer.

Cas de 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

Bien que cette compétition soit un , je suis particulièrement intéressé par les solutions efficaces et je suis susceptible de récompenser les solutions ingénieuses avec des primes. Cela dit, les solutions qui prennent des quantités astronomiques de temps sont toujours acceptables (je recommanderais de tester avec un jeu plus petit, comme un jeu de 16 cartes et 4 combinaisons).

Nathan Merrill
la source
Vos règles mentionnent-elles que les mouvements ne peuvent être effectués que dans une seule direction?
feersum
6
Chaque carte sur la table a en moyenne environ 0,25 + 0,25 = 0,5 mouvements légaux. L'espace de recherche est donc d'environ 52! * 0,5 = 4E67. Le défi tel qu'il est écrit (avec le code golf tag) ne peut être interprété que comme requis pour rechercher tout cet espace et signaler toute solution (ou "aucune" si elle est épuisée), ce qui laisse peu de place à l'ingéniosité et nécessite des échelles de temps astronomiques. Je vous suggère d'en faire un défi de code, compte tenu du taux de réussite et du temps, et de réduire l'influence de la longueur du code sur le score ou de l'éliminer complètement.
Level River St
1
@ Pietu1998 et c'est là que réside le problème. Je suppose que le mémoriseur vous coûte des octets, vous devez donc soumettre la version sans le mémoriser en tant que version golfée, mais il devient alors impossible de tester sur un jeu de 52 cartes. Codegolf ne fonctionne pas bien comme système de notation sur les problèmes avec de grands espaces de recherche.
Level River St
3
Je suis d'accord avec les temps d'exécution astronomiques pour ceux qui veulent être compétitifs au golf de code. Cependant, les gens sont certainement en mesure (et encouragés) de publier des réponses qui ne sont pas compétitives et concernent la durée d'exécution.
Nathan Merrill
4
De plus, si vous souhaitez tester une solution de code-golf, un jeu de 52 cartes n'est pas nécessaire. Un jeu de 16 cartes (4 couleurs) devrait fournir des temps d'exécution courts et vérifier l'exactitude.
Nathan Merrill

Réponses:

5

Python 3, 274 272 271 octets

2 octets enregistrés grâce à @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'')

C'est extrêmement lent. Cependant, vous pouvez l'essayer avec un mémo . Cela a un peu supplémentaire list- tupleconversions, mais est par ailleurs équivalente.

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'')

Même celui-ci est astronomiquement lent avec certaines entrées.

Le code utilise des chaînes, pas des nombres, il prend donc également en charge la notation comme KHau lieu de 13H.

Exemple:

$ 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
PurkkaKoodari
la source
Utilisez functools.lru_cacheau lieu d'écrire le vôtre.
orlp
@orlp Je le ferais, mais comme il listest inébranlable, cela ne fonctionne pas.
PurkkaKoodari
Utilisez ensuite des tuples.
orlp
@orlp OK, mais cela nécessiterait des modifications du code (par exemple des str.splitretours list). Je préférerais que les deux programmes soient fonctionnellement équivalents.
PurkkaKoodari
Tu pourrais faire h=lambda p:lru_cache(None)(g)(''.join(p)).
orlp