Consider the following list:
expected = [
'A',
'B',
'AB',
'C',
'D',
'CD',
'ABCD',
'E',
'F',
'EF',
'G',
'H',
'GH',
'EFGH',
'ABCDEFGH',
'I',
'J',
'IJ',
'K',
'L',
'KL',
'IJKL',
'M',
'N',
'MN',
'O',
'P',
'OP',
'MNOP',
'IJKLMNOP',
'ABCDEFGHIJKLMNOP',
...
]
Here's one way to look at it - you're learning how to write Chinese characters and want to learn increasingly big chunks of them, rehearsing them as you go. You start with A, then go with B, then there's already a sequence that is a pair of two so you combine it. Then you go with C and D, make another pair, practice it. Then you rehearse: ABCD. Then the same goes with E up to H, then rehearse: ABCDEFGH. The list is infinite.
The goal is to generate and print out an n-th element of this list, indexes going up from zero. Assume that after 'Z', you get 'A' again.
The winning criteria is source code length.
7 Answers 7
Python 2, 53 bytes
x,y=0,1
exec"x^=y-x;y+=x/y;"*input()
print range(x,y)
Similar to this construction with the transformation x = u-v, y = u
-
\$\begingroup\$ What a nice simplification! The first statement can be
x^=y-xfor -1 byte. \$\endgroup\$xnor– xnor2018年07月21日 17:40:27 +00:00Commented Jul 21, 2018 at 17:40 -
\$\begingroup\$ @xnor oh right, silly me \$\endgroup\$KSab– KSab2018年07月21日 18:03:52 +00:00Commented Jul 21, 2018 at 18:03
JavaScript (ES6), 59 bytes
We can save 2 bytes by making the sequence 1-indexed and using a simplification similar to the one used by KSab:
n=>(x=g=y=>n?g(y+=y==(x^=y-x),n--):x<y?[x++,...g(y)]:[])(1)
JavaScript (ES6), 61 bytes
Returns a list of non-wrapping integers.
n=>(g=v=>n?g(u&-u^v?v*2:!!u++,n--):v?[u-v,...g(v-1)]:[])(u=1)
Based upon a construction by Donald Knuth. Related OEIS entry: A182105.
How?
This is a two-stage recursive function.
We first build the sequence \$(u_n,v_n)\$ defined as \$(u_1,v_1)=(1,1)\$ and:
$$(u_{n+1},v_{n+1})=\begin{cases}(u_{n}+1,1),&\text{if }(u_{n}\operatorname{AND}-u_{n})=v_{n}\\(u_{n},2v_{n}),&\text{otherwise}\end{cases}$$
During the second pass, we build the list \$[u_n-v_n,u_n-v_n+1,\dots,u_n]\$ and eventually return it.
JavaScript (ES6), 97 bytes
Returns wrapping uppercase letters.
n=>(s=i='',g=v=>(s+=String.fromCharCode(65+i++%26),n--)?g(u&-u^v?v*2:!!u++):s.substr(u-v,v))(u=1)
Or 91 bytes in lowercase.
Python 2, 60 bytes
u=v=1
exec"v=u/v%2or 2*v;u+=1/v;"*input()
print range(u-v,u)
Based on Arnauld's use of Knuth's construction. The condition u&-u==v can be replaced with a simpler condition u/v%2>0, or alternatively u&v>0, since v is always a power of 2 that u is divisible by.
Wolfram Language (Mathematica), (削除) 80 (削除ここまで) 71 bytes
Range@#2+#-#2&@@Nest[If[#~BitAnd~-#==#2,{#+1,1},{#,2#2}]&@@#&,{1,1},#]&
Returns a list of integers instead of a wrapping string of alphabet. 0-indexed.
Uses OEIS A182105, thanks to @Arnauld.
Printing the list indefinitely, 54 bytes
Do[j=Range@i;#∣i&&Print@j[[-#;;]]&/@(2^j/2),{i,∞}]
1-indexed. The TIO version has lim instead of ∞ to prevent crashes.
Python 2, (削除) 93 (削除ここまで) (削除) 89 (削除ここまで) 82 bytes
def f(n):r=[];C=1;exec"p=C%2or 2*p;r+=[p];C=r.count(p);"*n;return range(C*p-p,C*p)
Returns a list of integers. Similar to Arnauld's Javascript approach.
Jelly, 16 bytes
1;ẎṀ+ƊẎQṭƊƊ¡ị@‘Ṿ
Try it online! TIO link works well up to and including \13ドル\$.
Full program. Prints ,-separated list of integers.
Charcoal, (削除) 45 (削除ここまで) (削除) 42 (削除ここまで) 35 bytes
FN⊞υ⎇∧›Lυ1=L§υ±1L§υ±2+⊟υ⊟υ§αL⭆υκ⮌⊟υ
Try it online! Link is to verbose version of code. 1-indexed. I couldn't find a simple formula to generate the result so I simply followed the procedure given in the question. Explanation:
FN
Repeat the given number n times.
⊞υ
Push the next element to the predefined empty array u, calculated as...
⎇∧›Lυ1=L§υ±1L§υ±2
... if there is more than one element in u and the last two elements have the same length...
+⊟υ⊟υ
... then append the penultimate element to the last element (which builds up the result in reverse order)...
§αL⭆υκ
... otherwise the next letter can be found by counting how many letters we've added so far and cyclically indexing into the predefined uppercase alphabet. (Taking either the sum of length or length of sum fails when the list is empty, and mapping the list into a string saves two bytes over special-casing an empty list.)
⮌⊟υ
Take the last element of u, which is the reversed nth element of the desired list, and implicitly print the reverse.
BCorCDEF? What decides what we concatenate and what we don't? How is it infinite if it starts atAagain afterZ(you mean at some point afterABCDEFGHIJKLMNOPQRSTUVWXZwe haveABCDEFGHIJKLMNOPQRSTUVWXZABor something?) \$\endgroup\$x,y,z,a,b...). \$\endgroup\$