# Roll the Alphabet into a Spiral

Write a program or function that, when given n, will print a spiral n characters long made up of the Latin alphabet ABCDEFGHIJKLMNOPQRSTUVWXYZ repeated as needed. This spiral should run through the alphabet only forwards.

Related to Alphabet Spiral, though the spiral runs through the alphabet forwards and backwards, and the spiral is constant.

Test cases

4   AB
DC

40   UVWXYZ
TGHIJA
NSFABKB
MREDCLC
LQPONMD
KJIHGFE

0

10  GHIJ
FAB
EDC

1000    UVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
TGHIJKLMNOPQRSTUVWXYZABCDEFGHIJA
SFABCDEFGHIJKLMNOPQRSTUVWXYZABKB
REZCDEFGHIJKLMNOPQRSTUVWXYZABCLC
QDYBMNOPQRSTUVWXYZABCDEFGHIJCDMD
PCXALEFGHIJKLMNOPQRSTUVWXYZKDENE
OBWZKDEFGHIJKLMNOPQRSTUVWXALEFOF
NAVYJCDMNOPQRSTUVWXYZABCDYBMFGPG
MZUXIBCLCDEFGHIJKLMNOPQREZCNGHQH
KXSVGZAJAZGHIJKLMNOPQROTGBEPIJSJ
JWRUFYZIZYFUVWXYZABCDSPUHCFQJKTK
IVQTEXYHYXETQRSTUVWXETQVIDGRKLUL
HUPSDWXGXWDSPUVWXYZYFURWJEHSLMVM
GTORCVWFWVCROTGHIJAZGVSXKFITMNWN
FSNQBUVEVUBQNSFABKBAHWTYLGJUNOXO
ERMPATUDUTAPMREDCLCBIXUZMHKVOPYP
DQLOZSTCTSZOLQPONMDCJYVANILWPQZQ
CPKNYRSBSRYNKJIHGFEDKZWBOJMXQRAR
BOJMXQRARQXMLKJIHGFELAXCPKNYRSBS
ANILWPQZQPWVUTSRQPONMBYDQLOZSTCT
ZMHKVOPYPONMLKJIHGFEDCZERMPATUDU
YLGJUNOXONMLKJIHGFEDCBAFSNQBUVEV
XKFITMNWVUTSRQPONMLKJIHGTORCVWFW
WJEHSLMLKJIHGFEDCBAZYXWVUPSDWXGX
VIDGRKJIHGFEDCBAZYXWVUTSRQTEXYHY
UHCFQPONMLKJIHGFEDCBAZYXWVUFYZIZ
TGBEDCBAZYXWVUTSRQPONMLKJIHGZAJA
SFAZYXWVUTSRQPONMLKJIHGFEDCBABKB
REDCBAZYXWVUTSRQPONMLKJIHGFEDCLC
QPONMLKJIHGFEDCBAZYXWVUTSRQPONMD
LKJIHGFE


Rules

• Your input will be a non-negative integer 0 <= n <= 1000, but your code should theoretically handle any non-negative integer.
• Your output format may be in any sane format, with delimiters if necessary.
• Rotations and reflections are equivalent.
• Your alphabet may be uppercase or lowercase.
• The empty spaces in your spiral may be filled in with whatever non-alphabetic nulls you see fit.
• The spiral itself may be in any shape you see fit. Rectangular spirals work best with ASCII solutions, but graphical solutions may be shorter with circular spirals.
• Leading and trailing spaces and newlines are allowed.
• This is code golf. The shortest answer in bytes (or equivalent) wins.

As always, if anything is unclear or incorrect, please let me know in the comments. Good luck and good golfing!

• most editors will not allow printing out a string that long Aug 31 '16 at 8:05
• @t-clausen.dk I went with the standard signed 32-bit integer maximum. If you have a better suggestion for an upper bound, I'd be happy to edit it in. Aug 31 '16 at 8:21
• Nice and tricky :-) Aug 31 '16 at 21:27

# Logo, 129 87 bytes

## Graphical solution, implemented as function

This was built on Calormen.com's Logo interpreter. The S function takes the number of characters as a parameter and draws them in a spiral. The T function outputs letters upright to prevent them from rotating with the spiral.. I decided that it looked nicer (and golfed out 42 bytes) to omit correcting the letter orientation. I also tightened up the spacing which did not change the byte count. If you were to actually roll up an alphabet, it would look more like this anyway.

### Updated Version (letters roll)

TO S:r
PU IF:r[REPEAT:r[LABEL CHAR((REPCOUNT-1)%26)+65
RT 99/SQRT(REPCOUNT)FD 12]]END


### Invocation

Invoke as follows: S iterations

### Sample output

S 1000


## Old Version (letters always upright)

TO T:l:h
RT:h
LABEL CHAR(:l%26)+65
LT:h
END
TO S:r
RT 95/SQRT(REPCOUNT)FD 15]]END


Old output removed to save space. See it here.

• Don't ask how I came up with the math. I tried searching for formulas online, but most solved the problem by keeping the turn angle constant and increasing the segment length, whereas I wanted to keep the segment length constant and change the angle. Trial and error seems to have led to a stable formula. Adjusting the 95 will change the tightness of the spiral, and changing the 15 will adjust the linear spacing of the letters. Sep 1 '16 at 19:03

## Javascript (ES6), 203 201 bytes

n=>{for(a=[],i=d=k=z=0,p=526,j=1;i<n;){p+=[1,32,-1,-32][d&3];j--||(((z^=1)||k++),j=k,d++);(a[y=p>>5]=(a[y]||Array(32).fill ))[p&31]=String.fromCharCode(65+(i++%26))}return a.map(r=>r.join).join
}


### Demo

The demo below should be preferably run in full page.

let f =

n=>{for(a=[],i=d=k=z=0,p=526,j=1;i<n;){p+=[1,32,-1,-32][d&3];j--||(((z^=1)||k++),j=k,d++);(a[y=p>>5]=(a[y]||Array(32).fill ))[p&31]=String.fromCharCode(65+(i++%26))}return a.map(r=>r.join).join
}

function draw(n) {
document.getElementById('v').innerHTML = n;
document.getElementById('o').innerHTML = f(n);
}
draw(500);
pre {font-size:10px}
<input type="range" min="1" max="1000" oninput="draw(this.value)" style="width:500px"><span id="v"></span><pre id="o"></pre>

# R, 46 or 51 bytes, depending on spacing

s=1:scan();plot(s*sin(s),s*cos(s),pch=letters)


(updated version of plot: the gray spiral isn't plotted by default but I added it after to show that the letters indeed lie on a spiral.)

The spiral isn't of constant spacing, so I hope this is okay. If constant spacing is required, start with s=(1:scan())^.5 instead, and add 5 bytes to the total. Then the output is as below (n=150):

• How you space your spiral is completely up to you. I do have two suggestions, though: 1) Keep the second spiral. It adds to your answer even if it's less golfy; 2) Can you draw a spiral line going through the letters in the image of your first spiral? Just to make the alphabet spiral clearer. Sep 2 '16 at 6:50

# Python 3.5, 180157152147 141 bytes

-6 due to Sherlock9

r=[[]]
for x in range(int(input())):
r=len(r[-1])<len(r[0])and r or[*zip(*r[::-1]),[]];r[-1]+=[chr(x%26+65)]
print(*map(''.join,r),sep='\n')


-5 due to Kap.

R=range
def g(n):
r=[[]]
for x in R(n):
if len(r[-1])==len(r[0]):r=[*zip(*r[::-1]),[]]
r[-1]+=[chr(x%26+65)]
print(*map(''.join,r),sep='\n')


### Revised Solution, python 3.x:

R=range
def g(n):
r=[[]]
for x in R(n):
if len(r[-1])==len(r[0]):r=list(zip(*r[::-1]))+[[]]
r[-1]+=[chr(x%26+65)]
print(*map(''.join,r),sep='\n')


### Previous Solution:

R=range
def g(n):
r=[]
for x,f in zip(R(n),(j<1for i in R(n)for j in R(i//2+1))):
if f:r=list(zip(*r[::-1]))+[[]]
r[-1].append(chr(x%26+65))
print(*map(''.join,r),sep='\n')


### Explanation

r is a list of lists that holds the spiral. The basic idea is that new letters are added to the bottom row of the spiral (r[-1].append(chr(x%26+65))). When the bottom row is filled up, the spiral is rotated 90 clockwise and a new empty row is added to the bottom (r = list(zip(*r[::-1]))+[[]]).

The trick is to figure out when to rotate the spiral. In the first solution, the generator (j<1for i in R(n)for j in R(i//2+1)) produces a sequence of True/False values that tell when to rotate the spiral. In the revised solution, I changed the way r is initialized. Now when the length of the bottom row equals the length of the top row, the spiral needs to be rotated.

• You can replace if len(r[-1])==len(r[0]):r=list(zip(*r[::-1]))+[[]] with if len(r[-1])==len(r[0]):r=[*zip(*r[::-1]),[]] to save 5 bytes. Sep 1 '16 at 1:37
• Since you only use range once, you can remove R to save bytes. You can also save bytes by converting your answer to a full program, though to preserve the use of [*zip(*r[::-1]),[]], you'll need to use range(int(input())). Sep 2 '16 at 11:22
• Also, for x in range(int(input())):r=len(r[-1])<len(r[0])and r or[*zip(*r[::-1]),[]];r[-1]+=[chr(x%26+65)] since you're checking when the last line is equal or greater to the first line. Sep 2 '16 at 11:53
• Two things: 1) You can make the for loop one line long by separating the statements with semicolons; and 2) you haven't defined n in this version. Either you need to use int(input()) or wrap in back up in a function. Sep 3 '16 at 3:40
• 2 bytes from condensing the for loop: for x in range(int(input())):r=len(r[-1])<len(r[0])and r or[*zip(*r[::-1]),[]];r[-1]+=[chr(x%26+65)] Sep 13 '16 at 2:40

# MATL, 21 18 bytes

X^Xk1YL1Y2y)wG>~*c


Input 0 exits with an error (which is allowed by default).

Try it online!

### Explanation

X^Xk   % Input n implicitly. Take square root and round up
1YL    % Square matrix of that size containing a spiral of numbers
1Y2    % Predefined literal: string "AB···YZ"
y      % Duplicate the spiral matrix onto the top
)      % Apply as an index inth the string. Gives 2D array of chars
w      % Swap: move copy of the spiral matrix to top
G>~    % Set entries that exceed the input to 0, and the rest to 1
*      % Multiply. This makes unwanted entries equal to 0
c      % Convert to char. 0 is shown as a space. Display implicitly


# Python 2, 84 82 bytes

I'm using Turtle again. It's so fun! :D

from turtle import*
up()
for i in range(input()):write(chr(i%26+65));rt(9);fd(9+i)


Try it online

Unfortunately, Trinket.io has a horribly small canvas. I changed 9+i to 9+i/9 and adjusted the turtle's starting point for the purpose of screen-capturing this image, so that more of the output would fit:

• One byte from if you remove a space from the import: from turtle import* and another from changing from while to for i in range(input()) Sep 13 '16 at 2:39

# Pyth, 32 bytes

JS@Q2ju+.t_G)Hc<*GQQ.u+NY.iJJZ]Y


A program that prints a rectangular lower-case ASCII spiral. Depending on the input, one row or column of leading or trailing whitespace may be present.

Try it online

How it works

JS@Q2ju+.t_G)Hc<*GQQ.u+NY.iJJZ]Y  Program. Input: Q
@Q2                             Yield sqrt(Q)
JS                                Unary range, J=[1, 2, 3, ..., floor(sqrt(q))]
.iJJ     Interleave J with itself, yielding [1, 1, 2, 2, 3, 3, ...
floor(sqrt(Q)), floor(sqrt(Q))]
.u+NY    Z    Cumulatively reduce by addition with base case 0,
yielding [0, 1, 2, 4, 6, 9, 12, 16, 20...]
*GQ               Repeat the lower-case alphabet Q times
<   Q              Truncate to legth Q
c                   Split the above at the indices in the above list
u                       ]Y  Reduce the above, with base case [[]]:
_G                       Reverse
.t  )                      Transpose
+     H                     Add the next arm of the spiral
j                            Join on newlines and implicitly print


# TSQL, 386362358 306 bytes

Please note that TSQL doesn't have a way to rotate text. This script is starting from A and calculating which direction the next letter should be placed. (right, down, left, left, left, up, up, right...)

The script can handle a maximum of 7744 letters.

Golfed:

DECLARE @z INT = 7744

DECLARE @ INT=2+SQRT(@z-1)DECLARE @o varchar(max)=REPLICATE(SPACE(@-1)+char(10),@-1);WITH C as(SELECT 0i,@/2a,@/2b UNION ALL SELECT i+1,a+z/2,b+z%2FROM(SELECT*,IIF(a>@/2*2-b,IIF(a<b,2,-1),IIF(a>b,-2,1))z FROM C)t WHERE i<@z-1)SELECT @o=STUFF(@o,@*a-@+b,1,char(i%26+65))FROM c OPTION(maxrecursion 0)PRINT @o


Ungolfed:

DECLARE @z INT = 7744

DECLARE @ INT=2+SQRT(@z-1)
DECLARE @o varchar(max)=REPLICATE(SPACE(@-1)+char(10),@-1)

;WITH C as
(
SELECT
0i,@/2a,@/2b
UNION ALL
SELECT
i+1,a+z/2,b+z%2
FROM
(SELECT*,
IIF(a>@/2*2-b,
IIF(a<b,2,-1),
IIF(a>b,-2,1))z FROM C)t
WHERE
i<@z-1
)
SELECT
@o=STUFF(@o,@*a-@+b,1,char(i%26+65))
FROM c
OPTION(maxrecursion 0)

PRINT @o


Fiddle

# Python 2, 243 bytes

r=range(input())
a=[1j**int((4*i+1)**.5)for i in r]
b=[map(int,(-sum(a[:i]).real,sum(a[:i]).imag))for i in r]
c,d=zip(*b)
for i in range(min(c),max(c)+1):print''.join([i,j]in b and chr(b.index([i,j])%26+65)or' 'for j in range(min(d),max(d)+1))


Ideone it!

# PHP, 219 bytes

for($q=ceil(sqrt($a=$argn))**2,$d=1,$x=$y=$w=0;$i<$q;$i++,${yx[$w%2]}+=[-1,1][$d&1],$i%$d?:$d+=$w++&1)$e[$c[]=$x-!($a&1)][$l[]=$y]=$i<$a?chr(65+$i%26):" ";for($k=min($c);$e[$k];print join($e[+$k++])."\n")ksort($e[+$k]);


Try it online!

PHP , 260 Bytes

Old version

for($y=$x=$d=$i=0;$i<$m=ceil(sqrt($n=$argv[1]))**2;$i++){$a[$y][$x]=$i<$n?chr($i%26+65):" ";$d=$y==$x&$y<1?0:(1-$y==$x&$x>0?1:($y==$x&$y>0?2:($y==-$x&$x<0?3:$d)));$d>2?$y--:($d>1?$x--:($d>0?$y++:$x++));}ksort($a);foreach($a as$r){ksort($r);echo join(\$r)."\n";}