Invertire una matrice N-dimensionale


10

Dettagli

Scrivi una funzione o un programma che, dato un array (o un elenco), contenente solo numeri interi, restituisce o genera un array con tutti gli elementi secondari invertiti. Cioè, invertire tutti gli elementi dell'array più profondo, quindi il secondo più profondo, ecc. Non è necessario specificare le dimensioni, ma la funzione o il programma deve funzionare per array frastagliati nel formato nativo del linguaggio di programmazione.


Esempi

Questo:

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

Diventerebbe questo:

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

Questo:

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

Diventerebbe questo:

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

Questo:

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

Diventerebbe questo:

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

indennità

Si spera che ciò incoraggi le risposte in alcuni linguaggi di programmazione orientati agli oggetti ...

-50% Bytecount Se il tuo programma può prendere come input un array (o un elenco) con i suoi membri di vari tipi (questi possono essere sotto forma di oggetti) e invertire con successo tutti gli array.

Questo:

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

Diventerebbe questo:

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

1
Nel tuo esempio di bonus, tratti le stringhe come atomi. Direi che sono sotto-array e quindi dovrebbero essere invertiti. Questo è in effetti ciò che fa la mia soluzione APL quando viene alimentata stringhe normali, poiché APL non ha un tipo di dati stringa, ma solo tipi di dati carattere. Le stringhe sono quindi matrici di caratteri unidimensionali. Se vuoi che le stringhe rimangano nell'ordine normale, devi solo renderle oggetti con un modulo di visualizzazione.
Adám

@Nᴮᶻ Credi che il Bytecount -50% sia troppo generoso? Potrei fare qualcosa del tipo di -30% Bytecount per vari tipi di dati e qualcosa come -10% Bytecount per invertire stringhe, -15% Bytecount per invertire un tipo intero (123 -> 321) e -15% Bytecount per invertire un tipo mobile (3.14 -> 41.3).
MrPublic

1
In genere non mi piacciono i bonus. Invertire numeri interi e float è ... interessante.
Adám,

4
Lascialo per ora, ma la prossima volta, potresti voler usare il sandbox per capire queste cose.
Adám,

Risposte:


9

Pyth, 11-50% = 5,5 byte

L?+IbY_yMbb

Provalo online: dimostrazione o Test Suite .

Questo definisce una funzione y. I 3 byte aggiuntivi <newline>yQchiamano semplicemente la funzione con l'elenco di input e quindi non devono essere conteggiati per il totale dei byte.

Spiegazione:

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 byte

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

⌽⍵argomento inverso
⍣(×|≡⍵)se l'argomento non è un atomo (segno della profondità [assoluta]) ...
∇¨... applica la funzione a ciascun elemento (dell'argomento invertito).

If ⎕ML←3(stile IBM), come nel caso dei sistemi migrati da APL2, è possibile salvare un byte rimuovendolo |.

Prova APL online.

Per curiosità, il proposto int e float reversing:

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

La funzione interna:

0::⌽⍵se si verifica un errore, è sufficiente restituire l'argomento modificato
⍎⌽⍕in stringa, invertire, fare in numero


4

Prolog, 40-50% = 20 byte

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

Ciò chiama ricorsivamente il predicato a/2con maplist/3, per ciascun membro dell'elenco, fino a quando reverse/2non riesce (ovvero l'ultimo elemento non era un elenco).


4

Python 2, 40-50% = 20

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

Per ottenere il bonus sono necessarie solo alcune piccole modifiche dal modo di base per farlo. Utilizza il fatto che tutti gli elenchi sono inferiori alla stringa vuota e tutti i numeri sono inferiori all'elenco vuoto.

Tutti i casi di test


Solo una nota che la versione senza il bonus è f=lambda x:map(f,x)[::-1]if x>[]else x.
mbomb007,

3

Emacs Lisp, 46 byte * 0,5 = 23

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

Esempio di utilizzo: (g '((1 2) 3 (four 5)))->((5 four) 3 (2 1))

Approccio ricorsivo classico: se l'argomento non è un elenco, prenderlo invariato, se è un elenco, mappare la funzione sul retro dell'elenco.


2

Mathematica, 34/2 = 17 byte

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

O solo Reverse//@#&se vuoi un sacco di errori e Reverseovunque.


2

Clojure 43/2 = 21,5 byte

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

1

JavaScript ES6, 42-50% = 21 byte

Il mio punteggio è perfetto in molti modi. Implementa una funzione rche si applica in modo ricorsivo ai membri del suo input.

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

Se assumiamo che nessun oggetto abbia la proprietà pop, questo diventa (31-50% = 15,5), grazie a dev-null:

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

Oppure, se assumiamo che l'oggetto abbia una reverseproprietà sana , potremmo farlo anche noi (35-50% = 17,5):

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

Credo che si potrebbe tranquillamente verificare la presenza di una serie come questa: a.pop?a.reverse().map(r):a. Supponendo che non sia necessario gestire void 0oggetti personalizzati.
Andlrc

1

Lua, 111 99 * .5 = 55.5 49.5 byte

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

Un bel po 'di ricorsione


1

CJam, 20 byte * 50% = 10

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

Definisce il blocco denominato Fche può essere applicato a un array in cima allo stack (o qualsiasi altra cosa, nel qual caso è un no-op).

Provalo qui.


1

Brachylog , 5-50 % = 2,5 byte

ċ↔↰ᵐ|

Provalo 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.

Dal momento che può anche invertire stringhe e numeri interi, dobbiamo fallire esplicitamente i non-list con ċ.


1

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

#/.List->Reverse@*List&

Provalo online!

Lists in Mathematica ( {...}) sono equivalenti a List[...]. @*è l'operatore di composizione, quindi la sostituzione di ogni occorrenza di Listcon Reverse@*Listinverte ogni elenco che si verifica nell'input ( Reverse@*List[...]= Reverse[{...}]).


24-50% = 12 byte

#~Reverse~Range@Depth@#&

Provalo online!

Non funziona solo su Lists.


1

Clojure, 38 byte

(e un bonus immagino, ma Clojure è un linguaggio dinamico, quindi viene gratis)

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

Questo è un buon inizio ma non ho utilizzato queste ottimizzazioni:

  • Definire una funzione anonima con fn anziché un nome con defn. Ma abbiamo ancora bisogno di un nome "mirato" fper la ricorsione
  • Prendi l'input come elenco anziché come vettore, quindi possiamo usarlo seq? invece dicoll?
  • Uso (into () ...) invece direverse
  • Invertire xprima della mappatura, quindi non abbiamo bisogno di tanti spazi

0

Rubino , 32-50% = 16 byte

Funzione ricorsiva. L'uso rescueper catturare NoMethodErrorciò che si innesca quando si cerca reverseun numero o mapuna stringa risulta essere 2 byte più corto del controllo se l'input è un array tramite a==[*a].

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

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.