우승 가능한 솔리테어 만 칼라 보드


10

Mancala 는 일반적으로 플레이어가 조작하는 구슬로 채워진 일련의 컵을 포함하는 보드 게임 제품군의 이름입니다. 이 도전은 게임의 솔리테어 변형에 대한 특정 규칙 세트를 사용합니다.

보드는 한쪽 끝에 "바구니"로 구성되고 그 뒤에 1부터 시작하여 번호가 매겨진 컵 수가 무한정으로 구성됩니다. 일부 컵에는 구슬이 몇 개 있습니다. nth 컵에 n구슬 이 정확히 있으면 구슬을 "뿌릴"수 있습니다. 파종은 n컵에서 모든 비드를 꺼낸 다음 각 컵에 한 번에 하나씩 비드 를 담그는 것을 의미합니다 . 마지막 구슬이 바구니에 들어갑니다. 보드의 모든 구슬이 바구니에 있으면 플레이어가 승리합니다.

분명히, 두 번째 컵에 정확히 하나의 비드가있는 경우와 같이 획득 할 수없는 많은 보드가 있습니다. 구슬이 0 인 컵을 모두 뿌릴 수없고, 두 번째 컵에 뿌릴 구슬이 충분하지 않기 때문에 합법적 인 플레이가 없습니다. 이것은 분명히 재미가 없기 때문에 당신의 임무는 승리 가능한 보드를 만드는 것입니다.

직무

다수의 비드 출력을 나타내는 양의 정수가 주어지면, 전술 한 바와 같이 입수 가능한 보드를 만들기 위해 각 컵에 넣어야하는 비드의 수를 나타내는 음이 아닌 정수의리스트가 제공된다. 이 목록에는 후행 0이 포함되지 않아야합니다.

주어진 수의 구슬에 대해 항상 정확히 하나의 당길 수있는 보드 구성이 있습니다.

데모

Winnable 보드를 4 번 입력하는 방법을 보여줍니다 [0, 1, 3]. Winnable 보드는 입니다. 우리는 유일하게 사용 가능한 움직임으로 시작하여 세 번째 컵에서 구슬을 뿌려서 얻습니다 [1, 2, 0]. 이제 우리는 실제로 선택을 할 수 있지만, 유일한 올바른 것은 첫 번째 컵을 파종하는 것 [0, 2, 0]입니다. 그런 다음 우리는 두 번째 컵 생산량 [1, 0, 0]을 뿌리고 마침내 첫 번째 컵을 다시 뿌려서 모든 빈 컵을 얻습니다.

테스트 사례 :

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]

테스트 케이스를 생성하는 프로그램을 만든 PeterTaylor 에게 감사드립니다 !


답변:


5

CJam (21 바이트)

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

온라인 데모

설명

이 백서 에서 언급 한 "재생되지 않는"기술을 독립적으로 도출했습니다. . 우리는 주어진 구슬 수에 대해 정확히 하나의 당첨 보드가 있음을 유도함으로써 증명합니다.

기본 사례 : 구슬이 0 개인 경우, 승리 한 유일한 보드는 빈 것입니다.

유도 단계 : 컵 k에서 파종 하면 다음 이동 컵 k이 비게되고 바구니 근처에있는 모든 컵에는 적어도 하나의 비드가 들어갑니다. 따라서 우리는 가장 낮은 번호의 빈 컵을 찾고 바구니에서 하나의 비드와 빈 컵 아래의 각 컵에서 하나의 비드를 가져 와서 빈 컵에 모두 배치 하여 n구슬이있는 우승 보드에서 구슬이 있는 독특한 우승 보드를 찾을 수 있습니다 n-1.

해부

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

파이썬, 42 41 바이트

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

4

자바 스크립트 (ES6), 63 37 바이트

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

@orlp의 Python 답변 포트. 설명 : i컵과 컵 의 총 구슬 수를 고려하십시오 . 이 컵 중 하나에서 각각의 놀이는 i그 총에서 구슬을 제거 합니다. (예를 들어, i3 인 경우 다섯 번째 컵에서 플레이하는 경우 해당 컵의 구슬 수를 5만큼 줄이지 만 네 번째와 세 번째 컵 모두에 1을 더합니다.) 따라서 총계는 배수 여야합니다. 의 i. 이제 i-1th 컵에는 i구슬을 하나 이상 포함 할 수 없으므로 여러 컵 을 남기 i려면 나머지 구슬을 포함해야합니다.i .

이전 설명 (@xnor의 링크에서) : 순진한 접근 방식은 "역 재생"기술입니다. 이것은 플레이가 컵을 비운다는 관찰을 사용하므로 리버스 플레이는 각 컵에서 비드를 수집하여 첫 번째 빈 컵에 넣습니다 (63 바이트).

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

이제 첫 번째 i컵을 고려하십시오 . 그중 하나가 비어있는 경우, 리버스 플레이는 1컵의 총 구슬 수에 추가 되며, 비어 있지 않은 경우에는 리버스 플레이가 i총에서 빼지 만 1모듈로 추가와 같습니다. i+1. n리버스 플레이 후 , 첫 번째 i컵 의 비드의 합은 n모듈로 와 동일 i+1하거나 다른 방법으로, ith 컵 n의 비드 수는 이전 컵의 비드의 합에서 모듈로 를 뺀 것과 같습니다 i+1. 이제 ith 컵을 플레이 할 수있게하려면 구슬의 수를 초과 할 수 없습니다i 실제로 나머지 구슬의 수와 동일합니다i+1. ( d=i+1더 적은 바이트를 사용하므로 사용합니다.)


@orlp의 솔루션을 사용하여 버전에서 함수를 할당하는 것을 잊어 재귀가 작동하지 않도록합니다. 또한 그 해결책에 관해서는 배열 연결이 +ES6의 것이 아닌가?
Value Ink

@KevinLau 죄송합니다. 바이트 수에 포함시키는 데 어려움을 겪은 후에도! 그러나 두 매개 변수가 모두 숫자이거나 부울이 아닌 한 +는 문자열 연결입니다.이 경우 더하기입니다. 다행히 배열 이해는 임의의 연결을 더 쉽게 만듭니다.
Neil

2

루비, 36 바이트

@orlp의 대답 포트는 내가 더 나은 것을 생각하기에는 너무 천재이기 때문에.

m=->n,i=2{n>0?[n%i]+m[n-n%i,i+1]:[]}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.