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

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

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

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.

+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


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]

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

Haskell, 99

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

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.


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]

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.


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.