Consider this spiral
###########
#
# #######
# # #
# # ### #
# # # # #
# # # # #
# # # #
# ##### #
# #
#########
Starting in the centre:
- The first line (upwards) has 3 characters.
- The second line has the same number of characters (3)
- Next, we add two chars (5) for the next two sides.
- This pattern continues, two sides the same length then increase the length by 2.
I want to generate this spiral for N lines.
- Write in any language.
- The input/argument, etc. is the number of lines in your spiral.
- Each line starts with the ending character of the previous line in the direction 90 degrees clockwise of the previous line.
- I don't care how much whitespace is before or after each line, as long as the elements of the spiral line up.
- Output text to draw the spiral with any non-whitespace character you choose.
- Attempt to do this in the smallest number of bytes.
Test cases (using a hash as output):
N = 1
#
#
#
N = 2
###
#
#
N = 3
###
# #
# #
#
#
N = 10
###########
#
# #######
# # #
# # ### #
# # # # #
# # # # #
# # # #
# ##### #
# #
#########
6 Answers 6
05AB1E, (削除) 13 (削除ここまで) 11 bytes
Code:
Thanks to Emigna for saving two bytes!
LDÈ-Ì'#3Ý·Λ
Uses the 05AB1E encoding. Try it online!
Explanation
The lengths of each individual edge on the spiral starts with length 3 and gradually increases every two steps by two:
$$ 3, 3, 5, 5, 7, 7, 9,\dots $$
For a spiral with \$n\$ edges, we just need to trim this list to size \$n\$. This is done with the following piece of code:
L # Create a list from [1 .. input]
DÈ # Duplicate and check for each number if even
- # Subtract that from the first list
Ì # Add 2
This basically gives us the desired list of lengths.
'# # Push the '#' character
0246S # Push the array [0, 2, 4, 6]
Λ # Write to canvas
The canvas works as a function that pops three parameters (where the rightmost parameter is popped first): <length(s)>, <char(s)>, <direction(s)>. The directions parameter is in this case a list of numbers. The numbers that correspond to the directions are:
$$ \left[\begin{array}{r} 7 & 0 & 1 \\ 6 & \circ & 2 \\ 5 & 4 & 3 \end{array}\right] $$
In this case, [0, 2, 4, 6] corresponds to the directions list [↑, →, ↓, ←]. The canvas iterates over each length retrieved from the list of lengths, uses the '#' character and cyclically iterates over the directions list.
Python 2, (削除) 176 (削除ここまで) (削除) 170 (削除ここまで) (削除) 165 (削除ここまで) (削除) 161 (削除ここまで) 157 bytes
g=lambda a,r:r and g(map(''.join,zip(*a))[::-1],r-1)or a
R=['#']
n=1
exec"R=g([' '+l for l in g(R,n)][:-1]+[(n+2)*'#'],3*n);n+=1;"*input()
print'\n'.join(R)
Repeatedly: Uses g to rotate the nth iteration of the spiral into a 'canonical' position (similar to N=3 or N=7), adds a new segment by adding 2 spaces at the left of each existing row, then replacing the last row with all '#'s (resulting in a position comparable to N=4 or N=8), and finally using g again to rotate it back to the correct position. Lather, rinse, repeat.
Charcoal, (削除) 16 (削除ここまで) (削除) 15 (削除ここまで) 14 bytes
×ばつ#+3⊗÷ι2↷
-2 bytes thanks to @Neil.
Try it online (verbose) or Try it online (pure).
Explanation:
Printing direction is to the right by default, and we want to start upwards, so we start by rotating 45 degrees counterclockwise:
PivotLeft();
↶
Then loop i in the range [0, input):
For(InputNumber()){ ... }
FN« ...
Print a new-line to mimic the effect of moving back one position:
Print("\n");
¶
Print "#" x amount of times in the current direction:
Print(Times("#", ... ))×ばつ# ...
Where x is: 3 + i // 2 * 2:
Add(3,Doubled(IntegerDivide(i,2))
+3⊗÷ι2
And then rotate 45 degrees clockwise for the next iteration of the loop:
PivotRight();
↷
-
\$\begingroup\$ I assume there's no command in Charcoal for moving backwards? \$\endgroup\$Emigna– Emigna2018年06月26日 12:18:11 +00:00Commented Jun 26, 2018 at 12:18
-
\$\begingroup\$ @Emigna Not sure, but I couldn't find it either. Was indeed looking for one myself when I was writing this answer. There is a Move with a given direction, as well as a Jump with given coordinates, but not a MoveBack unfortunately. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年06月26日 12:22:46 +00:00Commented Jun 26, 2018 at 12:22
-
1\$\begingroup\$
⊗÷ι²is a byte shorter than−ι%ι². Also, you can get the effect of moving back by printing a\nbefore the#s, which will allow you to remove the»#for an additional overall byte saving. \$\endgroup\$Neil– Neil2018年06月26日 14:25:42 +00:00Commented Jun 26, 2018 at 14:25 -
\$\begingroup\$ @Neil Thanks for the
⊗÷ι², but what would the changes be for printing a\nbefore the#s? The spiral is incorrect if I add thePrint("\n"). \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年06月26日 14:40:52 +00:00Commented Jun 26, 2018 at 14:40 -
\$\begingroup\$ Because the arms now overlap you need to make them an extra
#longer. \$\endgroup\$Neil– Neil2018年06月26日 14:43:06 +00:00Commented Jun 26, 2018 at 14:43
Python 2, (削除) 179 (削除ここまで) 178 bytes
thanks to Kevin Cruijssen for -1 byte.
n=input()
S,H=' #'
m=[S*n]*(n%2-~n)
x=n/4*2
y=0--n/4*2
k=2
m[y]=S*x+H+S*n
M=[1,0,-1,0]*n
exec'exec k/2*2*"x+=M[~k];y+=M[k];m[y]=m[y][:x]+H+m[y][x+1:];";k+=1;'*n
print'\n'.join(m)
Python 2, 179 bytes
In this approach formulas are used for x and y deltas instead of a lookup list.
n=input()
S,H=' #'
m=[S*n]*(n%2-~n)
x=n/4*2
y=0--n/4*2
k=2
m[y]=S*x+H+S*n
exec'exec k/2*2*"x+=k%-2+k%4/3*2;y-=(k%2or k%4)-1;m[y]=m[y][:x]+H+m[y][x+1:];";k+=1;'*n
print'\n'.join(m)
-
\$\begingroup\$
n+1+n%2ton%2-~nfor -1 byte. And I need to remember0--n/4*2being 1 shorter than-(-n/4*2). Nice answer, +1 from me. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年06月26日 15:17:56 +00:00Commented Jun 26, 2018 at 15:17
JavaScript (ES6), 185 bytes
Sure this can be golfed more, maybe with currying, but here's my very humble attempt. Line breaks added for readability except penultimate character
r=(a,n=1)=>n?r(a.reduce((_,c)=>c).map((_,i)=>a.map(e=>e[i])).reverse(),n-1):a,
s=n=>n?r(s(n-1)).map((r,i)=>[...r,w,w].map(x=>i?x:'#')):[[w=' ']],
d=n=>r(s(n),1-i).map(r=>r.join``).join`
`
Usage: d(10) returns a string as per the N=10 challenge example.
Defines a function r(a,n) to rotate an array a by n turns; a function s(n) to generate a 2-dimensional array representing a spiral of size n by recursively rotating and adding spacing and lines (not rotated back to starting position); and a function d(n) to draw a spiral of size n, rotated consistently as per the challenge, and rendered as a returned string.
This was a really fun challenge :¬)
Canvas, (削除) 20 (削除ここまで) 16 bytes
×ばつ;↶n}╶├⟳
Explanation
×ばつ;↶11╋}╶├⟳
ø push an empty art object
; swap with the input
{ } for i in 1 to n:
{: } duplicate i
{ 2% } mod 2
{ ! } negate
{ - } subtract that from i
{ ├ } add 2
{ ×ばつ } repeat '#' that many times
{ ; } swap with previous iteration
{ ↶ } turn 90 degrees anticlockwise
{ 11╋} overlap at (1,1)
╶├⟳ rotate 90 degrees n+2 times
*instead of#. Expected? \$\endgroup\$