Bulgarischer Solitaire

9

Bulgarian Solitaire ist ein Einzelspielerspiel, das Martin Gardner in seiner mathematischen Kolumne in Scientific American bekannt gemacht hat .

Sie haben Nidentische Karten, die in Stapel aufgeteilt sind. Sie nehmen eine Karte von jedem Stapel und bilden mit den entfernten Karten einen neuen Stapel. Sie wiederholen diesen Vorgang, bis Sie einen Zustand erreicht haben, den Sie bereits gesehen haben. Wenn Sie also fortfahren, wird die Schleife wiederholt.

Angenommen, Sie haben 8Karten, die in einen Stapel 5und einen Stapel aufgeteilt sind 3. Wir schreiben die Stapelgrößen in absteigender Reihenfolge : 5 3. Hier ist eine Abschrift des Spiels:

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

Sie entfernen zuerst eine Karte von jedem der beiden Stapel, wobei Stapel von 4und 2und ein neu erstellter Stapel von 2Geben übrig bleiben 4 2 2. Im nächsten Schritt verringern sich diese, 3 1 1gefolgt von einem neuen Stapel von 3. Schließlich leert der letzte Schritt die Stapel von Größe 1und produziert, 4 2 2was bereits erschienen ist, also hören wir auf.

Beachten Sie, dass die Summe der Stapelgrößen gleich bleibt.

Ihr Ziel ist es, eine solche Abschrift des Spiels aus einer bestimmten Startkonfiguration zu drucken. Dies ist Code Golf, also gewinnen die wenigsten Bytes.

Eingang

Eine Liste positiver Zahlen in absteigender Reihenfolge, die die anfänglichen Stapelgrößen darstellt. Eingabe über STDIN oder Funktionseingabe. Sie können jede gewünschte listenartige Struktur verwenden.

Sie erhalten nicht die Gesamtzahl der Karten Nals Eingabe.

Ausgabe

Drucken Sie die Reihenfolge der Stapelgrößen aus, die das Spiel des bulgarischen Solitaire durchläuft. Beachten Sie, dass ein Druck erforderlich ist und nicht zurückgegeben wird. Jeder Schritt sollte eine eigene Zeile sein.

Jede Zeile sollte eine Folge positiver Zahlen in absteigender Reihenfolge ohne Nein enthalten 0. Möglicherweise haben Sie Trennzeichen und Start- und End-Token (z. B. [3, 3, 1, 1]). Die Zahlen können mehrere Ziffern haben, daher sollten sie irgendwie getrennt werden.

Drucken Sie die angezeigten Stapelaufteilungen bis einschließlich einer Wiederholung. Die erste Zeile sollte also die Eingabe sein, und die letzte Zeile sollte eine Wiederholung einer vorherigen Zeile sein. Es sollte keine anderen Wiederholungen geben.

Testfälle

>> [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
quelle

Antworten:

4

Pyth, 40 25

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

Dies kommt einer Übersetzung meiner Python 2-Antwort ziemlich nahe.

Probelauf:

Eingang:

[4,4,3,2,1]

Ausgabe:

[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]

Wie es funktioniert:

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
quelle
1. Sie können ersetzen v$input()$mit Q. 2. Wenn Sie die Liste in absteigender Reihenfolge speichern, brauchen Sie überhaupt nicht N:W!}QYQ~Y]Q=Q_S+fTmtdQ]lQ;Q
Dennis
@ Tennis Danke, ich konnte nicht herausfinden, wie das geht; Ich wusste, dass es einen Weg gab, dies zu tun.
Justin
1
Folgendes habe ich völlig unabhängig gemacht : QW!}QY~Y]Q=Q_S+]lQfTmtdQQ. Es ist genau das gleiche, Charakter für Charakter, bis hin zur Kommutativität.
isaacg
3

CJam, 26 Bytes

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

Probieren Sie es online aus.

Beispiellauf

$ cjam <(echo 'q{~_:(_,+0-$W%]___&=}g{p}/') <<< '[5 3]'
[5 3]
[4 2 2]
[3 3 1 1]
[4 2 2]
Dennis
quelle
Das ist ein CJam!
Optimierer
Komm schon! Ich weiß, du kannst es kürzer machen als Pyth!
Optimierer
Wenn es :pfunktioniert, könnte ich ...
Dennis
4
Hör auf zu jammern! :p
Optimierer
3

Ruby, 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}}

Erläuterung

  • Die Eingabe wird als Argument für ein Lambda verwendet. Es erwartet eine Array.
  • Vorherige Spielzustände werden im gespeichert Hash g.
  • Um einen neuen Spielstatus zu erstellen Array#map, verringern Sie jedes Element um 1, addieren Sie die Länge des ArrayElements als Element, sortieren Sie es in absteigender Reihenfolge und löschen Sie das Element 0.
  • Um zu überprüfen, ob zuvor ein Spielstatus angezeigt wurde, reicht es aus, zu überprüfen, ob gein Schlüssel für den neuen Spielstatus vorhanden ist.
britishtea
quelle
+1 Wirklich ordentliches Ruby-Golfen hier! sort_bysort.reverse
Obwohl
Oh, das ist schade. Vielen Dank.
Britishtea
2

CJam, 35 34 33 Bytes

(Verdammt, dieser Stromausfall, den ich nicht als erster in CJam gepostet habe)

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

Eingang:

[1 1 1 1 1 1 1]

Ausgabe:

[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]

Probieren Sie es hier online aus

Optimierer
quelle
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

Ähnlich wie die Antwort von Quincunx, ersetzt jedoch Anhänge durch Hinzufügen und entfernt die letzten beiden Zeilen.

Beispielausgabe:

[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
quelle
Ähm, ähnlich? Das ist identisch; Sie haben einfach die Golfschritte gemacht, die völlig offensichtlich waren. Als ich zu meinem zurückkam, spielte ich Golf und stellte fest, dass dies jetzt eine doppelte Antwort von mir ist (oder umgekehrt, wie auch immer Sie es sehen möchten)
Justin
Ich habe Ihre Antwort erst entdeckt, nachdem ich meine gepostet habe. Ich bin damit einverstanden, sie als Duplikate voneinander zu betrachten.
Nathan Merrill
1

GolfScript, 50 46

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

Kann mit ziemlicher Sicherheit weiter Golf gespielt werden. Probieren Sie es hier aus.

Justin
quelle
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]
stolzer haskeller
quelle
1

CJam, 40 36 34 Bytes

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

Testen Sie es hier. Geben Sie die Eingabe als Array im CJam-Stil [5 3]in das Feld STDIN ein. Das Ausgabeformat ist ähnlich, daher eckige Klammern und Leerzeichen als Trennzeichen.

Selbst wenn ich dies weiter unten Golf spiele (was definitiv möglich ist), gibt es keine Möglichkeit, Pyth damit zu schlagen. Vielleicht ist es Zeit, J. zu lernen. Erklärung kommt später.

Martin Ender
quelle
Ich bin mir nicht sicher, ob J helfen wird. Ich kann meine APL nicht unter 38
TwiNight,
1

JavaScript (E6) 113

Schlechtester Eintrag bisher :(

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 in der FireFox / FireBug-Konsole

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

Ausgabe

[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
quelle
1

Python 2, 148 130 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

Dies merkt sich einfach alle vorherigen Iterationen und prüft, ob die neue in dieser Liste enthalten ist. Dann druckt es es aus.

Probelauf:

Eingang:

[4,4,3,2,1]

Ausgabe:

[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]

Bearbeiten: Ich habe die Spezifikationen zum Golf noch einmal gelesen und viel Golf gespielt.

Justin
quelle
Sie dürfen die Listen nur als Listen drucken.
xnor
@xnor Ooh danke, habe das komplett verpasst.
Justin
Dies wird nicht funktionieren mit [5,3]
Nathan Merrill
Dies ergibt die falsche Ausgabe für [4,2,2]. Es gibt jedoch eine einfache Lösung.
xnor
0

Python 3: 89 Zeichen

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

Ähnlich wie die bereits veröffentlichten Python-Lösungen, jedoch mit rekursiven Funktionsaufrufen anstelle von Schleifen. In der Liste swerden die bereits gesehenen Teilungen gespeichert und die Rekursion im Falle einer Wiederholung kurzgeschlossen.

Die Funktion print()(dies ist Python 3) muss nur irgendwie in jeder Schleife aufgerufen werden. Das Knifflige ist, dass a lambdanur einen einzigen Ausdruck zulässt, also können wir das nicht print(l);.... Außerdem gibt es Ausgaben aus None, mit denen schwer zu arbeiten ist. print(l)Am Ende stelle ich eine Ungleichheit auf die Seite; ==funktioniert aus irgendeinem Grund nicht, den ich nicht verstehe.

Ein alternativer Ansatz zum Einfügen in eine Liste verwendet gleich viele Zeichen.

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

Die Verwendung print(*l)würde die Ausgaben 4 2 2eher wie als formatieren [4,2,2].

xnor
quelle