Une danse aux multiples dimensions

19

Défi

Étant donné un ntableau dimensionnel d'entiers et une permutation des premiers nnombres naturels, permutez les dimensions du tableau en conséquence.

Détails

Ce défi est inspiré des MATLAB permute. démonstration La permutation est donnée sous la forme d'une liste d'entiers, par exemple, les [1,3,2]moyens 1 sont mappés sur 1, 2 sont mappés sur 3 et 3 sont mappés sur 2 (ici, la ie entrée correspond à la valeur imappée). Mais vous pouvez utiliser d'autres formats pratiques, par exemple sous forme de cycles ou de fonction. Si cela est plus pratique, vous pouvez également utiliser l'indexation basée sur 0.

Le tableau peut être supposé être un tableau "rectangulaire" m1 x m2 x ... x mncomplet (c'est-à-dire que vous pouvez supposer qu'il n'est pas irrégulier / irrégulier ).

Vous pouvez supposer que ce nn'est pas trop grand, car de nombreuses langues ont une limite du nombre de dimensions dans un tableau imbriqué.

Si votre langue ne prend pas en charge les tableaux multidimensionnels, vous pouvez également prendre une chaîne qui représente le tableau en entrée.

Exemples

  • Tout ntableau à dimensions avec la permutation d'identité [1,2,3,...,n]sera inchangé.
  • Le tableau [[10,20,30],[40,50,60]]avec la permutation [2,1]est mappé [[10,40],[20,50],[30,60]].
  • Le tableau [[[1,2],[3,4]],[[5,6],[7,8]]]avec la permutation [2,3,1]est mappé [[[1,3],[5,7]],[[2,4],[6,8]]].
flawr
la source

Réponses:

9

Haskell , 168 octets

pest une fonction (type classe polymorphe) prenant une permutation comme une liste de Ints, et une liste imbriquée représentant un tableau multidimensionnel de Ints.

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 ppuisse ê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 adéclaration, dans tous les cas, pprend 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 Intgère les tableaux de la dimension 1, qui previent 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 pavec des sous-réseaux de dimension n afin de le définir pour les tableaux de dimension n + 1 .
    • p(x:r)mfirst appelle p rrécursivement sur chaque élément de m, donnant un tableau de résultats ndans 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 nest donnée par x:y:z = x:sort r.
    • Si x<yalors la première dimension de nest déjà correctement placée, et nest simplement renvoyée.
    • Si x>y, alors la première et la deuxième dimension de ndoivent être échangées, ce qui est fait avec la transposefonction. 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.
Ørjan Johansen
la source
3

Python 2 , 312 octets

Cela utilise l'indexation 0 pour la permutation

from numpy import*
from itertools import*
z=range
def f(i,r):
	l=array(i).shape;R={b:a for a,b in enumerate(r)};r=len(r);m=eval('['*r+'0'+q('for k in z(l[R[%s]])]',r-1,-1,-1))
	for d in product(*[z(p) for p in l]):exec'm'+q('[d[R[%s]]]',r)+'=i'+q('[d[%s]]',r)
	return m
q=lambda s,*j:''.join(s%(j)for j in z(*j))

Essayez-le en ligne!

-2 octets grâce à @Jonathan Frech.

fireflame241
la source
Vous n'avez pas besoin de parenthèses pour appeler exec (enregistrer deux octets) , car c'est une instruction en Python 2.
Jonathan Frech
Il y a aussi un espace superflu dans z(p) for.
Jonathan Frech
1
Utilisé map(z,l), s%jet printpour 301 octets –– Essayez-le en ligne!
M. Xcoder
3

Python 2 , 41 25 octets

import numpy
numpy.einsum

Essayez-le en ligne!

Le vecteur de permutation pest donné sous forme d'une chaîne de lettres. Ainsi , [2,3,1]on peut donner comme 'bca'.

Merci à @EriktheOutgolfer économisé 16 octets!

rahnema1
la source
Cela prend-il en charge plus de 26 dimensions?
Erik the Outgolfer
En fait, pas plus de 52 dimensions: majuscule + minuscule.
rahnema1
2

JavaScript (ES6), 136 132 octets

(a,p,v=[],r=[],g=(a,[d,...p],_,h=(r,[i,...v])=>1/v[0]?h(r[i]=r[i]||[],v):r[i]=a)=>1/d?a.map((e,i)=>g(e,p,v[d]=i)):h(r,v))=>g(a,p)&&r

0 indexé. Explication: gitère récursivement sur le tableau en acréant un tableau vd'index réorganisé à l'aide de la permutation p. Une fois pépuisé, hpuis insère récursivement l'élément dans le tableau de résultats en rutilisant les indices permutés.

Neil
la source