Обратные столбцы при сохранении формы

20

Вступление

Предположим, у вас есть список списков целых чисел (или любых других объектов на самом деле, но для простоты давайте придерживаться целых чисел). Списки могут быть разной длины, и некоторые из них могут быть пустыми. Давайте напишем списки в табличном формате:

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

Эта таблица имеет 5 вертикальных столбцов, содержащее число 1, 6, 8, 12, 15, 2, 7, 9, 13, 16, 3, 10, 14, 17, 4, 11, 18, и 5. Если мы перевернем каждый столбец, мы получим списки 15, 12, 8, 6, 1, 16, 13, 9, 7, 2, 17, 14, 10, 3, 18, 11, 4, и 5. Давайте вставим эти числа обратно в столбцы таблицы, оставив длины строк такими же, как и раньше:

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

Ваша задача - реализовать эту операцию.

Вход и выход

Ваш ввод - это список списков неотрицательных целых чисел, представляющих строки. Строки могут иметь разную длину, а некоторые из них могут быть пустыми. Всегда будет хотя бы один ряд. Ваш вывод является результатом обращения каждого столбца, как описано выше. Ввод и вывод могут быть в любом разумном формате.

Наименьшее количество байтов в каждом языке выигрывает. Применяются стандартные правила .

Контрольные примеры

[[]] -> [[]]
[[],[]] -> [[],[]]
[[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
источник
1
Можем ли мы заполнить строки вывода нулями? (например [[1,9],[3],[2,4,5]] -> [[2,4],[3,null],[1,9,5]])
ETHproductions
@ETHproductions Нет, выходные данные должны содержать только цифры.
Згарб
-1, потому что он не является общим (не допускает использование отрицательных чисел, букв, строк и всех возможных типов в качестве элемента строки) + мне это не нравится (это кажется ненужным сложным)
RosLuP

Ответы:

5

Желе , 16 байт

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

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это устроено

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.
Деннис
источник
Хорошо, что в верхней строке очень умный! ( ḟṚṁṣjДелает ⁸ḟ⁹Ṛṁ⁸ṣ⁹¤j⁹правильно?) В противном случае я имел это в течение еще одного байта
Эрик Outgolfer
Да, это именно то, что он делает.
Деннис
4

Japt , 15 13 байт

сэкономили 2 байта благодаря @Shaggy

y@=XfÊX£o
®fÄ

Проверьте это онлайн!

Вторую строку можно удалить, если нам разрешено заполнять строки нулевыми значениями, сохраняя 4 байта.

объяснение

 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
ETHproductions
источник
Хороший! Вы можете уменьшить его до 13 байт , заменивl; с Êи mf_Äс ®fÄ.
Лохматый
На самом деле, mfкажется, работает на второй линии.
Лохматый
@ Shaggy Спасибо, не думал об этом! mfизбавиться от любых нулей в результате, хотя, к сожалению ...
ETHproductions
Ах, да, не думал об этом.
Лохматый
4

APL (Dyalog Unicode) , 20 19 16 байтов SBCS

-4 благодаря нгн.

Полная программа. Запрашивает ввод из STDIN.

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

Попробуйте онлайн!

Пояснение с примером прохождения

 запросить оцененный ввод
[[1,8,5],[7,5,4],[],[1]]

* повышение е к власти , что ( е п , которое гарантирует , что не будет никаких нулей)
[[2.7,2981,148.4],[1096.6,148.4,54.6],[],[2.7]]

 смешать списки в одну матрицу, дополняя нулями:
┌ ┐
│2.7E0 3.0E3 1.5E2│
│1.1E3 1.5E2 5.5E1│
│0.0E0 0.0E0 0.0E0│
│2.7E0 0.0E0 0.0E0│
└ ┘

 транспонирования
┌ ┐
│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 поменять положительные элементы каждого ряда
┌ ┐
│2.7E0 1.1E3 0.0E0 2.7E0│
│1.5E2 3.0E3 0.0E0 0.0E0│
│5.5E1 1.5E2 0.0E0 0.0E0│
└ ┘

 транспонирования
┌ ┐
│2.7E0 1.5E2 5.5E1│
│1.1E3 3.0E3 1.5E2│
│0.0E0 0.0E0 0.0E0│
│2.7E0 0.0E0 0.0E0│
└ ┘

 разбить матрицу на список списков
[[2.7,148.4,54.6],[1096.6,2981,148.4],[0,0,0],[2.7,0,0]]

0~¨⍨ удалить нули из каждого списка
[[2.7,148.4,54.6],[1096.6,2981,148.4],[],[2.7]]

 натуральный логарифм
[[1,5,4],[7,8,5],[],[1]]

Адам
источник
Что если вход содержит -1?
NNN
@ngn никогда не будет содержать отрицательных чисел; см. раздел «Ввод и вывод».
Згарб
@ Zgarb Отлично, спасибо.
НГН
@ Adám Я отредактировал, чтобы использовать ранг 1 вместо mix-each-split.
НГН
@ Adám также: exp / log вместо + 1 / -1 покрывает тесты с помощью ⎕fr ← 1287
ngn
3

К4 , 36 байт

Решение:

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

Примеры:

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

Объяснение:

Это было болезненно, и я все еще работаю над упрощением индексирования.

Например, вместо индексации в at, x[0]которая возвращает первую строку , мы хотим взять первый столбец , что можно сделать с помощью x[;0].

Однако проходя переменный yв x[;]лакомства как делать x[y]не x[;y]значит , толкая ::там: x[::;].

Это эквивалентно переворачиванию списка списков, но переворот требует, чтобы все списки были равной длины!

+{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
источник
3

Haskell , 174 байта

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

Попробуйте онлайн!

Ungolfed / Пояснение

Идея состоит в том, чтобы обернуть все элементы []и дополнить строки [](оказалось, что они короче, чем заполнение отрицательным целым числом, это также допускает и отрицательные входные данные) :

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

* Эта функция транспонирования ( h) просто возвращает список, если элементов вообще нет.

Функция reverse должна игнорировать []элементы (например, [[],[1],[],[3],[4]]-> [[],[4],[],[3],[1]]), для этого она получает два аргумента: первый - это элементы в обратном порядке (например, [4,3,1]), а второй - исходная строка.

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

Python 2 , 111 105 92 байта

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]

Попробуйте онлайн!

овс
источник
Вы можете использовать printвместо того, returnчтобы сохранить байт.
Джонатан Фрех
2

JavaScript (ES6), 79 76 байт

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

Редактировать: 3 байта сохранены благодаря @ETHproductions.

Нил
источник
@ETHproductions Right; Я понятия не имею, почему я так думал, иначе я бы уже это сделал.
Нил
0

Clojure, 123 байта

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

Я ожидал (+ nil)выбросить исключение, но оно оценивается в nil: o

Это работает без заполнения, вместо этого он подсчитывает, сколько из предыдущих строк по крайней мере столько же, сколько текущая строка R.

NikoNyrh
источник