The sequence s = [ 1 , 2 , 2 , 1 , 1 , 2 , 1 , 2 , 2 , 1 , 2 , 2 , 1 , 1 , 2 , 1 , 1 , 2 , 2 , 1 , 2 , … ] may be described as
1 one, 2 twos, 2 ones, 1 two, 1 one, 2 twos, 1 one, etc.
Remarkably, the counts that occur in this description are precisely the elements of s itself! Thus, s is a self-describing sequence.
1 1 2 2 2 2 1 1 1 2 1 1 2 2 2 1 1 2 2 2 2 1 1 1 2 2 1 1 ⋯
How many twos occur in the first 1,000,000 elements of this sequence?
Bonus : In the original version of this problem, no more than 2000 bytes of memory was to be used during the calculation.
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.
The logic of my solution may be clearer if it is written recursively:
1 2 3 4 5 6 7 8 9 |
|
At the very beginning, this will lead to endless recursion. Therefore I set the dbl[] flag at the top level (where we will never have to generate the next digit). This stops the recursion and gets the list really going.
A short snippet in Python3; took 0.5 seconds.
1 2 3 4 5 6 7 8 9 10 |
|
The most interesting thing about this is how such a short program can generate a sequence that never repeats, i.e. quasi-random. I like that, the implications this suggests.
Technically speaking, this is not a finite state automata because it involves a "tag" that grows without limit.
The program I wrote is just a bit longer than Arjen's, and, no, I did not figure one out in 5 minutes. I used 2 pointers on the string, and depending on what one says, the other is moved, after adding a few things to the string. While this is happening, count the 2's being added, until the string is 1,000,000 terms long. "Very confusing but straightforward anyway--once it is put together".
Let me get the logic in a moment.
Let p1 and p2 (p1<p2) be positions on the string, which returns S(p1) and S(p2).
If S(p1)=1
....then if S(p2)=1
................then S(p2+1)=2
................otherwise S(p2+1)=1
....p2=p2+1
If S(p1)=2
....then if S(p2)=1
.................then S(ps+1)=1
.........................S(ps+2)=2
.................otherwise S(ps+1)=2
..................................S(ps+2)=1
....p2=p2+2
p1=p1+1
No effort was made to restrict "memory space to 2000 bytes".
What's interesting about the Thue-Morse sequence is that its recurrence plot is strikingly similar to the one for this sequence. It takes a sharp eye to distinguish between the two.
Rather interesting indeed. The Thue-Morse sequence comes to mind too. Do you have the details that led you to your solution?
Log in to reply
The program I wrote is just a bit longer than Arjen's, and, no, I did not figure one out in 5 minutes. I used 2 pointers on the string, and depending on what one says, the other is moved, after adding a few things to the string. While this is happening, count the 2's being added, until the string is 1,000,000 terms long. "Very confusing but straightforward anyway--once it is put together".
Let me get the logic in a moment.
Let p1 and p2 (p1<p2) be positions on the string, which returns S(p1) and S(p2).
If S(p1)=1
....then if S(p2)=1
................then S(p2+1)=2
................otherwise S(p2+1)=1
....p2=p2+1
If S(p1)=2
....then if S(p2)=1
.................then S(ps+1)=1
.........................S(ps+2)=2
.................otherwise S(ps+1)=2
..................................S(ps+2)=1
....p2=p2+2
p1=p1+1
No effort was made to restrict "memory space to 2000 bytes".
What's interesting about the Thue-Morse sequence is that its recurrence plot is strikingly similar to the one for this sequence. It takes a sharp eye to distinguish between the two.
How do you show that this sequence never repeats?
Almost no time spent optimising. But then how often would I use this?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
[Python 2.7.10]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
... calculates the sequence recursively, starting from {1 2}, until the length of the sequence exceeds 1000000.
Not very efficient code. (spents about 3~4 seconds)
Problem Loading...
Note Loading...
Set Loading...
Output: 5 0 0 0 1 4 .
Explanation: We generate dynamically the same sequence at different levels:
s 0 : The bottom-level sequence, in which we count the number of twos.
s 1 : The sequence that describes s 0 ; specifically, if an element in s 1 equals 2, an element in s 0 will be repeated.
s 2 : The sequence that describes s 1 ;
and so on.
It turns out that we need to keep track of only two tidbits of information at each level:
v a l i : The digit at the current position in sequence s i ;
d b l i : Whether this digit in sequence s i will be repeated or not.
How do we generate the next digit at any given level i ?
If the flag d b l i is set, we simply repeat the digit. The value of v a l i needs no change. Only we must turn off the flag d b l i , because no digit may be repeated more than once. There is no need to generate the value at any higher level.
If the flag d b l i is not set, we must change the digit: v a l i ↦ 3 − v a l i . To determine whether this digit must be repeated or not, we must generate the next digit at a higher level. If this equals 2, we set the d b l flag; if not, we clear it. Note that generating the next digit at a higher level may in turn require generating a digit at the level above that, and so on.