Solitaire Solitaire


9

Bulgari Solitaire là một trò chơi một người chơi được phổ biến bởi Martin Gardner trong chuyên mục toán học của mình trong Khoa học Mỹ .

Bạn có Nthẻ giống hệt nhau, chia thành đống. Bạn lấy một thẻ từ mỗi cọc và tạo thành một đống mới với các thẻ bị loại bỏ. Bạn lặp lại quá trình này cho đến khi bạn đạt đến trạng thái bạn đã thấy và do đó tiếp tục sẽ lặp lại vòng lặp.

Ví dụ: giả sử bạn có 8thẻ, chia thành một đống 5và một đống 3. Chúng tôi viết các kích thước cọc theo thứ tự giảm dần : 5 3. Đây là bảng điểm của trò chơi:

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

Trước tiên, bạn loại bỏ một thẻ từ mỗi trong hai cọc, để lại các đống 42, và một đống mới được tạo ra 2, cho 4 2 2. Trong bước tiếp theo, những giảm này 3 1 1theo sau với một đống mới 3. Cuối cùng, bước cuối cùng làm trống các đống kích thước 1và sản xuất 4 2 2đã xuất hiện, vì vậy chúng tôi dừng lại.

Lưu ý rằng tổng kích thước cọc giữ nguyên.

Mục tiêu của bạn là in một bản sao của trò chơi như vậy từ một cấu hình bắt đầu nhất định. Đây là mã golf, vì vậy ít byte nhất sẽ thắng.

Đầu vào

Một danh sách các số dương theo thứ tự giảm dần biểu thị kích thước cọc ban đầu. Lấy đầu vào thông qua STDIN hoặc đầu vào chức năng. Bạn có thể sử dụng bất kỳ cấu trúc giống như danh sách bạn muốn.

Bạn không nhận được tổng số thẻ Nlàm đầu vào.

Đầu ra

In chuỗi kích thước cọc mà trò chơi Bulgari Solitaire trải qua. Lưu ý rằng in ấn là bắt buộc, không trả lại. Mỗi bước nên là dòng riêng của nó.

Mỗi dòng nên có một chuỗi các số dương theo thứ tự giảm dần mà không có 0. Bạn có thể có dấu phân cách và mã thông báo bắt đầu và kết thúc (ví dụ [3, 3, 1, 1]:). Các số có thể có nhiều chữ số, vì vậy chúng nên được tách ra bằng cách nào đó.

In các phần tách kích thước cọc mà bạn thấy cho đến khi và bao gồm cả việc lặp lại. Vì vậy, dòng đầu tiên phải là đầu vào và dòng cuối cùng phải là lặp lại của dòng trước đó. Không nên có bất kỳ sự lặp lại nào khác.

Các trường hợp thử nghiệm

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

Câu trả lời:


4

Bình thường, 40 25

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

Điều này khá gần với bản dịch câu trả lời python 2 của tôi.

Chạy mẫu:

Đầu vào:

[4,4,3,2,1]

Đầu ra:

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

Làm thế nào nó hoạt động:

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. Bạn có thể thay thế v$input()$bằng Q. 2. Nếu bạn lưu trữ danh sách theo thứ tự giảm dần, bạn hoàn toàn không cần N:W!}QYQ~Y]Q=Q_S+fTmtdQ]lQ;Q
Dennis

@Dennis Cảm ơn, tôi không thể tìm ra cách để làm điều đó; Tôi biết có một cách để làm như vậy.
Justin

1
Đây là những gì tôi đã làm, hoàn toàn độc lập : QW!}QY~Y]Q=Q_S+]lQfTmtdQQ. Nó giống hệt nhau, tính cách cho nhân vật, cho đến giao hoán.
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}}

Giải trình

  • Đầu vào được lấy làm đối số cho lambda. Nó mong đợi một Array.
  • Các trạng thái trò chơi trước được lưu trữ trong Hash g.
  • Để tạo trạng thái trò chơi mới, sử dụng Array#mapđể giảm mọi phần tử xuống 1, thêm độ dài của Arrayphần tử dưới dạng, sắp xếp theo thứ tự giảm dần và xóa phần tử 0.
  • Để kiểm tra xem trạng thái trò chơi đã được nhìn thấy trước đó chưa, kiểm tra xem gcó khóa cho trạng thái trò chơi mới không là đủ.

+1 Chơi golf Ruby thật gọn gàng ở đây! Tuy nhiên, trong khi sort_byđiều chắc chắn là thông minh, sort.reversethực ra lại ngắn hơn một ký tự ^^
daniero

À, điều đó thật tệ. Cảm ơn.
britishtea

2

CJam, 35 34 33 byte

(Chết tiệt, sự cắt giảm sức mạnh này mà tôi không phải là người đầu tiên đăng ở CJam)

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

Đầu vào:

[1 1 1 1 1 1 1]

Đầu ra:

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

Dùng thử trực tuyến tại đây


1

Con trăn 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

Tương tự như câu trả lời của Quincunx, nhưng thay thế bổ sung bằng phép cộng và xóa hai dòng cuối cùng.

Đầu ra mẫu:

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

Ừm, tương tự? Điều này là giống hệt nhau; bạn chỉ cần thực hiện các bước chơi golf là hoàn toàn rõ ràng. Khi tôi quay lại với tôi, tôi đã đánh gôn và phát hiện ra rằng đây là câu trả lời trùng lặp của tôi (hoặc ngược lại, tuy nhiên bạn muốn xem nó)
Justin

Tôi phát hiện ra câu trả lời của bạn chỉ sau khi đăng của tôi. Tôi ổn với việc xem xét chúng trùng lặp với nhau.
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 byte

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

Kiểm tra nó ở đây. Nhập đầu vào dưới dạng mảng kiểu CJam, như [5 3], vào trường STDIN. Định dạng đầu ra là tương tự nhau, vì vậy dấu ngoặc vuông và dấu cách là dấu phân cách.

Ngay cả khi tôi đánh gôn này xuống xa hơn (điều chắc chắn là có thể), không có cách nào để đánh bại Pyth với điều này. Có lẽ đã đến lúc tìm hiểu J. Giải thích đến sau.


Không chắc J sẽ giúp, tôi không thể lấy APL của mình dưới 38
TwiNight

1

JavaScript (E6) 113

Mục xấu nhất cho đến nay :(

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

Thử nghiệm trong bảng điều khiển FireFox / FireBug

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

Đầu ra

[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

Con trăn 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

Điều này chỉ đơn giản là ghi nhớ tất cả các lần lặp lại trước đó và kiểm tra xem cái mới có trong danh sách đó không. Sau đó, nó in nó ra.

Chạy mẫu:

Đầu vào:

[4,4,3,2,1]

Đầu ra:

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

Chỉnh sửa: Tôi đọc lại thông số kỹ thuật cho golf, cộng với việc áp dụng rất nhiều môn đánh gôn.


Bạn được phép chỉ in danh sách dưới dạng danh sách.
xnor

@xnor Ooh cảm ơn, hoàn toàn bỏ lỡ điều đó.
Justin

Điều này sẽ không hoạt động với [5,3]
Nathan Merrill

Điều này cho đầu ra sai cho [4,2,2]. Có một sửa chữa dễ dàng mặc dù.
xnor

0

Python 3: 89 ký tự

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

Giống như các giải pháp Python đã được đăng, nhưng với các lệnh gọi hàm đệ quy hơn là các vòng lặp. Danh sách slưu trữ các phần tách đã thấy và ngắn mạch ra đệ quy trong trường hợp lặp lại.

Hàm print()(đây là Python 3) chỉ cần được gọi bằng cách nào đó trong mỗi vòng lặp. Điều khó khăn là lambdachỉ cho phép một biểu thức duy nhất, vì vậy chúng tôi không thể làm print(l);.... Ngoài ra, nó đầu ra None, rất khó để làm việc với. Tôi cuộn lên đặt print(l)một bên của sự bất bình đẳng; ==Tôi không hiểu vì lý do nào đó.

Một cách tiếp cận khác của việc dán nó trong danh sách sử dụng nhiều ký tự như nhau.

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

Sử dụng print(*l)sẽ định dạng các đầu ra như thế 4 2 2chứ không phải [4,2,2].

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.