Bảng Mancala Solitaire có thể giành chiến thắng


10

Mancala là tên của một gia đình trò chơi cờ thường liên quan đến một loạt các cốc chứa đầy hạt mà người chơi thao tác. Thử thách này sẽ sử dụng một bộ quy tắc cụ thể cho một biến thể solitaire của trò chơi.

Bảng bao gồm một "giỏ" ở một đầu, theo sau là vô số cốc, được đánh số bắt đầu từ 1. Một số cốc sẽ có một số hạt trong đó. Nếu ncốc thứ có chính xác nhạt trong đó, bạn có thể "gieo" hạt từ nó. Gieo có nghĩa là lấy tất cả các nhạt ra khỏi cốc, sau đó gửi từng hạt một vào từng cốc về phía giỏ. Hạt cuối cùng sẽ đi vào giỏ. Người chơi chiến thắng khi tất cả các hạt trên bảng nằm trong rổ.

Rõ ràng, có nhiều bảng không thể thắng được, chẳng hạn như nếu có chính xác một hạt trong cốc thứ hai. Không có trò chơi hợp pháp vì tất cả các cốc có 0 hạt không thể được gieo và cốc thứ hai không có đủ hạt để được gieo. Điều này rõ ràng là không vui, vì vậy nhiệm vụ của bạn sẽ là tạo ra các bảng có thể thắng được.

Bài tập

Cho một số nguyên dương biểu thị một số hạt xuất ra một danh sách các số nguyên không âm biểu thị số lượng hạt cần được đặt trong mỗi cốc để tạo một bảng có thể thắng được như mô tả ở trên. Danh sách này không được chứa bất kỳ số 0 nào.

Đối với bất kỳ số lượng hạt nhất định, luôn có chính xác một cấu hình bảng có thể thắng.

Trình diễn

Đây là một minh họa về cách chơi bảng có thể thắng và đầu vào của 4. Bảng có thể thắng được [0, 1, 3]. Chúng tôi bắt đầu với động thái duy nhất có sẵn, gieo hạt từ cốc thứ ba để có được [1, 2, 0]. Bây giờ chúng tôi thực sự có một sự lựa chọn, nhưng điều duy nhất đúng là gieo cốc đầu tiên, nhận được : [0, 2, 0]. Sau đó, chúng tôi gieo cốc thứ hai cho năng suất [1, 0, 0]và cuối cùng chúng tôi lại gieo cốc thứ nhất một lần nữa để có được tất cả các cốc rỗng.

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

1 => [1]
2 => [0, 2]
3 => [1, 2]
4 => [0, 1, 3]
5 => [1, 1, 3]
6 => [0, 0, 2, 4]
7 => [1, 0, 2, 4]
8 => [0, 2, 2, 4]
9 => [1, 2, 2, 4]
10 => [0, 1, 1, 3, 5]
11 => [1, 1, 1, 3, 5]
12 => [0, 0, 0, 2, 4, 6]
13 => [1, 0, 0, 2, 4, 6]
14 => [0, 2, 0, 2, 4, 6]
15 => [1, 2, 0, 2, 4, 6]
16 => [0, 1, 3, 2, 4, 6]
17 => [1, 1, 3, 2, 4, 6]
18 => [0, 0, 2, 1, 3, 5, 7]
19 => [1, 0, 2, 1, 3, 5, 7]
20 => [0, 2, 2, 1, 3, 5, 7]

Xin chân thành cảm ơn PeterTaylor đã đưa ra một chương trình để tạo ra các trường hợp thử nghiệm!


Câu trả lời:


5

CJam (21 byte)

M{_0+0#_Wa*\)+.+}ri*`

Bản demo trực tuyến

Giải trình

Tôi độc lập rút ra kỹ thuật "không chơi" được đề cập trong bài báo này . Chúng tôi chứng minh bằng cảm ứng rằng có chính xác một bảng chiến thắng cho một số hạt nhất định.

Trường hợp cơ bản: với 0 hạt, bảng chiến thắng duy nhất là bảng trống.

Bước quy nạp: nếu chúng ta gieo từ cốc kthì ở cốc di chuyển tiếp theo ksẽ trống và mỗi cốc gần giỏ sẽ chứa ít nhất một hạt. Do đó, chúng ta có thể tìm thấy bảng chiến thắng độc đáo với nchuỗi hạt từ bảng chiến thắng bằng n-1chuỗi hạt bằng cách tìm kiếm chiếc cốc rỗng được đánh số thấp nhất, lấy một hạt từ giỏ và một chiếc từ mỗi chiếc cốc bên dưới chiếc cốc rỗng đó và đặt tất cả chúng vào chiếc cốc rỗng.

Mổ xẻ

M           e# Start with an empty board
{           e# Loop
  _0+0#     e#   Find position of first 0 (appending to ensure that there is one)
  _Wa*      e#   Make array of that many [-1]s
  \)+       e#   Append the index plus 1 (since board is 1-indexed)
  .+        e#   Pointwise addition
}
ri*         e# Read integer from stdin and execute loop that many times
`           e# Format for display

9

Python, 42 41 byte

m=lambda n,i=2:n*[1]and[n%i]+m(n-n%i,i+1)

4

JavaScript (ES6), 63 37 byte

f=(n,d=2)=>n?[n%d,...f(n-n%d,d+1)]:[]

Cổng câu trả lời Python của @ orlp. Giải thích: Xem xét tổng số hạt trong icốc thứ và cao hơn. Mỗi lần chơi từ một trong những chiếc cốc này sẽ loại bỏ các ihạt khỏi tổng số đó. (Ví dụ: nếu ilà 3 và bạn chơi từ cốc thứ năm, bạn giảm số hạt trong cốc đó xuống năm, nhưng bạn cũng thêm một hạt vào cả cốc thứ tư và cốc thứ ba.) Do đó, tổng số phải là bội số của i. Bây giờ i-1cốc thứ không thể chứa ihoặc nhiều hạt hơn, vì vậy để nó rời khỏi bội số của inó phải chứa phần còn lại của hạt modulo i.

Giải thích trước đây (từ liên kết của @ xnor): Cách tiếp cận ngây thơ là kỹ thuật "chơi ngược". Điều này sử dụng sự quan sát làm cho một vở kịch làm trống một cái cốc, do đó, chơi ngược lại thu thập một hạt từ mỗi cốc và đặt chúng vào cốc trống đầu tiên, như vậy (63 byte):

f=n=>n?[...a=f(n-1),0].some((m,i)=>(m?a[i]--:a[i]=i+1)>m)&&a:[]

Bây giờ, chỉ cần xem xét các icốc đầu tiên . Trong trường hợp một trong số chúng trống, chơi ngược sẽ thêm 1vào tổng số hạt trong các cốc đó, trong khi trong trường hợp không có hạt nào trống, thì chơi ngược sẽ trừ itổng số, tuy nhiên điều này tương đương với việc thêm 1modulo i+1. Sau khi phát nngược lại, tổng số hạt trong icốc đầu tiên sẽ tương đương với nmodulo i+1, hoặc đặt nó theo cách khác, số hạt trong icốc thứ hai sẽ tương đương với ntổng số hạt trong cốc trước, modulo i+1. Bây giờ để icốc thứ có thể chơi được, số lượng hạt không thể vượt quá i, vì vậy trên thực tế, nó sẽ bằng số lượng hạt modulo còn lạii+1. (Lưu ý rằng tôi sử dụng d=i+1vì nó sử dụng ít byte hơn.)


Bạn đã quên gán chức năng trong phiên bản bằng giải pháp của @ orlp, ngăn việc đệ quy hoạt động. Cũng liên quan đến giải pháp đó, liệu nối mảng +không phải là một điều trong ES6?
Mực giá trị

@KevinLau Rất tiếc, và sau khi gặp rắc rối về việc đưa nó vào số byte quá! Nhưng không, + là nối chuỗi, trừ khi cả hai tham số là số hoặc booleans, trong trường hợp đó là phép cộng. May mắn là sự hiểu biết mảng làm cho việc ghép tùy ý dễ dàng hơn.
Neil

2

Ruby, 36 byte

Một câu trả lời của @ orlp bởi vì nó quá thiên tài đối với tôi để nghĩ về bất cứ điều gì tốt hơn.

m=->n,i=2{n>0?[n%i]+m[n-n%i,i+1]:[]}
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.