Solomon Golomb’s self-describing sequence f ( 1 ) , f ( 2 ) , f ( 3 ) , . . . is the only non-decreasing sequence of positive integers with the property that it contains exactly f ( k ) occurrences of k for each k . A few moment’s thought reveals that the sequence must begin as follows:
n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
f(n) | 1 | 2 | 2 | 3 | 3 | 4 | 4 | 4 | 5 | 5 | 5 | 6 |
Find the 123456th term of the sequence.
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 6 8 4
a=[1]
for i in range(10000):
x=int(i+1)
for j in range(a[i]):
a.append(x)
a[1]=2
print a[123456-1]
The straightforward solution is to generate the sequence until we reach the 1 2 3 4 5 6 -th term.
1 2 3 4 5 6 7 8 9 |
|
To investigate further on this sequence, I found the recurrence relation from wikipedia :
f ( n ) = { 1 1 + f ( n − f ( f ( n − 1 ) ) ) n = 1 n > 1
Here I'll give a short explanation on why this works. To compute f ( n ) for n > 1 , our goal is to identify k such that f ( k ) + 1 = f ( n ) . By definition, f ( n ) is the number of occurrence of n . Hence f ( f ( n ) ) is the number of occurrence of f ( n ) .
Case 1 : f ( n − 1 ) = f ( n )
In this case, n − f ( f ( n − 1 ) ) = n − f ( f ( n ) ) must fall in the place where its term is one less than f ( n ) . Hence we just have to increment it by 1 .
Case 2 : f ( n − 1 ) = f ( n ) − 1
In this case, the n -th term is the first occurrence of f ( n ) in the sequence. So, n − f ( f ( n − 1 ) ) = n − f ( f ( n ) − 1 ) still falls in the correct place where its term is still one less than f ( n ) .
Surprisingly, this code is much slower than the naive one.
1 2 3 4 5 6 7 |
|
Another approach is to consider the formula by Benoit Cloitre :
For a 1 + a 2 + ⋯ + a n − 1 < k ≤ a 1 + a 2 + ⋯ + a n we have a k = n .
With this formula, the length of sequence we have to generate is shortened because we only need to generate the sequence until the prefix sum is larger than k instead of the number of terms equal to k like the first one. We generate a large enough sequence and binary search for the desired n .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Here is my code for it:
1 2 3 4 5 |
|
Did the same but I had to learn new things for this. I didn't know this 'list addition' before today. Thanks for posting!
Problem Loading...
Note Loading...
Set Loading...
I liked this problem :) I did some weird array checking, it nicely worked out, but it takes a while (~1 min.)