Dessinez un moulinet tournant

30

Rappelez-vous ces moulins à vent amusants sur lesquels vous soufflez et ils tournent en rond? Codons-en un!

Un moulin à vent aura l'ensemble de caractères \ | / _dessinant son centre et ses bras. Un moulinet possible pourrait ressembler à ceci:

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

Mais qu'est-ce qu'un moulinet qui ne tourne pas? Pas drôle! Nous pouvons le faire tourner en réorganisant les symboles:

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

Le défi est de créer un programme qui prend trois entiers et génère un moulinet comme spécifié ci-dessous. Le premier d'entre eux est le nombre de bras dont il dispose, le second est la longueur des bras du moulinet et le troisième est le nombre de fois qu'il tournera d'un huitième de tour dans le sens des aiguilles d'une montre.

Vous pouvez supposer ce qui suit:

  • Le nombre d'armes sera toujours 0, 1, 2, 4 ou 8.
  • Tous les bras seront également espacés les uns des autres.
  • La position initiale du moulinet aura son centre comme ceci:

     _
    |_|
    
  • Si le nombre de bras est 1, vous pouvez décider dans quelle direction le bras pointe.

  • Si le nombre de bras est de 2, vous pouvez décider de faire pointer les bras verticalement ou horizontalement.

Vous pouvez écrire un programme complet qui accepte des entrées via STDIN ou un argument de ligne de commande, ou une fonction qui accepte des entrées via des arguments de fonction. Votre programme doit afficher une séquence de sorties qui montre la rotation du moulinet, chacune séparée par au moins une ligne vide. Le centre du moulinet ne doit pas bouger de plus d'un espace. Vous pouvez générer autant d'espaces de début et de fin que nécessaire.

Voici quelques exemples:

0 2 1

 _
|_|

/\
\/

1 3 2

|
|
|_
|_|

   /
  /
 /
/\
\/

 _ ___
|_|

2 2 0

   _ __
__|_|

8 4 1

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

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

C'est le golf de code, donc le code le plus court gagne. Bonne chance!

TNT
la source
Peut-il y avoir une nouvelle ligne de fin dans la sortie?
usandfriends
Les sauts de ligne sont autorisés, sans restriction quant au montant.
TNT
Pour le dernier exemple également, vous disposez d'un espace supplémentaire ajouté à chaque ligne pour la première sortie. Pouvons-nous avoir des espaces préfixés et suiveurs dans la sortie?
usandfriends
Le nombre d'espaces de tête dans la sortie a à voir avec la position du centre du moulinet, dont la position ne doit pas changer de plus d'un espace. Si la rotation du moulinet fait en sorte qu'un bras se retrouve à gauche du centre du moulinet plus tard dans la sortie (comme pour l'entrée 1 3 5et le bras pointant initialement vers le haut), des espaces devront être ajoutés aux sorties précédentes pour s'adapter à cela.
TNT

Réponses:

4

Python 2 535 517 473 468 octets

5 octets enregistrés grâce à @Easterly Ink!

L'entrée devrait être séparée par des virgules (c.-à-d. NumArms, armLength, numRots)

Version golfée

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

Version non golfée

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

Explication

Assez simple quand il est en panne. Déterminez d'abord la taille de la grille requise, puis tracez le carré de base ou le diamant.

L'emplacement de départ, le symbole et la direction de chaque bras sont codés en dur pour chacun des 8 bras possibles pour la base carrée et diamantée. Ensuite, les dessiner est assez facile.

Pour tout faire pivoter, je passe simplement de la base carrée à la base en diamant, puis j'incrémente chacun des bras, en les faisant tourner une fois dans le sens horaire.

Dominic A.
la source
Vous pouvez supprimer les espaces dans des endroits tels que ' ' forto ' 'for', ] forto ]for', 8 for to 8for', print ''to print''.
Rɪᴋᴇʀ
Agréable! Je suis vraiment heureux de voir une réponse à ce défi.
TNT