Python 124 107 bytes * 50% = 53.5
f=lambda i,e=1:i and[e]*(i%3>1)+f(-~i/3,e*3)or[]
for i in range(3**4/2+1):r=f(-i),f(i);print i,map(sum,r),r
For different numbers of stones, replace the 4
in range(3**4/2+1)
with any positive integer.
Sample output:
0 [0, 0] ([], [])
1 [1, 0] ([1], [])
2 [3, 1] ([3], [1])
3 [3, 0] ([3], [])
4 [4, 0] ([1, 3], [])
5 [9, 4] ([9], [1, 3])
6 [9, 3] ([9], [3])
7 [10, 3] ([1, 9], [3])
8 [9, 1] ([9], [1])
9 [9, 0] ([9], [])
10 [10, 0] ([1, 9], [])
11 [12, 1] ([3, 9], [1])
12 [12, 0] ([3, 9], [])
13 [13, 0] ([1, 3, 9], [])
14 [27, 13] ([27], [1, 3, 9])
15 [27, 12] ([27], [3, 9])
16 [28, 12] ([1, 27], [3, 9])
17 [27, 10] ([27], [1, 9])
18 [27, 9] ([27], [9])
19 [28, 9] ([1, 27], [9])
20 [30, 10] ([3, 27], [1, 9])
21 [30, 9] ([3, 27], [9])
22 [31, 9] ([1, 3, 27], [9])
23 [27, 4] ([27], [1, 3])
24 [27, 3] ([27], [3])
25 [28, 3] ([1, 27], [3])
26 [27, 1] ([27], [1])
27 [27, 0] ([27], [])
28 [28, 0] ([1, 27], [])
29 [30, 1] ([3, 27], [1])
30 [30, 0] ([3, 27], [])
31 [31, 0] ([1, 3, 27], [])
32 [36, 4] ([9, 27], [1, 3])
33 [36, 3] ([9, 27], [3])
34 [37, 3] ([1, 9, 27], [3])
35 [36, 1] ([9, 27], [1])
36 [36, 0] ([9, 27], [])
37 [37, 0] ([1, 9, 27], [])
38 [39, 1] ([3, 9, 27], [1])
39 [39, 0] ([3, 9, 27], [])
40 [40, 0] ([1, 3, 9, 27], [])
The basic operating principle, is that the problem is analog to converting a number into ternary. In Python, this is a one liner:
f=lambda i:i and i%3+f(i/3)*10
Of course, we're working in a slightly different base. Instead of the values 0, 1, 2
we use -1, 0, 1
. This means when i%3 == 2
, this should really be -1
(calculated by (i+1)%3-1
or -~i%3-1
), and the value of the i
sent to the next iteration needs to be adjusted accordingly.
More specifically, if d=(i+1)%3-1
, then the value of i
sent to the next iteration should be (i-d)/3
. However, this calculaion can be simplified greatly using integer division, to just (i+1)//3
. Rationale: if d == 0
, then i
was already a multiple of 3
, and adding one won't change the integer quotient. If d == 1
, then we should be subtracting 1
to make i
a multiple of 3, but if we add 1
instead, it will now be 2 (mod 3)
, which won't change the integer quotient either. If however d == -1
, then we do in fact need to add 1
to reach the next multiple of 3
. Therefore, by using integer division, all three cases can be simplified to adding 1
.
One thing that makes this problem interesting is that the negative and positive values need to be separated into different baskets. I decided the best way to accomplish this is to only collect the positive values, and then call the function again with -i
, which will obviously have its stones reversed. This also allows me to save the -~i%3
calculation entirely, since I know what its value will be.