Invertir una matriz N-Dimensional

10

Detalles

Escriba una función o programa que, dada una matriz (o lista), que contiene solo enteros, devuelve o genera una matriz con todos los subelementos invertidos. Es decir, invierta todos los elementos de la matriz más profunda, luego la segunda más profunda, etc. No es necesario especificar las dimensiones, pero la función o el programa deben funcionar para matrices irregulares en el formato nativo de su lenguaje de programación.


Ejemplos

Esta:

[[1,2], [3,4]]

Se convertiría en esto:

[[4,3], [2,1]]

Esta:

[[[ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 9]],
 [[10,11,12], [13,14,15], [16,17,18]],
 [[19,20,21], [22,23,24], [25,26,27]],
 [[28,29,30], [31,32,33], [34,35,36]],
 [[37,38,39], [40,41,42], [43,44,45]],
 [[46,47,48], [49,50,51], [52,53,54]]]

Se convertiría en esto:

[[[54,53,52], [51,50,49], [48,47,46]],
 [[45,44,43], [42,41,40], [39,38,37]],
 [[36,35,34], [33,32,31], [30,29,28]],
 [[27,26,25], [24,23,22], [21,20,19]],
 [[18,17,16], [15,14,13], [12,11,10]],
 [[ 9, 8, 7], [ 6, 5, 4], [ 3, 2, 1]]]

Esta:

[[[1,2]],
 [[3,4], [5]],
 [[6,7,8], [9], [10,11]],
 [[[12,13], [14,15]], [16], [17,18,19,20]],
 [21]]

Se convertiría en esto:

[[21],
 [[20,19,18,17], [16], [[15,14], [13,12]]],
 [[11,10], [9], [8,7,6]],
 [[5], [4,3]],
 [[2,1]]]

Prima

Con suerte, esto alentará las respuestas en algunos lenguajes de programación orientados a objetos ...

-50% Bytecount Si su programa puede tomar como entrada una matriz (o lista) con sus miembros de varios tipos (estos pueden ser en forma de objetos) y revertir con éxito todas las matrices.

Esta:

[["Foo",["Bar",1]],
  2,
 ["Baz"],
 [[["Qux"],3],3.14]]

Se convertiría en esto:

[[3.14,[3,["Qux"]]],
 ["Baz"],
  2,
 [[1,"Bar"],"Foo"]]
Señor público
fuente
1
En su ejemplo de bonificación, trata las cadenas como átomos. Yo diría que son subarreglos y, por lo tanto, también deberían invertirse. De hecho, esto es lo que hace mi solución APL cuando alimenta cadenas normales, ya que APL no tiene un tipo de datos de cadena, solo tipos de datos de caracteres. Las cadenas son, por lo tanto, matrices de caracteres unidimensionales. Si desea que las cadenas permanezcan en el orden normal, solo tiene que convertirlas en objetos con un formulario de visualización.
Adám
@ Nᴮᶻ ¿Crees que el -50% Bytecount es demasiado generoso? Puedo hacer algo como -30% Bytecount para varios tipos de datos, y algo como -10% Bytecount para revertir cadenas, -15% Bytecount para revertir un tipo entero (123 -> 321) y -15% Bytecount para revertir un tipo flotante (3.14 -> 41.3).
Sr. público
1
Generalmente no me gustan los bonos. Invertir enteros y flotadores es ... interesante.
Adám
44
Déjelo por ahora, pero la próxima vez, es posible que desee usar el sandbox para descubrir tales cosas.
Adám
55
Acerca de los bonos ...
Martin Ender

Respuestas:

9

Pyth, 11 - 50% = 5.5 bytes

L?+IbY_yMbb

Pruébelo en línea: Demostración o Test Suite .

Esto define una función y. Los 3 bytes adicionales <newline>yQsimplemente llaman a la función con la lista de entrada y, por lo tanto, no es necesario contarlos para el total de bytes.

Explicación:

L?+IbY_yMbb
L             define a function y(b), that returns:
 ?+IbY           if b + [] == b (test if b is a list):
      _yMb           recursively call y on all elements in b, then reverse the list
          b      else: b
Jakube
fuente
6

Dyalog APL , 14-50 % = 7 bytes

{∇¨⍣(×|≡⍵)⌽⍵}

⌽⍵argumento inverso
⍣(×|≡⍵)si el argumento no es un átomo (signo de la profundidad [absoluta]) ...
∇¨... aplique la función a cada elemento (del argumento inverso).

Si ⎕ML←3(estilo IBM), como es el caso en los sistemas que migraron desde APL2, se puede guardar un byte al eliminarlo |.

Prueba APL en línea.

Por curiosidad, la inversión propuesta de int y float:

{∇¨⍣(×≡⍵){0::⌽⍵⋄⍎⌽⍕⍵}⍵}

La función interna:

0::⌽⍵si ocurre algún error, simplemente devuelva el argumento invertido
⍎⌽⍕make en cadena, revierta, haga en número

Adán
fuente
4

Prólogo, 40 - 50% = 20 bytes

a(X,Y):-reverse(X,Z),maplist(a,Z,Y);X=Y.

Esto recursivamente llama al predicado a/2con maplist/3, para cada miembro de la lista, hasta que reverse/2falla (es decir, el último elemento no era una lista).

Fatalizar
fuente
4

Python 2, 40 - 50% = 20

f=lambda x:map(f,x)[::-1]if"">x>[]else x

Solo se necesitan algunas modificaciones menores de la forma básica para hacerlo para obtener la bonificación. Utiliza el hecho de que todas las listas son menores que la cadena vacía y todos los números son menores que la lista vacía.

Todos los casos de prueba

FryAmTheEggman
fuente
Solo una nota de que la versión sin el bono es f=lambda x:map(f,x)[::-1]if x>[]else x.
mbomb007
3

Emacs Lisp, 46 bytes * 0.5 = 23

(defun g(x)(if(atom x)x(mapcar'g(reverse x))))

Ejemplo de uso: (g '((1 2) 3 (four 5)))->((5 four) 3 (2 1))

Enfoque recursivo clásico: si el argumento no es una lista, no lo modifique, si es una lista, asigne la función al reverso de la lista.

nimi
fuente
2

Mathematica, 34/2 = 17 bytes

Quiet[Reverse//@#]/.Reverse->(#&)&

O simplemente Reverse//@#&si quieres un montón de errores y Reverses en todas partes.

CalculadoraFeline
fuente
2

Clojure 43/2 = 21.5 bytes

(defn f[x](if(coll? x)(reverse(map f x))x))
wilkesybear
fuente
1

JavaScript ES6, 42 - 50% = 21 bytes

Mi puntaje es perfecto en muchos sentidos. Implementa una función rque se aplica recursivamente a los miembros de su entrada.

r=a=>Array.isArray(a)?a.reverse().map(r):a

Si suponemos que ningún objeto tiene la propiedad pop, esto se convierte en (31 - 50% = 15.5), gracias a dev-null:

r=a=>a.pop?a.reverse().map(r):a

O, si suponemos que el objeto tiene una reversepropiedad sensata , podríamos hacer eso también (35 - 50% = 17.5):

r=a=>a[R="reverse"]?a[R]().map(r):a
Conor O'Brien
fuente
Creo que se puede comprobar sin riesgos para una matriz de esta manera: a.pop?a.reverse().map(r):a. Asumiendo que no hay necesidad de manipular void 0y personalizar objetos.
andlrc
1

Lua, 111 99 * .5 = 55.5 49.5 bytes

function r(a)local t={}for i,v in next,a do t[#a+1-i]=type(v)=="table"and r(v)or v end return t end

Buen poco de recursividad

Trebuchette
fuente
1

CJam, 20 bytes * 50% = 10

{_`0='[={W%{F}%}&}:F

Define el bloque con nombre Fque se puede aplicar a una matriz en la parte superior de la pila (o cualquier otra cosa, en cuyo caso es un no-op).

Pruébalo aquí.

Martin Ender
fuente
1

Brachylog , 5 - 50% = 2.5 bytes

ċ↔↰ᵐ|

Pruébalo en línea!

         The input
ċ        which is a list
 ↔       reversed
   ᵐ     with each element
  ↰      passed through this same predicate
    |    is the output. If the input isn't a list,
         it is the output.

Como también puede revertir cadenas y enteros, tenemos que fallar explícitamente con las no listas ċ.

Cadena no relacionada
fuente
1

Wolfram Language (Mathematica) , 23 -50% = 11.5 bytes

#/.List->Reverse@*List&

Pruébalo en línea!

Lists en Mathematica ( {...}) son equivalentes a List[...]. @*es el operador de composición, por lo que al reemplazar cada aparición de Listcon Reverse@*Listinvierte cada lista que ocurre en la entrada ( Reverse@*List[...]= Reverse[{...}]).


24 -50% = 12 bytes

#~Reverse~Range@Depth@#&

Pruébalo en línea!

No solo funciona en Lists.

attinat
fuente
1

Clojure, 38 bytes

(y una bonificación, supongo, pero Clojure es un lenguaje dinámico, por lo que es gratis)

(fn f[x](if(seq? x)(map f(into()x))x))

Este es un buen comienzo, pero no empleó estas optimizaciones:

  • Defina una función anónima con en fnlugar de una con nombre defn. Pero aún necesitamos un nombre "con alcance" fpara la recursividad
  • Tome la entrada como una lista en lugar de un vector, luego podemos usar en seq?lugar decoll?
  • Usar en (into () ...)lugar dereverse
  • Invertir xantes del mapeo, no necesitamos tantos espacios entonces
NikoNyrh
fuente
0

Ruby , 32 - 50% = 16 bytes

Función recursiva. Usar rescuepara detectar el NoMethodErrorque se dispara al intentar reverseun número o mapuna cadena resulta ser 2 bytes más corto que verificar si la entrada es una matriz vía a==[*a].

f=->a{a.reverse.map(&f)rescue a}

Pruébalo en línea!

Tinta de valor
fuente