Bułgarski pasjans

9

Bulgarian Solitaire to gra dla jednego gracza, popularna przez Martina Gardnera w jego kolumnie matematycznej w Scientific American .

Masz Nidentyczne karty, podzielone na stosy. Z każdego stosu bierzesz kartę i tworzysz nowy stos z usuniętymi kartami. Powtarzasz ten proces, dopóki nie osiągniesz stanu, który już widziałeś, więc kontynuowanie powtórzy pętlę.

Załóżmy na przykład, że masz 8karty podzielone na stos 5i stos 3. Piszemy rozmiary stos w kolejności malejącej: 5 3. Oto zapis gry:

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

Najpierw usuwasz kartę z każdego z dwóch stosów, pozostawiając stosy 4i 2oraz nowo utworzony stos 2rozdawania 4 2 2. W następnym kroku te zmniejszają się, 3 1 1a wraz z nimi nowy stos 3. Wreszcie ostatni krok opróżnia stosy wielkości 1i produktów, 4 2 2które już się pojawiły, więc przestajemy.

Pamiętaj, że suma rozmiarów stosów pozostaje taka sama.

Twoim celem jest wydrukowanie takiego zapisu gry z danej konfiguracji początkowej. To jest kod golfowy, więc wygrywa najmniej bajtów.

Wejście

Lista liczb dodatnich w porządku malejącym reprezentujących początkowe rozmiary stosów. Wprowadź dane przez STDIN lub funkcję. Możesz użyć dowolnej struktury podobnej do listy.

Nie dostajesz całkowitej liczby kart Njako danych wejściowych.

Wynik

Wydrukuj sekwencję rozmiarów stosów, przez którą przechodzi gra Bułgarski pasjans. Pamiętaj, że drukowanie jest wymagane, a nie zwracane. Każdy krok powinien być własną linią.

Każda linia powinna mieć ciąg liczb dodatnich w porządku malejącym bez żadnych 0. Możesz mieć separatory oraz tokeny początkowe i końcowe (na przykład [3, 3, 1, 1]). Liczby mogą zawierać wiele cyfr, dlatego należy je jakoś rozdzielić.

Wydrukuj podziały wielkości stosu, które widzisz, aż do powtórzenia. Tak więc pierwszy wiersz powinien być wejściem, a ostatni wiersz powinien być powtórzeniem poprzedniego wiersza. Nie powinno być żadnych innych powtórzeń.

Przypadki testowe

>> [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
źródło

Odpowiedzi:

4

Pyth, 40 25

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

Jest to bardzo zbliżone do tłumaczenia mojej odpowiedzi na python 2.

Przykładowy przebieg:

Wejście:

[4,4,3,2,1]

Wynik:

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

Jak to działa:

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
źródło
1. Można wymienić v$input()$z Q. 2. Jeśli przechowujesz listę w malejącej kolejności, wcale nie potrzebujesz N:W!}QYQ~Y]Q=Q_S+fTmtdQ]lQ;Q
Dennis,
@Dennis Dzięki, nie mogłem wymyślić, jak to zrobić; Wiedziałem, że jest na to sposób.
Justin
1
Oto co zrobiłem, zupełnie niezależnie: QW!}QY~Y]Q=Q_S+]lQfTmtdQQ. Jest dokładnie taki sam, charakter dla postaci, aż do przemienności.
isaacg
3

CJam, 26 bajtów

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

Wypróbuj online.

Przykładowy przebieg

$ cjam <(echo 'q{~_:(_,+0-$W%]___&=}g{p}/') <<< '[5 3]'
[5 3]
[4 2 2]
[3 3 1 1]
[4 2 2]
Dennis
źródło
To trochę CJam!
Optymalizator
Chodź! Wiem, że możesz zrobić to krócej niż Pyth!
Optymalizator
Gdybym :ppracował, mógłbym ...
Dennis
4
Przestań jęczeć! :p
Optymalizator
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}}

Wyjaśnienie

  • Dane wejściowe są traktowane jako argumenty do lambda. Oczekuje Array.
  • Poprzednie stany gry są przechowywane w Hash g.
  • Aby utworzyć nowy stan gry, użyj, Array#mapaby zmniejszyć każdy element o 1, dodaj długość elementu Arrayjako element, posortuj go w malejącej kolejności i usuń element 0.
  • Aby sprawdzić, czy stan gry był wcześniej widziany, wystarczy sprawdzić, czy gma klucz do nowego stanu gry.
Britishtea
źródło
+1 Naprawdę fajnie Ruby gra w golfa tutaj! Jednak, choć sort_byrzecz jest z pewnością sprytna, w sort.reverserzeczywistości jest o jedną postać krótsza ^^
daniero
Aww, to źle. Dzięki.
britishtea,
2

CJam, 35 34 33 bajtów

(Cholera, ta przerwa w zasilaniu, której nie byłem pierwszą osobą, która opublikowała w CJam)

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

Wejście:

[1 1 1 1 1 1 1]

Wynik:

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

Wypróbuj online tutaj

Optymalizator
źródło
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

Podobna do odpowiedzi Quincunx, ale zastępuje dołączanie dodatkiem i usuwa ostatnie dwa wiersze.

Przykładowe dane wyjściowe:

[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
źródło
Umm, podobny? To jest identyczne; po prostu zrobiłeś kroki w golfa, które były całkowicie oczywiste. Kiedy wróciłem do mojego, grałem w golfa i odkryłem, że jest to teraz moja duplikat (lub odwrotnie, jakkolwiek chcesz to zobaczyć)
Justin,
Twoja odpowiedź znalazłem dopiero po opublikowaniu mojej. Nie mam nic przeciwko traktowaniu ich jako duplikatów.
Nathan Merrill,
1

GolfScript, 50 46

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

Prawie na pewno można dalej grać w golfa. Wypróbuj tutaj.

Justin
źródło
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]
dumny haskeller
źródło
1

CJam, 40 36 34 bajtów

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

Sprawdź to tutaj. Wprowadź dane wejściowe jako tablicę w stylu CJam, na przykład [5 3], w polu STDIN. Format wyjściowy jest podobny, więc nawiasy kwadratowe i spacje są ogranicznikami.

Nawet jeśli będę grać w golfa dalej (co jest zdecydowanie możliwe), nie ma sposobu na pokonanie Pytha. Może czas nauczyć się J. Wyjaśnienia, które pojawią się później.

Martin Ender
źródło
Nie jestem pewien, czy J pomoże, nie mogę uzyskać APL poniżej 38
TwiNight
1

JavaScript (E6) 113

Najgorszy jak dotąd wpis :(

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

Przetestuj w konsoli FireFox / FireBug

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

Wynik

[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
źródło
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

To po prostu zapamiętuje wszystkie poprzednie iteracje i sprawdza, czy nowa jest na tej liście. Następnie drukuje to.

Przykładowy przebieg:

Wejście:

[4,4,3,2,1]

Wynik:

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

Edycja: Ponownie przeczytałem specyfikację gry w golfa, a także dużo gry w golfa.

Justin
źródło
Możesz tylko wydrukować listy jako listy.
xnor
@xnor Ooh dzięki, całkowicie tego przegapiłem.
Justin,
To nie zadziała z [5,3]
Nathan Merrill
To daje niewłaściwe wyjście dla [4,2,2]. Jest jednak łatwa poprawka.
xnor
0

Python 3: 89 znaków

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

Podobnie jak w przypadku już opublikowanych rozwiązań w języku Python, ale z rekurencyjnymi wywołaniami funkcji zamiast pętli. Lista sprzechowuje już widoczne podziały i zwiera rekurencję w przypadku powtórzenia.

Funkcja print()(to jest Python 3) musi być jakoś wywołana w każdej pętli. Trudne jest to, że lambdapozwala tylko na jedno wyrażenie, więc nie możemy tego zrobić print(l);.... Ponadto generuje dane wyjściowe None, z którymi trudno jest pracować. Kończę stawianie print(l)jednej strony nierówności; ==nie działa z jakiegoś powodu, którego nie rozumiem.

Alternatywne podejście do umieszczania go na liście używa równie wielu znaków.

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

Użycie print(*l)spowoduje sformatowanie danych wyjściowych jak 4 2 2zamiast [4,2,2].

xnor
źródło