Dreht eine zweidimensionale Liste um 45 Grad

22

AUFGABE

Das Ziel ist es, ein Programm zu schreiben, das eine zweidimensionale Liste um 45 Grad dreht. Es muss in der Lage sein, dies bis zu 7 * 45 (auf einmal) zu tun, bevor die Liste zurückgegeben wird. Die Liste muss nicht quadratisch oder rechteckig sein. Sie müssen die Ausgabe für die Beispiele in Ihre Antwort aufnehmen. Es muss auch für Fälle funktionieren, die nicht in den Beispielen aufgeführt sind ... Kreise, Dreiecke usw. Sie können keine bereits vorhandene Funktion verwenden, um das Ganze zu erledigen.

Alle Listen haben mindestens eine Symmetrieachse (N, S, E, W). Alle Unterlisten sind als zentriert anzunehmen. Gerade-Ungerade-Listen werden zur korrekten Ausrichtung nach links verschoben. In Beispiel 4 finden Sie Lücken in der Mitte einer Unterliste.

EINGANG

Ihr Programm verwendet eine Variable lmit dem Namen, die die Liste enthält, und eine Variable mit dem Namen n, die den Betrag angibt, um den die Liste gedreht wird (n * 45) ( nwird immer kleiner als 7 sein und kann 0 sein). Es muss zulassen l, dass Unterlisten eines beliebigen druckbaren Datentyps (Dezimalzahl, Liste, Ganzzahl, Zeichenfolge [] .. usw.) enthalten sind. Unterlisten enthalten jedoch jeweils nur einen Datentyp.

Sie müssen keine Konsolen-Eingaben akzeptieren oder stdin verwenden. Die Zeilen, die die Testwerte von lund nangeben, sind nicht in der Zeichenanzahl enthalten, müssen jedoch im übermittelten Code enthalten sein.

AUSGABE

Ihr Programm muss die Liste in der richtigen Ausrichtung drucken. NIL kann zum Auffüllen von Listen verwendet werden, wenn Sie dies wünschen. Ein Auffüllen ist jedoch nicht erforderlich. Unterlisten müssen nicht wie in den Beispielen eingerückt oder durch Zeilenumbrüche getrennt werden.

Beispiele

1

IN
l=
[[0 , 1 , 2],
 [3 , 4 , 5],
 [6 , 7 , 8]]
n=1

OUT
[    [0],
   [3 , 1],
 [6 , 4 , 2],
   [7 , 5],
     [8]    ]

2

IN
l=
[[a , b , c , d],
 [e , f , g , h]]
n=2

OUT
[[e , a],
 [f , b],
 [c , g],
 [h , d]]

3

IN
l=
[[A , B , C , D , E , F],
     [G , H , I , J],
         [K , L],
         [0 , 8],
         [M , N],
     [O , P , Q , R],
 [S , T , U , V , W , X]]
n=7

OUT
[          [F],
         [E],
       [D , J],
     [C , I],
   [B , H , L],
 [A , G , K , 8],
           [0 , N , R , X],
             [M , Q , W],
               [P , V],
             [O , U],
               [T],
             [U]          ]

4

IN
l=
[[9 , 8 , 7 , 6],
     [5],
 [4 , 3 , 2 , 1],
     [0]        ]
n=3

OUT
[  [0 , 4],
     [3],
   [2 , 5 , 9],
 [1 ,NIL, 8],
       [7],
     [6],     ]

5

IN
l=
[    [Q],
 [X ,NIL, Y],
     [Z]    ]
n=2

OUT
[    [X],
 [Z ,NIL, Q],
     [Y]     ]
Οurous
quelle
4
Oooh. Das ist schwer. Sieht aber lustig aus!
TheDoctor
1
Zwei Fragen: 1) Wir müssen keine Listen auffüllen, oder? 2) Wollen Sie wirklich, dass wir die Listenzeiten drehen nund nicht um n· 45 °? Ich frage, weil ich ziemlich sicher bin, dass ich das Ergebnis von Beispiel 3 nicht durch Anwendung von sieben 45 ° -Drehungen erhalten würde.
Wrzlprmft
Nein, Sie müssen nicht auffüllen. Die Liste sollte jedoch in der richtigen visuellen Ausrichtung angeordnet werden können, obwohl sie nicht auf diese Weise ausgegeben werden muss. Die Ausgabe enthält keine Zeilenumbrüche. Die Liste wird um n * 45 gedreht.
Οurous

Antworten:

8

Python - 234 201

# example for defining lists and n
l=[[1,2,3,4],
     [5],
   [6,7,8,9]]
n=1

# counting code
j=1j
m=max(map(len,l))+len(l)
M=range(-m,m)
e=enumerate
d=[[v for x in M for i,u in e(l)for k,v in e(u)if[1,1+j,j,j-1,-1,-j-1,-j,1-j][n]*(k-(len(u)-1)/2+j*i)==x+y*j]for y in M]
print[x for x in d if x]

Ungolfed Version

rotation = [1,1+1j,1j,1j-1,-1,-1j-1,-1j,1-1j][n]
m = max(map(len,l))+len(l)
output = []
for y in range(-m,m):
    line = []
    for x in range(-m,m):
        for i,sublist in enumerate(l):
            for k,entry in enumerate(sublist):
                if rotation * ( k-(len(sublist)-1)/2 + i*1j ) == x + y*1j:
                    line += [entry]
    if line != []:
        output += [line]
print output

Hierbei wird verwendet, dass die Multiplikation (einer komplexen Zahl) mit einer komplexen Zahl dem Drehen und Strecken entspricht. [1,1+1j,1j,1j-1,-1,-1j-1,-1j,1-1j]sind komplexe Zahlen, die den erforderlichen Winkeln entsprechen und den kleinsten Skalierungsfaktor verwenden, so dass für eine ganzzahlige komplexe Eingabe die Ausgabe wiederum ganzzahlig komplex ist.

Wrzlprmft
quelle
1
Ich versuche zu verstehen, wie das funktioniert, aber ich verliere mich bei den komplexen Zahlen. Könnte ich um eine Erklärung bitten?
Οurous
1
@Unser: Lassen Sie x + iy = (x, y) und multiplizieren Sie dies mit 1 + i = (1,1). Sie erhalten eine Drehung um 45 Grad.
Kyle Kanos
Großartige Lösung. Ich versuche, es anzupassen, um auch den entsprechenden Abstand in die Ausgabelisten einzufügen, aber ich habe nicht viel Glück. Ist das eine nicht triviale Ergänzung?
Tkocmathla
@tkocmathla: Ich habe das nicht getestet, aber versuche es else: line += [None]nach dem vierten von der letzten Zeile hinzuzufügen .
Wrzlprmft