Dibujar un molinete giratorio

30

¿Recuerdas esos molinetes divertidos que soplas y giran y giran? ¡Codifiquemos uno!

Un molinete tendrá el conjunto de personajes \ | / _dibujando su centro y brazos. Un posible molinete podría verse así:

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

Pero, ¿qué es un molinete que no gira? ¡No es divertido! Podemos hacerlo girar reorganizando los símbolos:

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

El desafío es crear un programa que tome tres enteros y genere un molinete como se especifica a continuación. El primero de ellos es el número de brazos que tiene, el segundo es la longitud de los brazos del molinete, y el tercero es el número de veces que girará un octavo de una revolución en el sentido de las agujas del reloj.

Puede asumir lo siguiente:

  • El número de brazos siempre será 0, 1, 2, 4 u 8.
  • Todos los brazos estarán igualmente separados entre sí.
  • La posición inicial del molinete tendrá su centro así:

     _
    |_|
    
  • Si el número de brazos es 1, puede decidir en qué dirección apunta el brazo.

  • Si el número de brazos es 2, puede decidir hacer que los brazos apunten vertical u horizontalmente.

Puede escribir un programa completo que reciba información a través de STDIN o argumento de línea de comandos, o una función que reciba información a través de argumentos de función. Su programa debe mostrar una secuencia de salidas que muestre el giro del molinete, cada uno separado por al menos una línea vacía. El centro del molinete no debe moverse más de un espacio. Puede generar tantos espacios iniciales y finales como sea necesario.

Aquí hay unos ejemplos:

0 2 1

 _
|_|

/\
\/

1 3 2

|
|
|_
|_|

   /
  /
 /
/\
\/

 _ ___
|_|

2 2 0

   _ __
__|_|

8 4 1

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

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

Este es el código de golf, por lo que gana el código más corto. ¡Buena suerte!

TNT
fuente
¿Puede haber una nueva línea final en la salida?
usandfriends
Se permiten nuevas líneas al final, sin restricciones en cuanto al monto.
TNT
También para el último ejemplo, tiene un espacio adicional antepuesto a cada línea para la primera salida. ¿Podemos tener espacios prepended y finales en la salida?
usandfriends
El número de espacios iniciales en la salida tiene que ver con la posición del centro del molinete, cuya posición no debe cambiar más de un espacio. Si la rotación del molinete hará que un brazo termine hacia la izquierda del centro del molinete más tarde en la salida (como por ejemplo para la entrada 1 3 5y el brazo inicialmente apuntando hacia arriba), se necesitarán espacios en las salidas anteriores para acomodar esto.
TNT

Respuestas:

4

Python 2 535 517 473 468 bytes

¡Ahorró 5 bytes gracias a @Easterly Ink!

Se espera que la entrada esté separada por comas (es decir, numArms, armLength, numRots)

Versión de golf

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])

Versión sin golf

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 ''

Explicación

Bastante simple cuando se descompone. Primero averigüe qué tan grande de la cuadrícula se requiere, luego trace el cuadrado base o el diamante.

La ubicación inicial, el símbolo y la dirección de cada brazo están codificados para cada uno de los 8 brazos posibles para la base cuadrada y de diamante. Entonces, dibujarlos es bastante fácil.

Para rotar todo, simplemente cambio entre la base cuadrada y la base de diamante, luego incremento cada uno de los brazos, girándolos una vez en sentido horario.

Dominic A.
fuente
Puede eliminar los espacios en lugares como ' ' fora' 'for' , ] forto ]for', 8 for to 8for', print ''to print''.
Rɪᴋᴇʀ
¡Agradable! Estoy realmente feliz de ver una respuesta a este desafío.
TNT