22
\$\begingroup\$

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
 LYTWHABKBABCDEFGHIJKLMNSFADOHIRI
 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!

asked Aug 31, 2016 at 6:18
\$\endgroup\$
3
  • \$\begingroup\$ most editors will not allow printing out a string that long \$\endgroup\$ Commented Aug 31, 2016 at 8:05
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Aug 31, 2016 at 8:21
  • \$\begingroup\$ Nice and tricky :-) \$\endgroup\$ Commented Aug 31, 2016 at 21:27

10 Answers 10

12
\$\begingroup\$

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

Sample output for 1000 iterations

Old Version (letters always upright)

(削除)

TO T:l:h
RT:h
LABEL CHAR(:l%26)+65
LT:h
END
TO S:r
PU IF:r[REPEAT:r[T REPCOUNT-1 90-HEADING
RT 95/SQRT(REPCOUNT)FD 15]]END

(削除ここまで)

Old output removed to save space. See it here.

answered Sep 1, 2016 at 6:08
\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Sep 1, 2016 at 19:03
9
\$\begingroup\$

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>

answered Aug 31, 2016 at 16:58
\$\endgroup\$
8
\$\begingroup\$

R, 46 or 51 bytes, depending on spacing

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

enter image description here

(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):

enter image description here

answered Sep 1, 2016 at 13:13
\$\endgroup\$
1
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ Commented Sep 2, 2016 at 6:50
6
\$\begingroup\$

Python 3.5, (削除) 180 (削除ここまで) (削除) 157 (削除ここまで) (削除) 152 (削除ここまで) (削除) 147 (削除ここまで) 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.

answered Aug 31, 2016 at 20:59
\$\endgroup\$
5
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Sep 1, 2016 at 1:37
  • \$\begingroup\$ 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())). \$\endgroup\$ Commented Sep 2, 2016 at 11:22
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Sep 2, 2016 at 11:53
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Sep 3, 2016 at 3:40
  • \$\begingroup\$ 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)] \$\endgroup\$ Commented Sep 13, 2016 at 2:40
5
\$\begingroup\$

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
answered Aug 31, 2016 at 8:34
\$\endgroup\$
5
\$\begingroup\$

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:

output

answered Sep 12, 2016 at 20:57
\$\endgroup\$
1
  • \$\begingroup\$ 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()) \$\endgroup\$ Commented Sep 13, 2016 at 2:39
4
\$\begingroup\$

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
answered Sep 2, 2016 at 0:03
\$\endgroup\$
3
\$\begingroup\$

TSQL, (削除) 386 (削除ここまで) (削除) 362 (削除ここまで) (削除) 358 (削除ここまで) 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

answered Sep 2, 2016 at 8:41
\$\endgroup\$
2
\$\begingroup\$

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!

answered Aug 31, 2016 at 9:39
\$\endgroup\$
0
\$\begingroup\$

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";}
answered Sep 13, 2016 at 9:57
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.