Obróć listę dwuwymiarową o 45 stopni

22

ZADANIE

Celem jest napisanie programu, który obraca dowolną dwuwymiarową listę o 45 stopni, musi być w stanie to zrobić do 7 * 45 (jednocześnie) przed zwróceniem listy. Lista niekoniecznie będzie kwadratowa lub prostokątna. Musisz podać wynik dla przykładów w swojej odpowiedzi. Musi także działać w przypadkach, których nie ma w przykładach ... kółkach, trójkątach itp. Nie można użyć wcześniej istniejącej funkcji, aby wykonać całą czynność.

Wszystkie listy będą miały co najmniej jedną oś symetrii (N, S, E, W). Wszystkie listy podrzędne należy zakładać jako wyśrodkowane. Listy nieparzyste zostaną przesunięte do lewej, aby prawidłowo wyrównać. Zobacz przerwy 4 w środku listy podrzędnej.

WKŁAD

Twój program użyje zmiennej o nazwie lzawierającej listę oraz zmiennej o nazwie nokreślającej kwotę, którą lista zostanie obrócona (n * 45) ( nzawsze będzie mniejsza niż 7 i może wynosić 0). Będzie musiał zaakceptować lzawieranie list podrzędnych dowolnego typu danych do wydruku (liczba dziesiętna, lista, liczba całkowita, ciąg [] .. itd.), Ale listy podrzędne będą zawierać tylko jeden typ danych na raz.

Nie musisz akceptować danych wejściowych konsoli ani używać standardowego wejścia. Wiersze określające wartości testowe li nnie są uwzględniane w liczbie znaków, ale muszą być zawarte w przesłanym kodzie.

WYDAJNOŚĆ

Twój program musi wydrukować listę w prawidłowej orientacji, NIL może być używany do wypełniania list, jeśli chcesz, ale wypełnianie nie jest konieczne (jednak, jeśli są wypełnione, masz uśmiechniętą twarz). Podlisty nie muszą być wcięte ani oddzielane znakami nowej linii, jak w przykładach.

PRZYKŁADY

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]     ]
Obrzydliwe
źródło
4
Oooch To jest trudne. Wygląda jednak zabawnie!
TheDoctor
1
Dwa pytania: 1) Nie musimy wypełniać list, prawda? 2) Czy naprawdę chcesz, abyśmy obracali listę nrazy, a nie o n45 °? Pytam, ponieważ jestem całkiem pewien, że nie uzyskałbym wyniku z przykładu 3, stosując siedem obrotu o 45 °.
Wrzlprmft
Nie, nie musisz padać. Lista powinna jednak mieć możliwość ułożenia we właściwej orientacji wizualnej, chociaż nie musi być w ten sposób wyprowadzana ... wynik nie będzie zawierał nowych linii. Lista jest obracana o n * 45.
tragiczny

Odpowiedzi:

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]

Wersja bez golfa

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

Wykorzystuje to mnożenie (liczby zespolonej) przez liczbę zespoloną odpowiadającą obrotowi i rozciąganiu. [1,1+1j,1j,1j-1,-1,-1j-1,-1j,1-1j]są liczbami zespolonymi odpowiadającymi wymaganym kątom i przy użyciu najmniejszego współczynnika skalowania, tak że dla wejścia zespolonego z liczbą całkowitą wynikiem jest znów kompleks całkowity.

Wrzlprmft
źródło
1
Próbuję zrozumieć, jak to działa, ale gubię się przy liczbach zespolonych. Czy mogę prosić o wyjaśnienie?
tragiczny
1
@Ourous: Niech x + iy = (x, y), a następnie pomnożąc to przez 1 + i = (1,1), otrzymasz obrót o 45 stopni.
Kyle Kanos
Świetne rozwiązanie. Próbuję go dostosować, aby wstawić również odpowiednie wypełnienie do list wyników, ale nie mam szczęścia. Czy to nietrywialny dodatek?
tkocmathla,
@tkocmathla: Nie testowałem tego, ale próbowałem dodać else: line += [None]po czwartym z ostatniego wiersza.
Wrzlprmft