Зворотні стовпчики, зберігаючи форму


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

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⁹правда?) в іншому випадку я мав це ще на один байт
Ерік Аутгольфер

Так, саме це і робить.
Денніс

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

Хороший! Ви можете отримати його до 13 байт , замінюючи l;з Êі mf_Äз ®fÄ.
Кудлатий

Насправді просто mfздається, що це працює для другого рядка.
Кудлатий

@Shaggy Спасибі, не думав про це! mfпозбувся б будь-яких нулів у результаті, хоча, на жаль ...
ETHproductions

Ах, так, не думав про це.
Кудлатий

4

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

-4 завдяки ngn.

Повна програма. Підказки для введення даних від STDIN.

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

Спробуйте в Інтернеті!

Пояснення з прикладом проходження

 запит на оцінений вхід
[[1,8,5],[7,5,4],[],[1]]

* підняти e на силу цього ( e n, що забезпечує відсутність нулів)
[[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?
ngn

@ngn Input ніколи не буде містити негативних цифр; див. розділ "Введення та вихід".
Згарб

@ Zgarb Це ідеально, дякую.
ngn

@ Adám Я відредагував, щоб використовувати ранг 1 замість мікшн-кожен спліт.
ngn

@ 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

Пояснення:

Цей був біль, і я все ще працюю над тим, щоб спростити схилену індексацію.

Замість того, щоб індексувати в, наприклад, 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

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

Спробуйте в Інтернеті!

Безголів / пояснення

Ідея полягає в тому, щоб загорнути всі елементи в []і []прокладати рядки (виявилося коротшим, ніж прокладка з від'ємним цілим числом, це дозволяє також негативні введення, що приємно), потім перенести, повернути всі рядки і знову перемістити і вирівняти кожен рядок :

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) просто повертає список, якщо елементів взагалі немає.

Зворотна функція повинна ігнорувати []елементи (напр. [[],[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

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.