Kazanılabilir Solitaire Mancala Masaları


10

Mancala , genellikle oyuncuların manipüle ettiği boncuklarla dolu bir dizi bardak içeren bir masa oyunları ailesinin adıdır. Bu meydan okuma, oyunun bir solitaire varyantı için belirlenmiş belirli bir kural kullanacaktır.

Tahta bir ucunda bir "sepet" ve ardından 1'den başlayarak numaralandırılmış sonsuz sayıda bardaktan oluşur. Bazı fincanların içinde bir miktar boncuk bulunur. Eğer ninci bardağın içinde tam olarak nboncuklar varsa, ondan "boncuk" ekebilirsiniz. Ekim, tüm nboncukları fincandan çıkarmak, daha sonra her fincanda birer birer sepete doğru biriktirmek anlamına gelir . Son boncuk sepete girecek. Karttaki tüm boncuklar sepette olduğunda oyuncu kazanır.

Açıkçası, kazanamayan birçok tahta var, örneğin ikinci fincanda tam olarak bir boncuk varsa. Hiçbir yasal oyun yoktur, çünkü 0 boncuklu tüm fincanlara ekilemez ve ikinci fincanda ekilecek yeterli boncuk yoktur. Bu kesinlikle eğlenceli değil, bu yüzden göreviniz kazanılabilir panoları oluşturmak olacak.

Görev

Birkaç taneyi temsil eden pozitif bir tamsayı verildiğinde, yukarıda tarif edildiği gibi kazanılabilir bir tahta yapmak için her bir kaba konulması gereken tanelerin sayısını temsil eden negatif olmayan tamsayıların bir listesi çıkarılır. Bu liste herhangi bir sıfır içermemelidir.

Herhangi bir sayıda boncuk için, her zaman tam olarak bir kazanılabilir tahta konfigürasyonu vardır.

gösteri

Bu kazanılabilir tahtanın nasıl oynanacağının ve 4 girişinin bir göstergesidir. Kazanılabilir tahta [0, 1, 3]. Eldeki tek hamle ile başlıyoruz, elde etmek için üçüncü fincandan boncuklar ekiyoruz [1, 2, 0]. Şimdi biz aslında bir seçim var, ama sadece doğru bir alma, ilk fincan ekim edilir: [0, 2, 0]. Sonra ikinci bardağı ekiyoruz [1, 0, 0]ve nihayet tüm boş bardakları almak için ilk bardağı ekiyoruz.

Test senaryoları:

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]

Test örnekleri oluşturmak için bir program hazırladığı için PeterTaylor'a çok teşekkürler !


Yanıtlar:


5

CJam (21 bayt)

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

Çevrimiçi demo

açıklama

Ben bağımsız olarak bu yazıda bahsedilen "oyun" tekniğini türettim . İndüksiyonla, belirli sayıda boncuk için tam olarak bir kazanan tahta olduğunu kanıtlıyoruz.

Temel durum: 0 boncuk ile, tek kazanan tahta boş olanıdır.

Endüktif adım: fincandan ekersek k, bir sonraki harekette fincan kboş olacak ve sepete yakın olan her fincan en az bir boncuk içerecektir. Bu nedenle , en düşük numaralı boş bardağı arayarak, sepetten bir boncuk ve o boş bardağın altındaki her fincandan bir tane alarak ve hepsini boş bardağa yerleştirerek nboncuklu kazanan tahtadan boncuklarla benzersiz kazanan tahta bulabiliriz n-1.

teşrih

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 bayt

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

4

JavaScript (ES6), 63 37 bayt

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

Bağlantı noktası @ orlp'nin Python cevabı. Açıklama: iinci ve daha yüksek fincanlarda toplam boncuk sayısını düşünün . Bu fincanlardan birindeki her oyun i, toplamdan boncukları çıkaracaktır . (Örneğin i, 3 ise ve beşinci fincandan oynarsanız, o fincandaki boncuk sayısını beş oranında azaltırsınız, ancak dördüncü ve üçüncü fincanlara da bir tane eklersiniz.) Toplam, bu nedenle / i. Şimdi, bu i-1fincan idaha fazla boncuk içeremez , bu yüzden ikatının çoğunu bırakabilmesi için boncuk modülünün geri kalanını içermesi gerekir i.

Önceki açıklama (@ xnor'ın bağlantısından): Saf yaklaşım "ters oynama" tekniğidir. Bu, bir oyunun bir bardağı boşalttığı gözlemini kullanır, bu nedenle tersine oynatma her fincandan bir boncuk toplar ve bunları ilk boş bardağa koyar (63 bayt):

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

Şimdi, ilk ibardakları düşünün . Bunlardan birinin boş olması durumunda, ters oynama 1bu bardaklardaki toplam boncuk sayısına eklenirken, hiçbirinin boş olmaması durumunda, ters oynama itoplamdan çıkarılır , ancak bu 1modulo eklemeye eşdeğerdir i+1. nTers oynadıktan sonra , ilk ifincanlardaki boncukların toplamı nmoduloya eşdeğer olacak i+1veya başka bir yolla konacak, bu ibardaktaki boncukların sayısı n, önceki fincanlardaki boncukların toplamı olan moduloya eşdeğer olacaktır i+1. Şimdi bu ibardağın oynanabilmesi için boncukların sayısı geçemez i, bu yüzden aslında kalan boncukların modülo sayısına eşit olacaktır.i+1. ( d=i+1Daha az bayt kullandığından kullandığımı unutmayın .)


@ Orlp'nin çözümünü kullanarak sürümde işlevi atamayı ve özyinelemenin çalışmasını önlemeyi unuttunuz. Ayrıca bu çözümle ilgili olarak, dizi birleştirme +ES6'da bir şey değil mi?
Değer Mürekkebi

@KevinLau Hata! Bayt sayımına dahil etme zahmetine girdikten sonra! Ancak hayır, + her iki parametre de sayı veya boolean olmadığı sürece dize birleşimidir, bu durumda toplamadır. Neyse ki dizi anlayışları keyfi birleştirme işlemini kolaylaştırır.
Neil

2

Ruby, 36 bayt

@ Orlp'nin cevabı bir bağlantı noktası çünkü daha iyi bir şey düşünmek benim için çok dahice.

m=->n,i=2{n>0?[n%i]+m[n-n%i,i+1]:[]}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.