Bulgare Solitaire

9

Bulgarian Solitaire est un jeu solo rendu populaire par Martin Gardner dans sa chronique mathématique de Scientific American .

Vous avez des Ncartes identiques, divisées en piles. Vous prenez une carte de chaque pile et formez une nouvelle pile avec les cartes retirées. Vous répétez ce processus jusqu'à ce que vous atteigniez un état que vous avez déjà vu et continuer ainsi répéterait la boucle.

Par exemple, disons que vous avez des 8cartes, divisées en une pile de 5et une pile de 3. Nous écrivons les tailles de pile dans l' ordre décroissant: 5 3. Voici une transcription du jeu:

5 3
4 2 2
3 3 1 1 
4 2 2

Vous retirez d'abord une carte de chacune des deux piles, laissant des piles de 4et 2, et une pile nouvellement créée de 2, donnant 4 2 2. Dans l'étape suivante, ces diminutions sont 3 1 1suivies d'un nouveau tas de 3. Enfin, la dernière étape vide les piles de taille 1et produit 4 2 2ce qui est déjà apparu, alors on s'arrête.

Notez que la somme des tailles de pile reste la même.

Votre objectif est d'imprimer une telle transcription du jeu à partir d'une configuration de départ donnée. C'est le golf de code, donc le moins d'octets gagne.

Contribution

Une liste de nombres positifs par ordre décroissant représentant les tailles de pieux initiales. Prenez l'entrée via STDIN ou l'entrée de fonction. Vous pouvez utiliser n'importe quelle structure de type liste que vous souhaitez.

Vous n'obtenez pas le nombre total de cartes Nen entrée.

Production

Imprimez la séquence des tailles de pile que traverse le jeu Bulgarian Solitaire. Notez que l'impression est requise, pas de retour. Chaque étape doit être sa propre ligne.

Chaque ligne doit avoir une séquence de nombres positifs dans l'ordre décroissant sans aucun 0. Vous pouvez avoir des séparateurs et des jetons de début et de fin (par exemple, [3, 3, 1, 1]). Les numéros peuvent avoir plusieurs chiffres, ils doivent donc être séparés d'une manière ou d'une autre.

Imprimez les fractionnements de la taille des piles que vous voyez jusqu'à ce que la répétition soit incluse. Ainsi, la première ligne doit être l'entrée et la dernière ligne doit être une répétition d'une ligne précédente. Il ne devrait pas y avoir d'autres répétitions.

Cas de test

>> [1]
1
1

>> [2]
2
1 1
2

>> [1, 1, 1, 1, 1, 1, 1]
1 1 1 1 1 1 1
7
6 1
5 2
4 2 1
3 3 1
3 2 2
3 2 1 1
4 2 1

>> [5, 3]
5 3
4 2 2
3 3 1 1
4 2 2

>> [3, 2, 1]
3 2 1
3 2 1

>> [4, 4, 3, 2, 1]
4 4 3 2 1
5 3 3 2 1
5 4 2 2 1
5 4 3 1 1
5 4 3 2
4 4 3 2 1
xnor
la source

Réponses:

4

Pyth, 40 25

QW!}QY~Y]Q=Q_S+fTmtdQ]lQQ

C'est assez proche d'une traduction de ma réponse python 2.

Exemple d'exécution:

Contribution:

[4,4,3,2,1]

Production:

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]

Comment ça fonctionne:

Q                          Q = eval(input()) # automatic
 W!}QY                     while not Q in Y:
      ~Y]Q                     Y += [Q]
               fTmtdQ                     filter(lambda T: T, map(lambda d: d - 1, Q))
            _S+      ]lQ           sorted(                                             + [len(Q)])[::-1]
          =Q_S+fTmtdQ]lQ       Q = sorted(filter(lambda T: T, map(lambda d: d - 1, Q)) + [len(Q)])[::-1]
                        Q      print(Q)
QW!}QY~Y]Q=Q_S+fTmtdQ]lQQ
Justin
la source
1. Vous pouvez remplacer v$input()$par Q. 2. Si vous stockez la liste par ordre décroissant, vous n'avez pas besoin Ndu tout:W!}QYQ~Y]Q=Q_S+fTmtdQ]lQ;Q
Dennis
@Dennis Merci, je ne savais pas comment faire ça; Je savais qu'il y avait un moyen de le faire.
Justin
1
Voici ce que je l'ai fait, tout à fait indépendamment: QW!}QY~Y]Q=Q_S+]lQfTmtdQQ. C'est exactement la même chose, caractère pour caractère, jusqu'à la commutativité.
isaacg
3

CJam, 26 octets

q{~_:(_,+0-$W%]___&=}g{p}/

Essayez-le en ligne.

Exemple d'exécution

$ cjam <(echo 'q{~_:(_,+0-$W%]___&=}g{p}/') <<< '[5 3]'
[5 3]
[4 2 2]
[3 3 1 1]
[4 2 2]
Dennis
la source
C'est du CJam!
Optimizer
Allez !, je sais que vous pouvez le rendre plus court que Pyth un!
Optimizer
Si :pje travaillais, je pourrais ...
Dennis
4
Arrête de pleurnicher! :p
Optimizer
3

Rubis, 98

f=->c{g={c=>1}
p *loop{c=(c.map(&:pred)<<c.size).sort.reverse-[0]
g[c]?(break g.keys<<c): g[c]=1}}

Explication

  • L'entrée est considérée comme l'argument d'un lambda. Il attend un Array.
  • Les états de jeu précédents sont stockés dans le Hash g.
  • Pour créer un nouvel état de jeu, utilisez Array#mappour diminuer chaque élément de 1, ajoutez la longueur de l' Arrayélément en tant qu'élément, triez-le dans l'ordre décroissant et supprimez l'élément 0.
  • Pour vérifier si un état de jeu a déjà été vu, il gsuffit de vérifier s'il possède une clé pour un nouvel état de jeu.
britishtea
la source
+1 Ruby vraiment bien joué au golf ici! Cependant, bien que la sort_bychose soit certainement intelligente, sort.reverseest en fait un caractère plus court ^^
daniero
Aww, c'est dommage. Merci.
britishtea
2

CJam, 35 34 33 octets

(Merde, cette coupure de courant que je n'étais pas le premier à poster dans CJam)

l~{_p:(_,+{},$W%_`_S\#0<\S+:S;}g`

Contribution:

[1 1 1 1 1 1 1]

Production:

[1 1 1 1 1 1 1]
[7]
[6 1]
[5 2]
[4 2 1]
[3 3 1]
[3 2 2]
[3 2 1 1]
[4 2 1]

Essayez-le en ligne ici

Optimiseur
la source
1

Python 2 - 103

p=input()
m=[]
print p
while p not in m:m+=[p];p=sorted([x-1 for x in p if x>1]+[len(p)])[::-1];print p

Similaire à la réponse de Quincunx, mais remplace les ajouts par des ajouts et supprime les deux dernières lignes.

Exemple de sortie:

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]
Nathan Merrill
la source
Umm, similaire? C'est identique; vous avez simplement pris les mesures de golf qui étaient tout à fait évidentes. Quand je suis revenu au mien, je l'ai joué au golf et j'ai découvert que c'était maintenant une réponse en double de moi (ou vice versa, mais vous voulez la voir)
Justin
J'ai découvert votre réponse seulement après avoir posté la mienne. Je suis d'accord avec les considérer comme des doublons les uns des autres.
Nathan Merrill
1

GolfScript, 50 46

~.p$[]{[1$]+\.{(.!";"*~}%\,+$.-1%p\.2$?)!}do];

Peut presque certainement être joué plus loin. Essayez-le ici.

Justin
la source
1

Haskell, 99

import Data.List
g l=until(nub>>=(/=))(\l->l++[reverse$sort$length(last l):[x-1|x<-last l,x>1]])[l]
fier haskeller
la source
1

CJam, 40 36 34 octets

]l~{a+_W=_p:(_,+$W%{},1$1$a#0<}gp;

Testez-le ici. Entrez l'entrée comme un tableau de style CJam, comme [5 3]dans le champ STDIN. Le format de sortie est similaire, donc les crochets et les espaces comme délimiteurs.

Même si je joue plus loin (ce qui est certainement possible), il n'y a aucun moyen de battre Pyth avec ça. Il est peut-être temps d'apprendre J. Explication plus tard.

Martin Ender
la source
Je ne suis pas sûr que J vous aidera, je ne peux pas obtenir mon APL en dessous de 38
TwiNight
1

JavaScript (E6) 113

Pire entrée jusqu'à présent :(

F=l=>{
  for(k=[];console.log(l),!k[l];)
    k[l]=l=[...l.map(n=>(p+=n>1,n-1),p=1),l.length].sort((a,b)=>b-a).slice(0,p)
}

Test dans la console FireFox / FireBug

F([4,4,3,2,1])

Production

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]
edc65
la source
1

Python 2, 148 130 101 101

l=input()
s=[]
print l
while l not in s:s+=l,;l=sorted([i-1for i in l if 1<i]+[len(l)])[::-1];print l

Cela se souvient simplement de toutes les itérations précédentes et vérifie si la nouvelle est dans cette liste. Ensuite, il l'imprime.

Exemple d'exécution:

Contribution:

[4,4,3,2,1]

Production:

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]

Edit: J'ai relu les spécifications pour le golf, et appliqué beaucoup de golf.

Justin
la source
Vous pouvez simplement imprimer les listes sous forme de listes.
xnor
@xnor Ooh merci, complètement raté cela.
Justin
Cela ne fonctionnera pas avec [5,3]
Nathan Merrill
Cela donne la mauvaise sortie pour [4,2,2]. Il existe cependant une solution simple.
xnor
0

Python 3: 89 caractères

g=lambda l,s=[]:print(l)!=l in s or g(sorted([x-1for x in l if~-x]+[len(l)])[::-1],s+[l])

Tout comme les solutions Python déjà publiées, mais avec des appels de fonction récursifs plutôt que des boucles. La liste sstocke les divisions déjà vues et court-circuite la récursion en cas de répétition.

La fonction print()(c'est Python 3) doit juste être appelée d'une manière ou d'une autre dans chaque boucle. La chose délicate est que a lambdane permet qu'une seule expression, donc nous ne pouvons pas le faire print(l);.... En outre, il génère des résultats None, ce qui est difficile à utiliser. Je finis par mettre print(l)d'un côté une inégalité;==ne fonctionne pas pour une raison que je ne comprends pas.

Une approche alternative de le coller dans une liste utilise autant de caractères.

g=lambda l,s=[]:l in s+[print(l)]or g(sorted([x-1for x in l if~-x]+[len(l)])[::-1],s+[l])

L'utilisation print(*l)formaterait les sorties comme 4 2 2plutôt que [4,2,2].

xnor
la source