Zeichnen Sie ein sich drehendes Windrad

30

Erinnerst du dich an die lustigen Windräder, auf denen du bläst und die sich immer wieder drehen? Code eins!

Bei einem Windrad werden die Zeichen in \ | / _der Mitte und auf den Armen angezeigt . Ein mögliches Windrad könnte so aussehen:

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

Aber was ist ein Windrad, das sich nicht dreht? Kein Spaß! Wir können es drehen, indem wir die Symbole neu anordnen:

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

Die Herausforderung besteht darin, ein Programm zu erstellen, das drei Ganzzahlen benötigt und ein Windrad wie unten angegeben ausgibt. Das erste ist die Anzahl der Arme, die es hat, das zweite ist die Länge der Windradarme, und das dritte ist die Häufigkeit, mit der es eine Achtelumdrehung im Uhrzeigersinn dreht.

Sie können folgendes annehmen:

  • Die Anzahl der Arme wird immer 0, 1, 2, 4 oder 8 sein.
  • Alle Arme sind gleichmäßig voneinander beabstandet.
  • Die anfängliche Position des Windrads hat die Mitte wie folgt:

     _
    |_|
    
  • Wenn die Anzahl der Arme 1 ist, können Sie entscheiden, in welche Richtung der Arm zeigt.

  • Wenn die Anzahl der Arme 2 beträgt, können Sie festlegen, dass die Arme vertikal oder horizontal zeigen.

Sie können ein vollständiges Programm schreiben, das Eingaben über STDIN oder ein Befehlszeilenargument oder eine Funktion, die Eingaben über Funktionsargumente erhält, akzeptiert. Ihr Programm muss eine Folge von Ausgaben anzeigen, die das Durchdrehen des Windrads anzeigt, wobei jede durch mindestens eine Leerzeile getrennt ist. Die Mitte des Windrads sollte sich nicht um mehr als eine Stelle bewegen. Sie können beliebig viele führende und nachfolgende Leerzeichen ausgeben.

Hier sind einige Beispiele:

0 2 1

 _
|_|

/\
\/

1 3 2

|
|
|_
|_|

   /
  /
 /
/\
\/

 _ ___
|_|

2 2 0

   _ __
__|_|

8 4 1

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

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

Dies ist Codegolf, also gewinnt der kürzeste Code. Viel Glück!

TNT
quelle
Kann die Ausgabe einen nachgestellten Zeilenumbruch enthalten?
Usandfriends
Hinterlegte Zeilenumbrüche sind ohne Mengenbeschränkung zulässig.
TNT
Auch für das letzte Beispiel steht vor jeder Zeile ein zusätzlicher Platz für die erste Ausgabe. Können wir Leerzeichen in der Ausgabe voranstellen und nachstellen?
Usandfriends
Die Anzahl der führenden Leerzeichen in der Ausgabe hat mit der Position der Mitte des Windrads zu tun, deren Position sich nicht um mehr als ein Leerzeichen verschieben sollte. Wenn die Drehung des Windrads dazu führt, dass ein Arm später in der Ausgabe links von der Mitte des Windrads endet (z. B. bei der Eingabe 1 3 5und wenn der Arm anfänglich nach oben zeigt), müssen Leerzeichen in früheren Ausgaben vorangestellt werden, um dies zu berücksichtigen.
TNT

Antworten:

4

Python 2 535 517 473 468 Bytes

5 Bytes gespart dank @Easterly Ink!

Eingabe wird voraussichtlich durch Kommas getrennt (z. B. numArms, armLength, numRots)

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

Erläuterung

Ziemlich einfach, wenn es kaputt ist. Stellen Sie zunächst fest, wie viel Raster erforderlich ist, und zeichnen Sie dann das Basisquadrat oder den Diamanten.

Die Startposition, das Symbol und die Richtung jedes Arms sind für jeden der 8 möglichen Arme für die Quadrat- und Diamantbasis fest codiert. Dann ist es einfach genug, sie zu zeichnen.

Um alles zu drehen, wechsle ich einfach zwischen der quadratischen und der diamantischen Basis, inkrementiere dann jeden der Arme und drehe sie einmal im Uhrzeigersinn.

Dominic A.
quelle
Sie können die Räume in Orten wie entfernen ' ' forzu ' 'for', ] forzu ]for', 8 zu 8for', print ''zu print''.
Freitag,
Nett! Ich freue mich sehr, eine Antwort auf diese Herausforderung zu sehen.
TNT