Desenhe um cata-vento giratório

30

Lembra-se daqueles cata-ventos divertidos que você assopra e eles giram sem parar? Vamos codificar um!

Um cata-vento terá o conjunto de caracteres \ | / _desenhando seu centro e braços. Um possível cata-vento poderia ser assim:

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

Mas o que é um cata-vento que não gira? Não é divertido! Podemos fazê-lo girar reorganizando os símbolos:

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

O desafio é criar um programa que use três números inteiros e produza um cata-vento, conforme especificado abaixo. O primeiro deles é o número de braços que possui, o segundo é o comprimento dos braços do cata-vento e o terceiro é o número de vezes que ele gira um oitavo de uma rotação no sentido horário.

Você pode assumir o seguinte:

  • O número de armas sempre será 0, 1, 2, 4 ou 8.
  • Todos os braços serão igualmente espaçados um do outro.
  • A posição inicial do cata-vento terá seu centro assim:

     _
    |_|
    
  • Se o número de braços for 1, você pode decidir em qual direção o braço aponta.

  • Se o número de braços for 2, você pode decidir apontar os braços na vertical ou na horizontal.

Você pode escrever um programa completo que receba entrada por meio de STDIN ou argumento da linha de comando ou uma função que aceita entrada por argumentos de função. Seu programa deve mostrar uma sequência de saídas que mostra a rotação do cata-vento, cada uma separada por pelo menos uma linha vazia. O centro do cata-vento não deve se mover em mais de um espaço. Você pode gerar quantos espaços iniciais e finais forem necessários.

aqui estão alguns exemplos:

0 2 1

 _
|_|

/\
\/

1 3 2

|
|
|_
|_|

   /
  /
 /
/\
\/

 _ ___
|_|

2 2 0

   _ __
__|_|

8 4 1

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

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

Isso é código de golfe, então o código mais curto vence. Boa sorte!

TNT
fonte
Pode haver uma nova linha à direita na saída?
usandfriends
Novas linhas à direita são permitidas, sem restrições quanto ao valor.
TNT
Também para o último exemplo, você tem um espaço extra anexado a cada linha para a primeira saída. Podemos ter espaços precedentes e finais na saída?
usandfriends
O número de espaços à esquerda na saída tem a ver com a posição do centro do cata-vento, cuja posição não deve mudar em mais de um espaço. Se a rotação do cata-vento fizer com que um braço termine à esquerda do centro do cata-vento mais tarde na saída (como na entrada 1 3 5e o braço inicialmente apontando para cima), os espaços precisarão ser anexados nas saídas anteriores para acomodar isso.
TNT

Respostas:

4

Python 2 535 517 473 468 bytes

Guardado 5 bytes graças a @Easterly Ink!

É esperado que a entrada seja separada por vírgula (ou seja, numArms, armLength, numRots)

Versão Golfed

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

Versão Ungolfed

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

Explicação

Muito simples quando está quebrado. Primeiro, calcule o tamanho da grade necessária e plote o quadrado base ou o diamante.

A localização, símbolo e direção de cada braço são codificados para cada um dos 8 braços possíveis para a base quadrada e de diamante. Então, desenhá-los é fácil.

Para girar tudo, eu simplesmente alterno entre a base quadrada e a base de diamante e, em seguida, incremento cada um dos braços, girando-os no sentido horário uma vez.

Dominic A.
fonte
Você pode remover os espaços em locais como ' ' forpara ' 'for', ] forpara ]for', 8 para para 8for', print ''para print''.
Rɪᴋᴇʀ
Agradável! Estou muito feliz em ver uma resposta para este desafio.
TNT