p
est une fonction (type classe polymorphe) prenant une permutation comme une liste de Int
s, et une liste imbriquée représentant un tableau multidimensionnel de Int
s.
Appelez as p [2,1] [[10,20,30],[40,50,60]]
, mais si le défaut de type ne réussit pas, vous devrez peut-être ajouter une annotation de type comme :: [[Int]]
(imbriquée de manière appropriée) en donnant le type du résultat.
import Data.List
class P a where p::[Int]->[a]->[a]
instance P Int where p _=id
instance P a=>P[a]where p(x:r)m|n<-p r<$>m,y:z<-sort r=last$n:[p(x:z)<$>transpose n|x>y]
Essayez-le en ligne!
Les défis de golf avec des tableaux imbriqués de profondeur arbitraire sont un peu gênants à Haskell, car le typage statique a tendance à gêner. Alors que les listes Haskell (avec la même syntaxe exacte que dans la description du défi) peuvent être imbriquées très bien, les listes de différentes profondeurs d'imbrication sont de types incompatibles. De plus, les fonctions d'analyse de Haskell standard nécessitent de connaître le type de la valeur que vous essayez d'analyser.
En conséquence, il semble inévitable que le programme doive inclure des déclarations liées au type, qui sont relativement verbeuses. Pour la partie golfée, j'ai décidé de définir une classe de type P
, telle qu'elle p
puisse être polymorphe sur le type du tableau.
Pendant ce temps, le harnais de test du TIO montre un moyen de contourner le problème d'analyse.
Comment ça fonctionne
Pour résumer l'essence de cet algorithme: Il effectue un tri à bulles sur la liste de permutation, transposant les dimensions voisines lorsque les indices de permutation correspondants sont échangés.
Comme indiqué par la class P a
déclaration, dans tous les cas, p
prend deux arguments, une permutation (toujours de type [Int]
) et un tableau.
- La permutation peut être donnée sous la forme dans la description du défi, bien que la façon dont l'algorithme fonctionne, le choix des indices est arbitraire, à l'exception de leur ordre relatif. (Donc, les travaux basés sur 0 et 1.)
- La base
instance P Int
gère les tableaux de la dimension 1, qui p
revient simplement inchangée, car la seule dimension ne peut être mappée qu'à elle-même.
- L'autre
instance P a => P [a]
est défini récursivement, appelant p
avec des sous-réseaux de dimension n afin de le définir pour les tableaux de dimension n + 1 .
p(x:r)m
first appelle p r
récursivement sur chaque élément de m
, donnant un tableau de résultats n
dans lequel toutes les dimensions sauf la première ont été permutées correctement les unes par rapport aux autres.
- La permutation restante qui doit être effectuée
n
est donnée par x:y:z = x:sort r
.
- Si
x<y
alors la première dimension de n
est déjà correctement placée, et n
est simplement renvoyée.
- Si
x>y
, alors la première et la deuxième dimension de n
doivent être échangées, ce qui est fait avec la transpose
fonction. Enfin, p(x:z)
est appliqué récursivement à chaque élément du résultat, garantissant que la première dimension d'origine est transposée à la bonne position.
exec
(enregistrer deux octets) , car c'est une instruction en Python 2.