Narysuj Wirujący Wiatraczek

30

Pamiętasz te zabawne wiatraczki, które dmuchasz i kręcą się w kółko? Kodujmy jeden!

Wiatraczek będzie miał zestaw znaków \ | / _rysujących jego środek i ramiona. Jeden z możliwych wiatraczek może wyglądać następująco:

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

Ale czym jest wiatraczek, który się nie kręci? Nie ma zabawy! Możemy go obrócić, zmieniając symbole:

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

Wyzwanie polega na stworzeniu programu, który pobiera trzy liczby całkowite i generuje wiatraczek, jak określono poniżej. Pierwsze z nich to liczba ramion, jakie ma, drugie to długość ramion wiatraczka, a trzecie to liczba obrotów, w których obróci się o jedną ósmą obrotu w prawo.

Możesz założyć, co następuje:

  • Liczba ramion zawsze będzie wynosić 0, 1, 2, 4 lub 8.
  • Wszystkie ramiona będą w równych odstępach od siebie.
  • Początkowa pozycja koła zębatego będzie miała swój środek w następujący sposób:

     _
    |_|
    
  • Jeśli liczba ramion wynosi 1, możesz zdecydować, w którym kierunku wskazane jest ramię.

  • Jeśli liczba ramion wynosi 2, możesz zdecydować, aby ramiona były skierowane pionowo lub poziomo.

Możesz napisać pełny program, który pobiera dane wejściowe za pomocą argumentu STDIN lub wiersza polecenia, lub funkcję, która pobiera dane wejściowe za pomocą argumentów funkcji. Twój program musi pokazywać sekwencję wyjść, która pokazuje obracanie się wiatraczka, każde oddzielone co najmniej jedną pustą linią. Środek wiatraczka nie powinien poruszać się o więcej niż jedno pole. Możesz wydrukować tyle spacji początkowych i końcowych, ile potrzeba.

Oto kilka przykładów:

0 2 1

 _
|_|

/\
\/

1 3 2

|
|
|_
|_|

   /
  /
 /
/\
\/

 _ ___
|_|

2 2 0

   _ __
__|_|

8 4 1

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

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

To jest kod golfowy, więc wygrywa najkrótszy kod. Powodzenia!

TNT
źródło
Czy w wyniku może być końcowy znak nowej linii?
usandfriends
Końcowe znaki nowej linii są dozwolone, bez ograniczeń dotyczących kwoty.
TNT
Również w ostatnim przykładzie do każdego wiersza jest wstawiona dodatkowa spacja dla pierwszego wiersza. Czy możemy mieć poprzedzające i końcowe spacje na wyjściu?
usandfriends
Liczba wiodących odstępów na wyjściu ma związek z położeniem środka koła zębatego, którego położenie nie powinno przesuwać się o więcej niż jedną przestrzeń. Jeśli obrót koła zębatego spowoduje, że ramię wyląduje na lewo od środka koła zębatego później na wyjściu (np. Na wejściu 1 3 5i ramię początkowo skierowane w górę), należy wcześniej wstawić spacje, aby to uwzględnić.
TNT

Odpowiedzi:

4

Python 2535517 473 468 bajtów

Zaoszczędź 5 bajtów dzięki @Easterly Ink!

Dane wejściowe powinny być oddzielone przecinkami (tj. NumArms, armLength, numRots)

Wersja golfowa

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

Wersja bez golfa

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

Wyjaśnienie

Całkiem proste, gdy się zepsuje. Najpierw dowiedz się, ile potrzeba siatki, a następnie narysuj kwadrat podstawowy lub diament.

Początkowa lokalizacja każdego ramienia, symbol i kierunek są zakodowane na stałe dla każdego z 8 możliwych ramion dla podstawy kwadratowej i diamentowej. Następnie ich narysowanie jest dość łatwe.

Aby wszystko obrócić, po prostu przełączam między kwadratową i diamentową podstawą, a następnie zwiększam każde z ramion, obracając je raz w prawo.

Dominic A.
źródło
Można usunąć spacje w miejscach, jak ' ' fordo ' 'for', ] fordo ]for', do 8 do 8for', print ''do print''.
Rɪᴋᴇʀ
Miły! Bardzo się cieszę, widząc odpowiedź na to wyzwanie.
TNT