Una danza de muchas dimensiones

19

Desafío

Dada una nmatriz dimensional de enteros y una permutación de los primeros nnúmeros naturales, permuta las dimensiones de la matriz en consecuencia.

Detalles

Este desafío está inspirado en los MATLAB permute. demostración La permutación se proporciona como una lista de enteros, por ejemplo, [1,3,2]significa que 1 se asigna a 1, 2 se asigna a 3 y 3 se asigna a 2 (aquí la ientrada th es el valor al que ise asigna). Pero puede usar otros formatos que sean convenientes, por ejemplo, como ciclos o como una función. Si es más conveniente, también puede usar la indexación basada en 0.

Se puede suponer que la matriz es una matriz "rectangular" m1 x m2 x ... x mncompleta (es decir, se puede suponer que no es irregular / irregular ).

Puede suponer que nno es demasiado grande, ya que muchos idiomas tienen un límite del número de dimensiones en una matriz anidada.

Si su idioma no admite matrices multidimensionales, también puede tomar una cadena que represente la matriz como entrada.

Ejemplos

  • Cualquier nmatriz dimensional con la permutación de identidad no [1,2,3,...,n]cambiará.
  • La matriz [[10,20,30],[40,50,60]]con la permutación [2,1]se asigna a [[10,40],[20,50],[30,60]].
  • La matriz [[[1,2],[3,4]],[[5,6],[7,8]]]con la permutación [2,3,1]se asigna a [[[1,3],[5,7]],[[2,4],[6,8]]].
falla
fuente

Respuestas:

9

Haskell , 168 bytes

pes una función (tipo polimórfico de clase) que toma una permutación como una lista de Ints, y una lista anidada que representa una matriz multidimensional de Ints.

Llame como p [2,1] [[10,20,30],[40,50,60]], sin embargo, si el valor predeterminado de tipo no tiene éxito, es posible que tenga que agregar una anotación de tipo como :: [[Int]](anidada adecuadamente) dando el tipo del resultado.

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]

Pruébalo en línea!

Los desafíos de golf con matrices anidadas de profundidad arbitraria son un poco incómodos en Haskell, porque la escritura estática tiende a interferir. Si bien las listas de Haskell (con la misma sintaxis exacta que en la descripción del desafío) se pueden anidar perfectamente, las listas de diferentes profundidades de anidación son de tipos incompatibles. Además, las funciones de análisis estándar de Haskell requieren conocer el tipo del valor que está intentando analizar.

Como resultado, parece inevitable que el programa necesite incluir declaraciones relacionadas con el tipo, que son relativamente detalladas. Para la parte de golf, decidí definir una clase de tipo P, tal que ppueda ser polimórfica sobre el tipo de matriz.

Mientras tanto, el arnés de prueba del TIO muestra una forma de sortear el problema del análisis.

Cómo funciona

  • Para resumir la esencia de este algoritmo: realiza una clasificación de burbujas en la lista de permutación, transponiendo dimensiones vecinas cuando se intercambian los índices de permutación correspondientes.

  • Como lo indica la class P adeclaración, en cualquier caso, ptoma dos argumentos, una permutación (siempre de tipo [Int]) y una matriz.

  • La permutación se puede dar en la forma en la descripción del desafío, aunque la forma en que funciona el algoritmo, la elección de los índices es arbitraria, excepto por su orden relativo. (Así que tanto el trabajo basado en 0 como en el 1).
  • La base instance P Intmaneja matrices de dimensión 1, que psimplemente regresa sin cambios, ya que la única dimensión solo se puede asignar a sí misma.
  • El otro instance P a => P [a]se define de forma recursiva, llamando pcon dimensión n submatrices con el fin de definir para la dimensión n + 1 arrays.
    • p(x:r)mprimeras llamadas de forma p rrecursiva en cada elemento de m, dando una matriz de resultados nen la que todas las dimensiones, excepto la primera, se han permutado correctamente entre sí.
    • La permutación restante que debe realizarse nestá dada por x:y:z = x:sort r.
    • Si x<yentonces, la primera dimensión de nya está colocada correctamente, y nsimplemente se devuelve.
    • Si x>y, entonces la primera y segunda dimensión de nnecesidad de intercambiarse, que se hace con la transposefunción. Finalmente, p(x:z)se aplica de forma recursiva a cada elemento del resultado, asegurando que la primera dimensión original se transponga a la posición correcta.
Ørjan Johansen
fuente
3

Python 2 , 312 bytes

Esto usa indexación 0 para la permutación

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

Pruébalo en línea!

-2 bytes gracias a @Jonathan Frech.

fireflame241
fuente
No necesita paréntesis para llamar exec (guardar dos bytes) , ya que es una declaración en Python 2.
Jonathan Frech
También hay un espacio superfluo en z(p) for.
Jonathan Frech
1
Utilizado map(z,l), s%jy printpara 301 bytes - Pruébelo en línea!
Sr. Xcoder
3

Python 2 , 41 25 bytes

import numpy
numpy.einsum

Pruébalo en línea!

El vector de permutación pse da como una cadena de letras. Entonces [2,3,1]se puede dar como 'bca'.

¡Gracias a @EriktheOutgolfer ahorró 16 bytes!

rahnema1
fuente
¿Esto soporta más de 26 dimensiones?
Erik the Outgolfer
En realidad no más de 52 dimensiones: mayúsculas + minúsculas.
rahnema1
2

JavaScript (ES6), 136 132 bytes

(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 indexado. Explicación: gitera recursivamente sobre la matriz acreando una matriz vde índices reordenados usando la permutación p. Una vez que pse agota, hinserta recursivamente el elemento en la matriz de resultados rutilizando los índices permutados.

Neil
fuente