Inverter uma matriz N-Dimensional


10

Detalhes

Escreva uma função ou programa que, dada uma matriz (ou lista), contendo apenas números inteiros, retorne ou produza uma matriz com todos os subelementos invertidos. Ou seja, inverta todos os elementos da matriz mais profunda, depois a segunda mais profunda etc. As dimensões não precisam ser especificadas, mas a função ou o programa deve funcionar com matrizes irregulares no formato nativo da sua linguagem de programação.


Exemplos

Este:

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

Se tornaria este:

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

Este:

[[[ 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 tornaria este:

[[[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]]]

Este:

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

Se tornaria este:

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

Bônus

Espero que isso encoraje respostas em algumas linguagens de programação orientadas a objetos ...

-50% Bytecount Se o seu programa pode tomar como entrada uma matriz (ou lista) com seus membros de vários tipos (eles podem estar na forma de objetos) e reverter com êxito todas as matrizes.

Este:

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

Se tornaria este:

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

11
No seu exemplo de bônus, você trata as cordas como átomos. Eu argumentaria que eles são subconjuntos e, portanto, devem ser revertidos também. Na verdade, é isso que minha solução de APL faz quando alimenta cadeias de caracteres normais, pois a APL não possui um tipo de dados, apenas tipos de caracteres. Strings são, portanto, matrizes de caracteres unidimensionais. Se você deseja que as strings permaneçam na ordem normal, basta criar objetos com um formulário de exibição.
Adám 17/03/16

@ Nᴮᶻ Você acredita que o Bytecount -50% é muito generoso? Posso fazer algo parecido com -30% Bytecount para vários tipos de dados e algo como -10% Bytecount para reverter Strings, -15% Bytecount para reverter um tipo inteiro (123 -> 321) e -15% Bytecount para reverter um tipo flutuante (3,14 -> 41,3).
Sr. Pública

11
Eu geralmente não gosto de bônus. Inverter números inteiros e flutuantes é ... interessante.
Adám 17/03/16

4
Deixe por enquanto, mas da próxima vez, você pode usar a caixa de areia para descobrir essas coisas.
Adám 17/03/16

Respostas:


9

Pitão, 11 - 50% = 5,5 bytes

L?+IbY_yMbb

Experimente on-line: Demonstration ou Test Suite .

Isso define uma função y. Os 3 bytes adicionais <newline>yQsimplesmente chamam a função com a lista de entrada e, portanto, não precisam ser contados no total de bytes.

Explicação:

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

6

Dyalog APL , 14 - 50% = 7 bytes

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

⌽⍵argumento reverso
⍣(×|≡⍵)se o argumento não for um átomo (sinal da profundidade [absoluta]) ...
∇¨... aplique a função a cada elemento (do argumento reverso).

Se ⎕ML←3(estilo IBM), que é o caso de sistemas que migraram do APL2, um byte pode ser salvo removendo |.

Experimente o APL online.

Por curiosidade, o int e float reversos propostos :

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

A função interna:

0::⌽⍵se ocorrer algum erro, basta retornar o argumento revisado
⍎⌽⍕make para string, reverse, make into number


4

Prolog, 40 - 50% = 20 bytes

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

Isso chama recursivamente o predicado a/2com maplist/3, para cada membro da lista, até reverse/2falhar (ou seja, o último elemento não era uma lista).


4

Python 2, 40 - 50% = 20

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

Apenas algumas pequenas modificações necessárias da maneira básica de fazer isso são necessárias para obter o bônus. Usa o fato de que todas as listas são menores que a sequência vazia e todos os números são menores que a lista vazia.

Todos os casos de teste


Apenas uma nota de que a versão sem o bônus é 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))))

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

Abordagem recursiva clássica: se o argumento não for uma lista, mantenha-o inalterado; se for uma lista, mapeie a função no verso da lista.


2

Mathematica, 34/2 = 17 bytes

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

Ou apenas Reverse//@#&se você quiser uma tonelada de erros Reversees em todos os lugares.


2

Clojure 43/2 = 21,5 bytes

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

1

JavaScript ES6, 42 - 50% = 21 bytes

Minha pontuação é perfeita de várias maneiras. Implementa uma função rque se aplica recursivamente aos membros de sua entrada.

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

Se assumirmos que nenhum objeto tem a propriedade pop, isso se tornará (31 - 50% = 15.5), graças a dev-null:

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

Ou, se assumirmos que o objeto tem uma reversepropriedade sã , também poderíamos fazer isso (35 - 50% = 17,5):

r=a=>a[R="reverse"]?a[R]().map(r):a

Acho que se pode verificar com segurança uma matriz como este: a.pop?a.reverse().map(r):a. Supondo que não há necessidade de manipular void 0objetos personalizados.
18716 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

Bom recursão


1

CJam, 20 bytes * 50% = 10

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

Define o bloco nomeado Fque pode ser aplicado a uma matriz no topo da pilha (ou qualquer outra coisa, nesse caso, é um não operacional).

Teste aqui.


1

Braquilog , 5 - 50% = 2,5 bytes

ċ↔↰ᵐ|

Experimente online!

         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 também podemos reverter seqüências de caracteres e números inteiros, temos que explicitamente falhar as não listas com ċ.


1

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

#/.List->Reverse@*List&

Experimente online!

Lists no Mathematica ( {...}) são equivalentes a List[...]. @*é o operador de composição, portanto, substituir cada ocorrência de Listpor Reverse@*Listreverte todas as listas que ocorrem na entrada ( Reverse@*List[...]= Reverse[{...}]).


24 -50% = 12 bytes

#~Reverse~Range@Depth@#&

Experimente online!

Não funciona apenas em Lists.


1

Clojure, 38 bytes

(e um bônus, eu acho, mas o Clojure é uma linguagem dinâmica, por isso é de graça)

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

Este é um bom começo, mas não empregou essas otimizações:

  • Defina uma função anônima com em fnvez de uma nomeada com defn. Mas ainda precisamos de um nome com "escopo"f para recursão
  • Tome entrada como uma lista em vez de vetor, então podemos usar em seq?vez decoll?
  • Use em (into () ...)vez dereverse
  • Inverter xantes do mapeamento, não precisamos de tantos espaços

0

Rubi , 32 - 50% = 16 bytes

Função recursiva. Usar rescuepara capturar o NoMethodErrorque dispara ao tentar reverseum número ou mapuma sequência acaba por ser 2 bytes mais curto do que verificar se a entrada é uma matriz via a==[*a].

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

Experimente online!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.