Rotar una lista bidimensional en 45 grados

22

TAREA

El objetivo es escribir un programa que rote cualquier lista bidimensional en 45 grados, debe poder hacerlo hasta 7 * 45 (a la vez) antes de devolver la lista. La lista no será necesariamente cuadrada o rectangular. Debe incluir la salida de los ejemplos en su respuesta. También debe funcionar para casos que no están en los ejemplos ... círculos, triángulos, etc. No puede usar una función preexistente para hacer todo.

Todas las listas tendrán al menos un eje de simetría (N, S, E, W). Se debe suponer que todas las sublistas están alineadas al centro. Las listas pares e impares se desplazarán a la izquierda para alinearse correctamente. Ver ejemplo 4 para huecos en el medio de una sublista.

ENTRADA

Su programa usará una variable llamada que lcontiene la lista, y una variable llamada que nespecifica la cantidad que se rotará la lista (n * 45) ( nsiempre será menor que 7 y puede ser 0). Tendrá que aceptar que lcontenga sublistas de cualquier tipo de datos imprimibles (decimal, List, int, String [] .. etc.), pero las sublistas solo contendrán un tipo de datos a la vez.

No es necesario aceptar la entrada de la consola o usar stdin. Las líneas que especifican los valores de prueba de ly nno se incluyen en el recuento de caracteres, pero deben incluirse en el código enviado.

SALIDA

Su programa debe imprimir la lista en la orientación correcta, NIL puede usarse para rellenar listas si lo desea, pero el relleno no es necesario (sin embargo, obtendrá una cara sonriente si están rellenadas). Las sublistas no tienen que estar sangradas o separadas por líneas nuevas como en los ejemplos.

EJEMPLOS

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

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

OUT
[    [X],
 [Z ,NIL, Q],
     [Y]     ]
Οurous
fuente
44
Oooh Eso es duro. ¡Parece divertido!
TheDoctor
1
Dos preguntas: 1) No tenemos que rellenar listas, ¿verdad? 2) ¿Realmente quiere que giremos los ntiempos de la lista y no n· 45 °? Pregunto porque estoy bastante seguro de que no obtendría el resultado del ejemplo 3 aplicando siete rotaciones de 45 °.
Wrzlprmft
No, no tienes que rellenar. Sin embargo, la lista debe poder organizarse en la orientación visual correcta, aunque no es necesario que se envíe de esa manera ... la salida no tendrá nuevas líneas. La lista se rota por n * 45.
Precioso

Respuestas:

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]

Versión sin golf

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

Esto usa que la multiplicación (de un número complejo) por un número complejo corresponde a rotación y estiramiento. [1,1+1j,1j,1j-1,-1,-1j-1,-1j,1-1j]son números complejos que corresponden a los ángulos requeridos y usan el factor de escala más pequeño de tal manera que para una entrada compleja entera la salida es nuevamente compleja entera.

Wrzlprmft
fuente
1
Estoy tratando de entender cómo funciona esto, pero me pierdo en los números complejos. ¿Puedo pedir una explicación?
Precioso
1
@Ourous: Sea x + iy = (x, y), luego multiplique esto por 1 + i = (1,1), obtendrá una rotación de 45 grados.
Kyle Kanos
Gran solución Estoy tratando de adaptarlo para insertar también el relleno apropiado en las listas de salida, pero no tengo mucha suerte. ¿Es eso una adición no trivial?
tkocmathla
@tkocmathla: No probé esto, pero intente agregar else: line += [None]después del cuarto de la última línea.
Wrzlprmft