Odwróć kolumny zachowując kształt

20

Wprowadzenie

Załóżmy, że masz listę liczb całkowitych (lub dowolnych obiektów, ale trzymajmy się liczb całkowitych dla uproszczenia). Listy mogą mieć różne długości, a niektóre z nich mogą być puste. Napiszmy listy w formacie tabelarycznym:

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

Tabela ta ma 5 pionowe kolumny, zawierające numery 1, 6, 8, 12, 15, 2, 7, 9, 13, 16, 3, 10, 14, 17, 4, 11, 18, i 5. Jeśli odwrócić każdą kolumnę otrzymujemy list 15, 12, 8, 6, 1, 16, 13, 9, 7, 2, 17, 14, 10, 3, 18, 11, 4, i 5. Podłączmy te liczby z powrotem do kolumn tabeli, zachowując jednakowe długości wierszy:

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

Twoim zadaniem jest wdrożenie tej operacji.

Wejście i wyjście

Twoje dane wejściowe to lista nieujemnych liczb całkowitych reprezentujących wiersze. Rzędy mogą mieć różne długości, a niektóre z nich mogą być puste. Zawsze będzie co najmniej jeden rząd. Twój wynik jest wynikiem odwrócenia każdej kolumny, jak opisano powyżej. Dane wejściowe i wyjściowe mogą mieć dowolny rozsądny format.

Najniższa liczba bajtów w każdym języku wygrywa. Standardowy zasady .

Przypadki testowe

[[]] -> [[]]
[[],[]] -> [[],[]]
[[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]]
Zgarb
źródło
1
Czy możemy wypełnić wiersze danych wyjściowych wartościami null? (np. [[1,9],[3],[2,4,5]] -> [[2,4],[3,null],[1,9,5]])
ETHproductions
@ETHproductions Nie, dane wyjściowe powinny zawierać tylko liczby.
Zgarb
-1, ponieważ nie jest ogólna (nie zezwalaj na liczby ujemne, litery, łańcuchy i wszystkie możliwe typy jako elementy wiersza) + nie podoba mi się (wydaje się to niepotrzebne trudne)
RosLuP 30.01.2018

Odpowiedzi:

5

Galaretka , 16 bajtów

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

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

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.
Dennis
źródło
Fajnie, najwyższa linia jest bardzo sprytna! ( ḟṚṁṣjCzy ⁸ḟ⁹Ṛṁ⁸ṣ⁹¤j⁹tak?) Inaczej miałem to na jeszcze jeden bajt
Eryk Outgolfer
Tak, właśnie to robi.
Dennis
4

Japt , 15 13 bajtów

zapisano 2 bajty dzięki @Shaggy

y@=XfÊX£o
®fÄ

Przetestuj online!

Drugi wiersz można usunąć, jeśli wolno nam uzupełnić wiersze wartościami zerowymi, oszczędzając 4 bajty.

Wyjaśnienie

 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
ETHprodukcje
źródło
Niezłe! Można je dostać w dół do 13 bajtów , zastępując l;z Êi mf_Äz ®fÄ.
Kudłaty
Właściwie mfwydaje się, że działa tylko na drugą linię.
Kudłaty
@Shaggy Thanks, nie myślałem o nich! mf
pozbyłby się
Ach, tak, nie myślałem o tym.
Kudłaty
4

APL (Dyalog Unicode) , 20 19 16 bajtów SBCS

-4 dzięki ngn.

Pełny program Monity o wejście z STDIN.

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

Wypróbuj online!

Objaśnienie z przykładem przejścia

 monit o podanie danych wejściowych
[[1,8,5],[7,5,4],[],[1]]

* podnieść e do potęgi tego ( e n, co zapewni, że nie będzie zer)
[[2.7,2981,148.4],[1096.6,148.4,54.6],[],[2.7]]

 zmieszaj listy w jedną matrycę, wypełniając zerami:
┌ ┐
│2.7E0 3.0E3 1.5E2│
│1.1E3 1.5E2 5.5E1│
│0.0E0 0.0E0 0.0E0│
│2.7E0 0.0E0 0.0E0│
└ ┘

 transponować
┌ ┐
│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 odwróć pozytywne elementy każdego rzędu
┌ ┐
│2.7E0 1.1E3 0.0E0 2.7E0│
│1.5E2 3.0E3 0.0E0 0.0E0│
│5.5E1 1.5E2 0.0E0 0.0E0│
└ ┘

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

 podziel macierz na listę list
[[2.7,148.4,54.6],[1096.6,2981,148.4],[0,0,0],[2.7,0,0]]

0~¨⍨ usuń zera z każdej listy
[[2.7,148.4,54.6],[1096.6,2981,148.4],[],[2.7]]

 naturalny logarytm
[[1,5,4],[7,8,5],[],[1]]

Adám
źródło
Co jeśli wejście zawiera -1?
ngn
@ngn Dane wejściowe nigdy nie będą zawierać liczb ujemnych; patrz sekcja „Wejście i wyjście”.
Zgarb
@Zgarb To idealnie, dziękuję.
ngn
@ Adám Zredagowałem, aby użyć rangi 1 zamiast mieszania każdego podziału.
ngn
@ Adám również: exp / log zamiast + 1 / -1 obejmuje testy z ←fr ← 1287
ngn
3

K4 , 36 bajtów

Rozwiązanie:

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

Przykłady:

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

Wyjaśnienie:

To było uciążliwe, a ja wciąż pracuję nad uproszczeniem indeksowania.

Na przykład zamiast indeksowania w at, x[0]który zwróciłby pierwszy wiersz , chcemy wziąć pierwszą kolumnę , co można zrobić za pomocą x[;0].

Jednak przekazanie zmiennej ydo x[;]traktuje ją jako x[y]nie x[;y]odkładanie jej ::tam:x[::;] .

Jest to równoważne z przerzucaniem listy list, ale przerzucanie wymaga, aby wszystkie listy miały taką samą długość!

+{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
streetster
źródło
3

Haskell , 174 bajty

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

Wypróbuj online!

Niegolfowane / Wyjaśnienie

Chodzi o to, aby owinąć wszystkie elementy []i wypełnić wiersze [](okazało się, że jest krótszy niż wypełnienie ujemną liczbą całkowitą, co pozwala również na ujemne wartości wejściowe, co jest miłe), a następnie transponować, odwrócić wszystkie rzędy i ponownie transponować i spłaszczyć każdy rząd :

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

* Ta funkcja transpozycji (h ) po prostu zwraca listę, jeśli nie ma żadnych elementów.

Funkcja odwrotna musi ignorować []elementy (np. [[],[1],[],[3],[4]]-> [[],[4],[],[3],[1]]), robi to przez otrzymanie dwóch argumentów: Pierwszy to elementy w odwrotnej kolejności (np. [4,3,1]), A drugi pierwotny wiersz.

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
ბიმო
źródło
2

Python 2 , 111 105 92 bajtów

def f(l):x=map(lambda*n:[v for v in n if-1<v],*l);return[map(list.pop,x[:len(k)])for k in l]

Wypróbuj online!

ovs
źródło
Możesz użyć printzamiast returnzapisać bajt.
Jonathan Frech
2

JavaScript (ES6), 79 76 bajtów

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

Edycja: Zapisano 3 bajty dzięki @ETHproductions.

Neil
źródło
@ETHproductions Prawo; Nie mam pojęcia, dlaczego myślałem, że tak się nie stanie, inaczej zrobiłbym to już.
Neil
1

APL (Dyalog Unicode) , 27 bajtów SBCS

≢¨⍴¨∘↓∘⍉⍉∘↑{⍵\⌽⍵/⍺}⍤1∘⍉∘↑=⍨

Wypróbuj online!

ngn
źródło
Myślę, że zastanowiłeś się nad tym.
Adám
Wiedziałem, że mogę skorzystać, @ale nie mam tego.
ngn
0

Clojure, 123 bajty

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

Spodziewałem się (+ nil) się rzucić wyjątek, ale ewaluujenil : o

Działa to bez dopełniania, zamiast tego zlicza ile poprzednich rzędów jest co najmniej tak długich jak bieżący R.

NikoNyrh
źródło