Invertire le colonne mantenendo la forma


20

introduzione

Supponiamo di avere un elenco di elenchi di numeri interi (o di qualsiasi oggetto in realtà, ma atteniamoci agli interi per semplicità). Gli elenchi potrebbero avere lunghezze diverse e alcuni di essi potrebbero essere vuoti. Scriviamo le liste in formato tabulare:

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

Questa tabella contiene 5 colonne verticali, contenente i numeri 1, 6, 8, 12, 15, 2, 7, 9, 13, 16, 3, 10, 14, 17, 4, 11, 18, e 5. Se invertiamo ogni colonna, otteniamo le liste 15, 12, 8, 6, 1, 16, 13, 9, 7, 2, 17, 14, 10, 3, 18, 11, 4, e 5. Ricolleghiamo quei numeri nelle colonne della tabella mantenendo le lunghezze delle righe uguali a prima:

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

Il tuo compito è implementare questa operazione.

Ingresso e uscita

Il tuo input è un elenco di elenchi di numeri interi non negativi, che rappresentano le righe. Le righe possono avere lunghezze diverse e alcune potrebbero essere vuote. Ci sarà sempre almeno una riga. L'output è il risultato dell'inversione di ogni colonna, come descritto sopra. L'input e l'output possono essere in qualsiasi formato ragionevole.

Vince il conteggio dei byte più basso in ogni lingua. Si applicano le regole standard del .

Casi test

[[]] -> [[]]
[[],[]] -> [[],[]]
[[8,5,1]] -> [[8,5,1]]
[[1,200],[0,3]] -> [[0,3],[1,200]]
[[],[3,9],[1],[]] -> [[],[1,9],[3],[]]
[[],[5,8,7],[0,6,5,7,1]] -> [[],[0,6,5],[5,8,7,7,1]]
[[1,8,5],[7,5,4],[],[1]] -> [[1,5,4],[7,8,5],[],[1]]
[[],[],[2],[],[31],[],[5],[],[],[],[7]] -> [[],[],[7],[],[5],[],[31],[],[],[],[2]]
[[1,10,100,1000],[2,20,200],[3,30],[4],[5,50,500],[6,60],[7]] -> [[7,60,500,1000],[6,50,200],[5,30],[4],[3,20,100],[2,10],[1]]
[[8,4],[3,0,4,8,1],[8],[0,8],[9,7,1,6],[3,8,1,9,5]] -> [[3,8],[9,7,1,9,5],[0],[8,8],[3,0,1,6],[8,4,4,8,1]]
[[3,9,3],[5],[1],[3,5],[9,0,6,2],[1,3],[4,9,2],[6,6,7,8,7]] -> [[6,6,7],[4],[1],[9,9],[3,3,2,8],[1,0],[5,5,6],[3,9,3,2,7]]
[[8,5,6],[3,5,2,4,9],[4,3,8,3,7],[6,1,1],[1,8,9,9],[9,1,2],[8,7]] -> [[8,7,2],[9,1,9,9,7],[1,8,1,3,9],[6,1,8],[4,3,2,4],[3,5,6],[8,5]]
[[2,4],[1,4],[0,8,7,3],[4,9,2,5],[2,8,0],[0,8,3],[7,3,1],[],[3,3,7,8]] -> [[3,3],[7,3],[0,8,7,8],[2,8,1,5],[4,9,3],[0,8,0],[1,4,2],[],[2,4,7,3]]

1
Possiamo riempire le righe dell'output con valori null? (es. [[1,9],[3],[2,4,5]] -> [[2,4],[3,null],[1,9,5]])
ETHproductions

@ETHproductions No, l'output dovrebbe contenere solo numeri.
Zgarb,

-1 perché non è generale (non consentire numeri negativi, lettere, stringhe e tutti i tipi possibili come elemento riga) + Non mi piace (sembra inutile difficile)
RosLuP

Risposte:


5

Gelatina , 16 byte

ḟṚṁṣj
z-ç€-ZFḟ-ṁ

Provalo online! o verifica tutti i casi di test .

Come funziona

z-ç€-ZFḟ-ṁ  Main link. Argument: M (matrix / 2D array)

z-          Zip the rows of M, using -1 as filler.
  ç€-       Map the helper link over the result, with right argument -1.
     Z      Zip the rows of the result.
      F     Flatten the resulting matrix.
       ḟ-   Filterfalse -1; remove all occurrences of -1.
         ṁ  Mold; shape the result like M.


ḟṚṁṣj       Helper link.
            Left argument: A (row / 1D array). Right argument: -1

ḟ           Filterfalse; remove all occurrences of -1.
 Ṛ          Reverse the resulting vector.
   ṣ        Split A at occurrences of -1.
  ṁ         Mold; shape the vector to the left like the 2D array to the right.
    j       Join the resulting 2D array, separating by -1.

Bello, in prima linea è molto intelligente! ( ḟṚṁṣjfa ⁸ḟ⁹Ṛṁ⁸ṣ⁹¤j⁹bene?) altrimenti avrei avuto questo per un altro byte
Erik the Outgolfer il

Sì, è esattamente quello che fa.
Dennis,

4

Japt , 15 13 byte

salvato 2 byte grazie a @Shaggy

y@=XfÊX£o
®fÄ

Provalo online!

La seconda riga può essere rimossa se ci è permesso di riempire le righe con valori null, salvando 4 byte.

Spiegazione

 y@  =XfÊ X£  o      Implicit: U = input array
UyX{U=Xfl Xm{Uo}}    (Ungolfed)
UyX{            }    Map each column X in the input by this function:
    U=Xfl              Set U to X filtered to only items whose factorial is truthy;
                       this just gets rid of the empty slots in the column.
          Xm{  }       Map each item in X to
             Uo          the last item in U, popping this item from the list.
                       Due to the way .map works in JS, this is only called on real items
                       and not empty slots, so this preserves empty slots.
                     Newline: set U to the resulting column-reversed array
 ®   fÄ              Due to the way y works, there will now be `undefined` in some rows.
UmZ{Zf+1}            (Ungolfed)
 mZ{    }            Map each row Z in U to
    Zf+1               Z filtered to only items where the item + 1 is truthy.
                     undefined + 1 is NaN, which is falsy, and thus eliminated.
                     Implicit: output result of last expression

Ben fatto! È possibile ottenere fino a 13 byte sostituendo l;con Êe mf_Äcon ®fÄ.
Shaggy,

In realtà, mfsembra funzionare solo per la seconda riga.
Shaggy,

@Shaggy Grazie, non ci avevo pensato! mf
eliminerei

Ah, sì, non ci stavo pensando.
Shaggy,

4

APL (Dyalog Unicode) , 20 19 16 byte SBCS

-4 grazie a ngn.

Programma completo. Richiede input da STDIN.

0~¨⍨↓⍉⌽@×⍤1⍉↑*⎕

Provalo online!

Spiegazione con esempio walk-through

 richiesta di input valutato
[[1,8,5],[7,5,4],[],[1]]

* elevare e alla potenza di quello ( e n che assicura che non ci siano zeri)
[[2.7,2981,148.4],[1096.6,148.4,54.6],[],[2.7]]

 mescola gli elenchi in un'unica matrice, riempiendo di zeri:
┌ ┐
│2.7E0 3.0E3 1.5E2│
│1.1E3 1.5E2 5.5E1│
│0.0E0 0.0E0 0.0E0│
│2.7E0 0.0E0 0.0E0│
└ ┘

 trasporre
┌ ┐
│2.7E0 1.1E3 0.0E0 2.7E0│
│3.0E3 1.5E2 0.0E0 0.0E0│
│1.5E2 5.5E1 0.0E0 0.0E0│
└ ┘

⌽@×⍤1 invertire gli elementi positivi di ogni riga
┌ ┐
│2.7E0 1.1E3 0.0E0 2.7E0│
│1.5E2 3.0E3 0.0E0 0.0E0│
│5.5E1 1.5E2 0.0E0 0.0E0│
└ ┘

 trasporre
┌ ┐
│2.7E0 1.5E2 5.5E1│
│1.1E3 3.0E3 1.5E2│
│0.0E0 0.0E0 0.0E0│
│2.7E0 0.0E0 0.0E0│
└ ┘

 dividere la matrice in un elenco di elenchi
[[2.7,148.4,54.6],[1096.6,2981,148.4],[0,0,0],[2.7,0,0]]

0~¨⍨ rimuove gli zeri da ogni elenco
[[2.7,148.4,54.6],[1096.6,2981,148.4],[],[2.7]]

 logaritmo naturale
[[1,5,4],[7,8,5],[],[1]]


Cosa succede se l'input contiene -1?
ngn,

@ngn Input non conterrà mai numeri negativi; vedere la sezione "Input e output".
Zgarb,

@Zgarb È perfetto, grazie.
ngn,

@Adám Ho modificato per utilizzare il rango 1 invece di mescolare ogni divisione.
ngn,

@Adám anche: exp / log invece di + 1 / -1 copre i test con ←fr ← 1287
ngn

3

K4 , 36 byte

Soluzione:

+{x[w]:|x w:&~^x;x}'x'[::;]@!|/#:'x:

Esempi:

q)k)+{x[w]:|x w:&~^x;x}'x'[::;]@!|/#:'x:(1 2 3 4 5;6 7;8 9 10 11;0#0N;12 13 14;15 16 17 18)
15 16 17 18 5
12 13        
8  9  14 11  

6  7  10     
1  2  3  4

q)k)+{x[w]:|x w:&~^x;x}'x'[::;]@!|/#:'x:(0#0N;5 8 7; 0 6 5 7 1)

0 6 5    
5 8 7 7 1

Spiegazione:

Questo è stato un dolore e sto ancora lavorando per semplificare l'indicizzazione elisa.

Invece di indicizzare at, ad esempio, x[0]che restituirebbe la prima riga , vogliamo prendere la prima colonna , che può essere fatta usando x[;0].

Tuttavia passando variabile ynella x[;]tratta come fare x[y], non x[;y]quindi spingendo l' ::in là: x[::;].

Ciò equivale a capovolgere l'elenco di elenchi, ma capovolgere richiede che tutti gli elenchi abbiano la stessa lunghezza!

+{x[w]:|x w:&~^x;x}'x'[::;]@!|/#:'x: / the solution
                                  x: / save input as variable x
                               #:'   / count (#:) each (') 
                             |/      / take the max of these lengths
                            !        / til, range 0..max-1
                           @         / apply (index into)
                      [::;]          / :: is a kind of null, 
                    x'               / index into x at each of these    
 {              ; }'                 / two statement lambda on each (')
              ^x                     / null x (returns true if entry is null)
             ~                       / not, so flip true/false
            &                        / where, indexes where true
          w:                         / save as variable w  
        x                            / index into w at these indexes
       |                             / reverse
  x[w]:                              / store this back in variable x at indexes w
                 x                   / return x from function
+                                    / flip the result

3

Haskell , 174 byte

f x=map g.h.map(g.reverse>>=(!)).h$take(maximum$length<$>x).(++z).map pure<$>x
g=concat
h x|g x==[]=x|4>2=foldr(zipWith(:))z x
x!(c:d)|c==[]=c:x!d|a:b<-x=[a]:b!d
_!y=y
z=[]:z

Provalo online!

Ungolfed / Spiegazione

L'idea è di avvolgere tutti gli elementi []e riempire le righe con [](risultando più breve rispetto al riempimento con un numero intero negativo, questo consente anche input negativi che è bello), quindi trasporre, invertire tutte le righe e trasporre nuovamente e appiattire ogni riga :

map concat                                   -- flatten each row
  . transpose'                               -- transpose (*)
  . map (\row-> reverse (concat row) ! row)  -- reverse each row (see below)
  . transpose'                               -- tranpose (*)
  $ take (maximum $ length <$> x)            -- only keep up as many as longest row
      . (++ z)                               -- pad row with [],[],..
      . map (\e-> [e])                       -- wrap elements in []
 <$> x

* Questa funzione di trasposizione ( h) restituisce semplicemente l'elenco se non ci sono elementi.

La funzione inversa deve ignorare gli []elementi (es. [[],[1],[],[3],[4]]-> [[],[4],[],[3],[1]]), lo fa ricevendo due argomenti: il primo sono gli elementi in ordine inverso (es. [4,3,1]) E il secondo la riga originale.

x@(a:b) ! (c:d)
 | c == []   = c:x ! d    -- if current element is []: skip it
 | otherwise = [a]:b ! d  -- else: replace with new one (a) and continue
_ ! y = y                 -- base case (if no new elements are left): done


2

JavaScript (ES6), 79 76 byte

(a,d=[],g=s=>a.map(b=>b.map((c,i)=>(d[i]=d[i]||[])[s](c))))=>g`push`&&g`pop`

Modifica: salvato 3 byte grazie a @ETHproductions.


@ETHproductions Right; Non ho idea del perché pensassi di no, altrimenti l'avrei già fatto.
Neil,


0

Clojure, 123 byte

#(map(fn[i R](map(fn[j _](let[V(for[Q %](get Q j))F filter](nth(reverse(F + V))(count(F +(take i V))))))(range)R))(range)%)

Mi aspettavo (+ nil)di lanciare un'eccezione, ma valuta nil: o

Funziona senza riempimento, invece conta quante delle righe precedenti sono almeno lunghe quanto la riga corrente R.

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.