Gire uma lista bidimensional em 45 graus


22

TAREFA

O objetivo é escrever um programa que gire qualquer lista bidimensional em 45 graus; ele deve ser capaz de fazer isso até 7 * 45 (de uma vez) antes de retornar a lista. A lista não será necessariamente quadrada ou retangular. Você deve incluir a saída para os exemplos em sua resposta. Também deve funcionar para casos que não estão nos exemplos ... círculos, triângulos etc. Você não pode usar uma função preexistente para fazer a coisa toda.

Todas as listas terão pelo menos um eixo de simetria (N, S, E, W). Todas as sublistas devem ser assumidas como alinhadas ao centro. As listas ímpares serão deslocadas para a esquerda para alinhar corretamente. Veja o exemplo 4 para lacunas no meio de uma sub-lista.

ENTRADA

Seu programa usará uma variável denominada lcontendo a lista e uma variável denominada nespecificando a quantidade que a lista será rotacionada (n * 45) ( nsempre será menor que 7 e pode ser 0). Ele precisará aceitar lsublistas de qualquer tipo de dados imprimíveis (decimal, Lista, int, String [] .. etc), mas as sublistas conterão apenas um tipo de dados por vez.

Você não precisa aceitar a entrada do console ou usar stdin. As linhas que especificam os valores de teste le nnão estão incluídas na contagem de caracteres, mas devem ser incluídas no código enviado.

SAÍDA

Seu programa deve imprimir a lista na orientação correta; o NIL pode ser usado para preencher listas, se você desejar, mas o preenchimento não é necessário (você recebe uma carinha sorridente, se forem preenchidas). As sub-listas não precisam ser recuadas ou separadas por novas linhas, como nos exemplos.

EXEMPLOS

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

4
Oooh. Isso é difícil. Parece divertido, no entanto!
TheDoctor

1
Duas perguntas: 1) Não precisamos preencher listas, certo? 2) Deseja realmente rodar a lista nvezes e não em n· 45 °? Estou perguntando, porque tenho certeza de que não obteria o resultado do exemplo 3 aplicando sete rotações de 45 °.
Wrzlprmft

Não, você não precisa preencher. A lista deve, no entanto, poder ser organizada na orientação visual correta, embora não precise ser produzida dessa maneira ... a saída não terá novas linhas. A lista é girada por n * 45.
Οurous

Respostas:


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]

Versão Ungolfed

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

Isso usa que a multiplicação (de um número complexo) por um número complexo corresponde a rotação e alongamento. [1,1+1j,1j,1j-1,-1,-1j-1,-1j,1-1j]são números complexos que correspondem aos ângulos necessários e usam o menor fator de escala, de modo que, para uma entrada de complexo inteiro, a saída é novamente um complexo inteiro.


1
Estou tentando entender como isso funciona, mas me perco nos números complexos. Eu poderia pedir uma explicação?
Οurous

1
@Ourous: Seja x + iy = (x, y), multiplicando por 1 + i = (1,1), obtendo uma rotação de 45 graus.
Kyle Kanos #

Ótima solução. Estou tentando adaptá-lo para também inserir o preenchimento apropriado nas listas de saída, mas não estou tendo muita sorte. Isso é uma adição não trivial?
tkocmathla

@tkocmathla: Eu não testei isso, mas tente adicionar else: line += [None]após o quarto da última linha.
Wrzlprmft
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.