Faire pivoter une liste bidimensionnelle de 45 degrés

22

TÂCHE

Le but est d'écrire un programme qui fait pivoter n'importe quelle liste bidimensionnelle de 45 degrés, il doit pouvoir le faire jusqu'à 7 * 45 (à la fois) avant de retourner la liste. La liste ne sera pas nécessairement carrée ou rectangulaire. Vous devez inclure la sortie des exemples dans votre réponse. Cela doit également fonctionner pour les cas qui ne sont pas dans les exemples ... cercles, triangles, etc. Vous ne pouvez pas utiliser une fonction préexistante pour faire le tout.

Toutes les listes auront au moins un axe de symétrie (N, S, E, W). Toutes les sous-listes doivent être considérées comme alignées au centre. Les listes paires-impaires se déplaceront vers la gauche pour s'aligner correctement. Voir l'exemple 4 pour les lacunes au milieu d'une sous-liste.

CONTRIBUTION

Votre programme utilisera une variable nommée lcontenant la liste et une variable nommée nspécifiant la quantité de rotation de la liste (n * 45) ( nsera toujours inférieure à 7 et peut être 0). Il devra accepter de lcontenir des sous-listes de tout type de données imprimables (décimal, List, int, String [] .. etc.), mais les sous-listes ne contiendront qu'un seul type de données à la fois.

Vous n'avez pas besoin d'accepter l'entrée de la console ou d'utiliser stdin. Les lignes spécifiant les valeurs de test de let nne sont pas incluses dans le nombre de caractères, mais doivent être incluses dans le code soumis.

SORTIE

Votre programme doit imprimer la liste dans le bon sens, NIL peut être utilisé pour remplir les listes si vous le souhaitez, mais le remplissage n'est pas nécessaire (vous obtenez un visage souriant si elles sont rembourrées, cependant). Les sous-listes n'ont pas besoin d'être mises en retrait ou séparées par des retours à la ligne comme dans les exemples.

EXEMPLES

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
la source
4
Oooh. C'est difficile. Ça a l'air amusant, cependant!
TheDoctor
1
Deux questions: 1) Nous n'avons pas à remplir les listes, non? 2) Voulez-vous vraiment que nous tournions la liste net non pas de n· 45 °? Je pose la question parce que je suis assez certain que je n'obtiendrais pas le résultat de l'exemple 3 en appliquant sept rotations à 45 °.
Wrzlprmft
Non, vous n'avez pas besoin de rembourrer. La liste devrait cependant pouvoir être arrangée dans la bonne orientation visuelle, bien qu'elle ne doive pas être sortie de cette façon ... la sortie n'aura pas de nouvelle ligne. La liste est tournée de n * 45.
3urous

Réponses:

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]

Version non golfée

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

Cela utilise cette multiplication (d'un nombre complexe) par un nombre complexe correspondant à la rotation et à l'étirement. [1,1+1j,1j,1j-1,-1,-1j-1,-1j,1-1j]sont des nombres complexes correspondant aux angles requis et utilisant le plus petit facteur d'échelle de sorte que pour une entrée complexe entière, la sortie soit à nouveau complexe entière.

Wrzlprmft
la source
1
J'essaie de comprendre comment cela fonctionne, mais je me perds devant les chiffres complexes. Puis-je demander une explication?
Mayurous
1
@Ourous: Soit x + iy = (x, y), puis en multipliant cela par 1 + i = (1,1), vous obtenez une rotation de 45 degrés.
Kyle Kanos
Excellente solution. J'essaie de l'adapter pour insérer également le rembourrage approprié dans les listes de sortie, mais je n'ai pas beaucoup de chance. Est-ce un ajout non trivial?
tkocmathla
@tkocmathla: Je n'ai pas testé cela, mais essayez d'ajouter else: line += [None]après le quatrième de la dernière ligne.
Wrzlprmft