Inverser les colonnes tout en préservant la forme


20

introduction

Supposons que vous ayez une liste de listes d'entiers (ou n'importe quel objet vraiment, mais restons sur des entiers pour plus de simplicité). Les listes peuvent être de différentes longueurs et certaines peuvent être vides. Écrivons les listes sous forme de tableau:

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

Ce tableau a 5 colonnes verticales, contenant les nombres 1, 6, 8, 12, 15, 2, 7, 9, 13, 16, 3, 10, 14, 17, 4, 11, 18et 5. Si on inverse chaque colonne, on obtient les listes 15, 12, 8, 6, 1, 16, 13, 9, 7, 2, 17, 14, 10, 3, 18, 11, 4et 5. Reprenons ces numéros dans les colonnes du tableau tout en conservant la même longueur que précédemment:

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

Votre tâche consiste à implémenter cette opération.

Entrée et sortie

Votre entrée est une liste de listes d'entiers non négatifs, représentant les lignes. Les lignes peuvent avoir des longueurs différentes et certaines d'entre elles peuvent être vides. Il y aura toujours au moins une ligne. Votre sortie est le résultat de l'inversion de chaque colonne, comme détaillé ci-dessus. L'entrée et la sortie peuvent être dans n'importe quel format raisonnable.

Le nombre d'octets le plus bas dans chaque langue gagne. Les règles de standard s'appliquent.

Cas de 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
Pouvons-nous remplir les lignes de la sortie avec des valeurs nulles? (par exemple [[1,9],[3],[2,4,5]] -> [[2,4],[3,null],[1,9,5]])
ETHproductions

@ETHproductions Non, la sortie ne doit contenir que des chiffres.
Zgarb

-1 car ce n'est pas général (ne pas autoriser les nombres négatifs, les lettres, la chaîne et tous les types possibles comme élément de ligne) + Je ne l'aime pas (cela semble inutile difficile)
RosLuP

Réponses:


5

Gelée , 16 octets

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

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça fonctionne

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.

Sympa, la ligne du haut est très intelligente! ( ḟṚṁṣjNe ⁸ḟ⁹Ṛṁ⁸ṣ⁹¤j⁹pas?) Sinon j'avais ce pour un octet
Erik le Outgolfer

Oui, c'est exactement ce que ça fait.
Dennis

4

Japt , 15 13 octets

économisé 2 octets grâce à @Shaggy

y@=XfÊX£o
®fÄ

Testez-le en ligne!

La deuxième ligne peut être supprimée si nous sommes autorisés à remplir les lignes avec des valeurs nulles, économisant 4 octets.

Explication

 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

Joli! Vous pouvez le réduire à 13 octets en remplaçant l;par Êet mf_Äpar ®fÄ.
Shaggy

En fait, mfsemble juste fonctionner pour la deuxième ligne.
Shaggy

@Shaggy Merci, je n'y avais pas pensé! mfpermettrait de se débarrasser de tous les zéros dans le résultat, malheureusement ...
ETHproductions

Ah, oui, je n'y pensais pas.
Shaggy

4

APL (Dyalog Unicode) , 20 19 16 octets SBCS

-4 grâce à ngn.

Programme complet. Demande l'entrée de STDIN.

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

Essayez-le en ligne!

Explication avec un exemple de procédure pas à pas

 invite pour l'entrée évaluée
[[1,8,5],[7,5,4],[],[1]]

* élever e à la puissance de cela ( e n qui garantit qu'il n'y aura pas de zéros)
[[2.7,2981,148.4],[1096.6,148.4,54.6],[],[2.7]]

 mélanger les listes dans une seule matrice, avec des zéros:
┌ ┐
│2.7E0 3.0E3 1.5E2│
│1.1E3 1.5E2 5.5E1│
│0.0E0 0.0E0 0.0E0│
│2.7E0 0.0E0 0.0E0│
└ ┘

 transposer
┌ ┐
│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 inverser les éléments positifs de chaque ligne
┌ ┐
│2.7E0 1.1E3 0.0E0 2.7E0│
│1.5E2 3.0E3 0.0E0 0.0E0│
│5.5E1 1.5E2 0.0E0 0.0E0│
└ ┘

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

 diviser la matrice en une liste de listes
[[2.7,148.4,54.6],[1096.6,2981,148.4],[0,0,0],[2.7,0,0]]

0~¨⍨ supprimer les zéros de chaque liste
[[2.7,148.4,54.6],[1096.6,2981,148.4],[],[2.7]]

 un algorithme naturel
[[1,5,4],[7,8,5],[],[1]]


Que faire si l'entrée contient -1?
ngn

@ngn Input ne contiendra jamais de nombres négatifs; voir section "Entrée et sortie".
Zgarb

@Zgarb C'est parfait, merci.
ngn le

@ Adám j'ai édité pour utiliser le rang 1 au lieu de mélanger-chaque-split.
ngn

@ Adám aussi: exp / log au lieu de + 1 / -1 couvre les tests avec ⎕fr ← 1287
ngn

3

K4 , 36 octets

Solution:

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

Exemples:

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

Explication:

Celui-ci a été une douleur, et je travaille toujours à simplifier l'indexation élidé.

Au lieu d'indexer dans, par exemple, x[0]qui retournerait la première ligne , nous voulons prendre la première colonne , ce qui peut être fait en utilisant x[;0].

Cependant la variable qui passe ydans la x[;]traite comme faisant x[y]pas x[;y]bousculade d' où le ::là: x[::;].

Cela équivaut à retourner la liste des listes, mais pour retourner, toutes les listes doivent être de longueur égale!

+{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 octets

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

Essayez-le en ligne!

Non golfé / Explication

L'idée est d'envelopper tous les éléments []et de remplir les lignes avec [](s'est avéré être plus court que le remplissage avec un entier négatif, cela permet également des entrées négatives, ce qui est bien), puis transposer, inverser toutes les lignes et transposer à nouveau et aplatir chaque ligne :

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

* Cette fonction de transposition ( h) renvoie simplement la liste s'il n'y a aucun élément.

La fonction inverse doit ignorer les []éléments (par exemple [[],[1],[],[3],[4]]-> [[],[4],[],[3],[1]]), elle le fait en recevant deux arguments: le premier est les éléments dans l'ordre inverse (par exemple [4,3,1]) et le second la ligne d'origine.

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 octets

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

Edit: sauvé 3 octets grâce à @ETHproductions.


@ETHproductions Right; Je ne sais pas pourquoi je pensais que ce ne serait pas le cas, sinon je l'aurais déjà fait.
Neil


0

Clojure, 123 octets

#(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)%)

je m'attendais à (+ nil) à lever une exception, mais elle évalue à nil: o

Cela fonctionne sans remplissage, au lieu de cela, il compte combien de lignes précédentes sont au moins aussi longues que la ligne actuelle R.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.