30
\$\begingroup\$

Remember those fun pinwheels that you blow on and they spin round and round? Let's code one!

A pinwheel will have the set of characters \ | / _ drawing its center and arms. One possible pinwheel could look like this:

    |
    |
    |_ ___
 ___|_|
      |
      |
      |

But what's a pinwheel that doesn't spin? No fun! We can make it spin by rearranging the symbols:

      /
\    /
 \  /
  \/\
   \/\
   /  \
  /    \
 /

The challenge is to create a program that takes three integers and outputs a pinwheel as specified below. The first of these is the number of arms it has, the second is the length of the pinwheel's arms, and the third is the number of times it will spin one-eighth of a revolution clockwise.

You can assume the following:

  • The number of arms will always be 0, 1, 2, 4, or 8.
  • All the arms will be equally spaced apart from each other.
  • The initial position of the pinwheel will have its center like this:

     _
    |_|
    
  • If the number of arms is 1, you may decide which direction the arm points.

  • If the number of arms is 2, you may decide to make the arms point vertically or horizontally.

You can write a full program that takes input through STDIN or command-line argument, or a function that takes input through function arguments. Your program must show a sequence of outputs that shows the pinwheel spinning, each separated by at least one empty line. The center of the pinwheel should not move by more than one space. You may output as many leading and trailing spaces as necessary.

Here are some examples:

0 2 1

 _
|_|

/\
\/

1 3 2

|
|
|_
|_|

   /
  /
 /
/\
\/

 _ ___
|_|

2 2 0

   _ __
__|_|

8 4 1

 \   |    /
  \  |   /
   \ |  /
    \|_/____
 ____|_|
     / |\
    /  | \
   /   |  \
  /    |   \

     |   /
 \   |  /
  \  | /
   \ |/
____\/\____
     \/\
     /| \
    / |  \
   /  |   \
  /   |

This is code golf, so shortest code wins. Good luck!

\$\endgroup\$
  • \$\begingroup\$ Can there be a trailing newline in the output? \$\endgroup\$ – usandfriends Jan 6 '16 at 20:40
  • \$\begingroup\$ Trailing newlines are permitted, without restriction concerning the amount. \$\endgroup\$ – TNT Jan 6 '16 at 21:22
  • \$\begingroup\$ Also for the last example, you have an extra space prepended to each line for the first output. Can we have prepended and trailing spaces in the output? \$\endgroup\$ – usandfriends Jan 6 '16 at 21:37
  • \$\begingroup\$ The number of leading spaces in the output has to do with the position of the center of the pinwheel, the position of which should not shift by more than one space. If the rotation of the pinwheel will cause an arm to end up left of the pinwheel's center later in the output (such as for input 1 3 5 and the arm initially pointing up), spaces will need to be prepended in earlier outputs to accommodate for this. \$\endgroup\$ – TNT Jan 6 '16 at 21:51
4
\$\begingroup\$

Python 2 535 517 473 468 bytes

Saved 5 bytes thanks to @Easterly Ink!

Input expected to be comma separated (i.e., numArms,armLength,numRots)

Golfed Version

n,l,t=input()
b=[7,3,1,5,0,4,2,6][:n]
w=5+2*l
h=w-3
X=w/2
Y=h/2-1
z=range
d=[0,1,1,1,0,-1,-1,-1]
for j in z(t+1):
 g=[[' 'for _ in[1]*w]for _ in[1]*h];a=j%2;b=[(k+1)%8for k in b];print''
 if a:g[Y][X:X+2]='/\\';g[Y+1][X:X+2]='\\/'
 else:g[Y][X+1]='_';g[Y+1][X:X+3]='|_|'
 for k in b:k=k+8*a;x=[0,2,3,3,2,0,-1,-1,0,1,2,2,1,0,-2,-1][k]+X;y=[0,0,0,2,2,2,1,0,-1,-1,0,1,2,2,0,0][k]+Y;exec"g[y][x]='|/_\\\\'[k%4];x+=d[k%8];y+=d[(k-2)%8];"*l
 for k in z(h):print''.join(g[k])

Ungolfed Version

numArms, armLength, rotAmount = input()

# Choose which arms to draw
arms = [0,4,2,6,1,5,3,7][:numArms]
for i in xrange(rotAmount+1):

    # Set up the grid spacing
    maxWidth = 5 + 2 * armLength
    maxHeight = 2 + 2 * armLength
    grid = [[' ' for x in xrange(maxWidth)] for y in xrange(maxHeight)]

    # Add the base square
    angle = i%2
    startX = len(grid[0])/2
    startY = len(grid)/2 - 1
    if angle:
        grid[startY][startX:startX+2] = '/\\'
        grid[startY+1][startX:startX+2] = '\\/'
    else:
        grid[startY][startX+1] = '_'
        grid[startY+1][startX:startX+3] = '|_|'

    for armNum in arms:
        # Determine where this arm starts
        armIdx = armNum + 8*angle;
        armX = [0,2,3,3,2,0,-1,-1,0,1,2,2,1,0,-2,-1][armIdx] + startX
        armY = [0,0,0,2,2,2,1,0,-1,-1,0,1,2,2,0,0][armIdx] + startY

        # Determine the direction it travels
        d = [0,1,1,1,0,-1,-1,-1]
        dirX = [0,1,1,1,0,-1,-1,-1][armIdx%8]
        dirY = [-1,-1,0,1,1,1,0,-1][(armIdx)%8]
        sym = '|/_\\'[armIdx%4]

        # Draw the arm
        for i in xrange(armLength):
            grid[armY][armX] = sym
            armX += dirX
            armY += dirY

    # Increment which arms to draw next
    arms = [(a+1)%8 for a in arms]
    for i in xrange(len(grid)):
        print ''.join(grid[i])
    print ''

Explanation

Pretty simple when it's broken down. First figure out how big of grid is required, then plot the base square or diamond.

Each arm's starting location, symbol and direction is hardcoded in for each of the 8 possible arms for the square and diamond base. Then, drawing them is easy enough.

To rotate everything, I simply switch between the square and diamond base, then increment each of the arms, rotating them clockwise once.

\$\endgroup\$
  • \$\begingroup\$ You can remove the spaces in places like ' ' for to ' 'for', ] for to ]for',8 for to 8for', print '' to print''. \$\endgroup\$ – Rɪᴋᴇʀ Mar 21 '16 at 2:31
  • \$\begingroup\$ Nice! I'm really happy to see an answer to this challenge. \$\endgroup\$ – TNT Mar 22 '16 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.