Кортежи, последовательно просматривая записи в списке списков

9

Вызов:

Получив список непустых списков целых чисел, верните список кортежей следующего вида: кортежи первого списка, начинающиеся с каждого элемента первого списка, за которым следует первый элемент каждого последующего списка, так что i-й кортеж должен быть [ith element of first list, first element of second list, ... , first element of last list]. Например:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]] => [[1, 4, 7], [2, 4, 7], [3, 4, 7], ...

Затем выполните кортежи формы [last element of first list, ith element of second list, first element of third list, ..., first element of last list], поэтому в нашем примере это будет:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]] =>  ..., [3, 4, 7], [3, 5, 7], [3, 6, 7], ...

Продолжайте с каждым оставшимся списком, пока не доберетесь до [last element of first list, ..., last element of second to last list, ith element of last list]:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]] => ..., [3, 6, 7], [3, 6, 8], [3, 6, 9]]

Полный вывод выглядит следующим образом:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]] => 
        [[1, 4, 7], [2, 4, 7], [3, 4, 7], [3, 5, 7], [3, 6, 7], [3, 6, 8], [3, 6, 9]]

Несколько шаблонов для хорошей меры:

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

Примеры:

[] => [[]] (or an error, thanks to ngn for correcting the output in this case)

[[1]] => [[1]]

[[1, 2], [3, 4], [5]] => [[1, 3, 5], [2, 3, 5], [2, 4, 5]]

[[1], [2], [5, 6], [3], [4]] => [[1, 2, 5, 3, 4], [1, 2, 6, 3, 4]]

[[1, 2, 3], [4, 5]] => [[1, 4], [2, 4], [3, 4], [3, 5]]

[[1, 2, 3], []] => unspecified behavior (can be an error)

[[3, 13, 6], [9, 2, 4], [5, 10, 8], [12, 1, 11], [7, 14]] => 
     [[3, 9, 5, 12, 7], [13, 9, 5, 12, 7], [6, 9, 5, 12, 7], [6, 2, 5, 12, 7], 
      [6, 4, 5, 12, 7], [6, 4, 10, 12, 7], [6, 4, 8, 12, 7], [6, 4, 8, 1, 7], 
      [6, 4, 8, 11, 7], [6, 4, 8, 11, 14]]  

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

Если у кого-то есть лучшее название, дайте мне знать.

капот
источник
1
У меня есть чувство, которое [] => []действительно должно быть, [] => [[]]но я не могу найти слов, чтобы объяснить, почему.
нгн
1
@ngn Вы правы, это должно быть [[]]потому, что существует один пустой кортеж с одной записью из каждого (нулевого) подсписка. Возможно, это слишком раздражает, чтобы программы правильно выводили это, поэтому я скажу, что в этом нет необходимости.
Капюшон
1
[]Строго говоря, Да - это пустой список непустых списков, но выходные данные неоднозначны между []и [[]]если это разрешенный ввод. («Кортежи первого списка, начинающиеся с каждого элемента первого списка ...» - первого списка нет, так что мы закончили -> [])
Джонатан Аллан
1
@JonathanAllan Теперь я убежден, что «правильный» вывод для []должен быть [[]]. Например, количество выходных кортежей - это то, sum(inner list lengths) - length of outer list + 1что в пустом случае дает 1длина, [[]]а не длина []. Это немного педантичный вопрос, хотя ...
Капюшон
1
Можем ли мы предположить, что все записи различны? Или, более сильно, перестановка на 1..n как в ваших примерах?
xnor

Ответы:

5

JavaScript (ES6), 59 байт

Ожидается список списков натуральных чисел.

f=a=>[a.map(a=>a[0]),...a.some(a=>a[1]&&a.shift())?f(a):[]]

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

Как?

На каждой итерации:

  • Мы выводим новый список, состоящий из первого элемента каждого списка.
  • Мы удаляем первый элемент первого списка, содержащий как минимум 2 элемента, и повторяем процесс. Или мы прекращаем рекурсию, если такого списка не существует.
Arnauld
источник
1
Этот a.someтрюк потрясающий!
ETHproductions
1
@ETHproductions Теперь ищем вызов, где использование awe.someне будет пустой тратой байтов ... :)
Арнаулд
2

Python 2 , 62 байта

lambda M:[zip(*M)[l.pop(0)*0]for l in M+[[1,1]]for _ in l[1:]]

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

Использование поп-идеи Часа Брауна, вдохновленной представлением Арнаулда в JS .


Python 2 , 68 байт

M=input()
for l in[[0,0]]+M:
 for x in l[1:]:l[0]=x;print zip(*M)[0]

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

Изменяет первые элементы списков, чтобы сохранить нужные значения. Это [[0,0]]+ужасный хак для печати начальных первых значений.

XNOR
источник
2

Желе , 15 байт

ẈṚṪ×€PƊƤFQṚCịŒp

Попробуйте онлайн! (нижний колонтитул отображает фактический возвращенный список, а не представление Jelly)

Как?

Указатели в декартово произведение списков в необходимых точках ...

ẈṚṪ×€PƊƤFQṚCịŒp - Link: list of lists  e.g. [[6,8,4,9],[7,1,5],[3,2]]
Ẉ               - length of each            [4,3,2]
 Ṛ              - reverse                   [2,3,4]
       Ƥ        - for each prefix:             [2]      [2,3]      [2,3,4]
      Ɗ         -   last 3 links as a monad:
  Ṫ             -     tail (pop rightmost)     2        3          4
     P          -     product (of remaining)   1        2          6
    €           -     for €ach (range tail)    [1,2]    [1,2,3]    [1,2,3,4]   
   ×            -       multiply               [1,2]    [2,4,6]    [6,12,18,24]
        F       - flatten                   [1,2,2,4,6,6,12,18,24]
         Q      - de-duplicate              [1,2,4,6,12,18,24]
          Ṛ     - reverse                   [24,18,12,6,4,2,1]
           C    - complement (1-x)          [-23,-17,-11,-5,-3,-1,0]
             Œp - Cartesian product (of the input)
                -         -> [[6,7,3],[6,7,2],[6,1,3],[6,1,2],[6,5,3],[6,5,2],[8,7,3],[8,7,2],[8,1,3],[8,1,2],[8,5,3],[8,5,2],[4,7,3],[4,7,2],[4,1,3],[4,1,2],[4,5,3],[4,5,2],[9,7,3],[9,7,2],[9,1,3],[9,1,2],[9,5,3],[9,5,2]]
            ị   - index into (1-based & modular)
                -   indexes:      -23,                                            -17,                                            -11,                                             -5,             -3,             -1,     0
                -    values: [[6,7,3],                                        [8,7,3],                                        [4,7,3],                                        [9,7,3],        [9,1,3],        [9,5,3],[9,5,2]]
                -         -> [[6,7,3],[8,7,3],[4,7,3],[9,7,3],[9,1,3],[9,5,3],[9,5,2]]

ẈṚ’ṣ1T$¦ƬUṚị"€(14 байт) не выполняется для входных данных с (не завершающей) длиной один список; а может быть ṣ1T$можно заменить чем-то другим?

Джонатан Аллан
источник
2

K (нгн / к) , 40 21 19 18 байт

{x@'/:?|\+|!|#:'x}

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

использует идеи из ответа @ H.PWiz

{ } функция с аргументом x

#:' длина каждого

| обеспечить регресс

! все индексные кортежи для массива с такими измерениями как столбцы в матрице (список списков)

| обеспечить регресс

+ транспонирования

|\ бегущие максимумы

? уникальный

x@'/: использовать каждый кортеж справа в качестве индексов в соответствующих списках из x

СПП
источник
1

Древесный уголь , 33 байта

IE⊕ΣEθ⊖LιEθ§λ⌈⟦⁰⌊⟦⊖Lλ⁻ι∧μΣE…θμ⊖Lν

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

Приведите целые числа к строкам перед неявной печатью, используя формат вывода по умолчанию для списков, каждый элемент которого находится на отдельной строке, а вложенные списки с двойным интервалом.

E⊕ΣEθ⊖Lι

Возьмите сумму длин списков и вычтите длину списка списков. Затем цикл от 0 до этого значения включительно.

Eθ§λ

Карта по списку списков и индекс в каждом списке.

⌈⟦⁰⌊⟦⊖Lλ

Зафиксируйте индекс до 0 и последний индекс в списке. (Закрывающие скобки подразумеваются.)

⁻ι∧μΣE…θμ⊖Lν

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

Нил
источник
1

APL (Dyalog Classic) , 32 30 27 байтов

1↓¨∪⊃{(⍵,¨⊃⍺),⍺,¨⍨⊢/⍵}/⌽0,⎕

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

полная программа, ввод с клавиатуры ( )

для входных []выходов [[]](их APL эквиваленты 0⍴⊂⍬и,⊂⍬ )

предполагает уникальность чисел на входе

СПП
источник
1
Не то, чтобы это имело значение для вывода, но я думаю, что вход для второго теста должен быть,⊂,1
H.PWiz
@ H.PWiz верно, исправлено, ура
нг
1

JavaScript (ES6), 58 54 байта

h=(x,s)=>[x.map(y=>s|y?y[0]:s=y.shift()),...s?h(x):[]]

После 14+ попыток проиграть мой код (удалив все экземпляры циклов while pushи concat), я пришел к итерации, алгоритмически подобной ответу @ Arnauld , что неудивительно, учитывая, насколько он лаконичен!

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

58 байт

Для еще 1 байта замена s = y.shift()на y.shift(s = 1)должна обрабатывать все целые числа (предположительно, поскольку я лично не проверял это).

h=(x,s)=>[x.map(y=>!s/y[1]?s=y.shift():y[0]),...s?h(x):[]]

58 байт

Бонусная версия, с небольшой перестановкой:

h=x=>[x.map(y=>s&&y[1]?y.shift(s=0):y[0],s=[]),...s||h(x)]

объяснение

Ранние версии кода пытались изменить клон (массив) первых элементов каждого массива, но дополнительный шаг инициализации этого массива был дорогим ... пока я не понял, что отображение первых элементов каждого массива было примерно операция "only" необходима, если я изменяю исходные массивы.

Использует логический флаг, чтобы проверить, был ли какой-либо массив еще смещен (т.е. укорочен). В дальнейшем проверили условную проверку, наблюдая, что JS приводит массивы с числовым значением в качестве единственного элемента к этому числу, одновременно приводя массивы с несколькими значениями, такими как NaN.

var
h = (x, s) => 
    [
        x.map(y =>                 // map to first element of each array
            s|y                    // if s == 1 (i.e. an array has been shortened)
                                   // or the current array y has length == 1
                ? y[0]
                : s = y.shift()    // remove first element of y and set s to truthy
        ),
        ...s ? h(x) : []           // only concatenate a recurrence of the function if an array has had a value removed
    ]
избыточность
источник
1

APL (Dyalog) , 15 байт ( SBCS )

Спасибо ngn за указание на ненужный байт

{∪⌈\,⍉⍳≢¨⍵}⊃¨¨⊂

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

{∪⌈\,⍉⍳≢¨⍵}генерирует списки для индексации на входе. например(1 2 3) (4 5 6) (7 8 9) -> (0 0 0) (1 0 0) (2 0 0) (2 1 0) (2 2 0) (2 2 1) (2 2 2)

≢¨⍵: длина каждого списка во входных данных

,⍉⍳создает все комбинации чисел вплоть до его ввода. например2 3 -> (0 0) (1 0) (0 1) (1 1) (0 2) (1 2)

⌈\: сканирование с максимумом. например, приведенный выше пример будет(0 0) (1 0) (1 1) (1 1) (1 2) (1 2)

: удалить дубликаты

⊃¨¨⊂ выполняет индексацию, помня о глубине любого аргумента

H.PWiz
источник
Отличный ответ! Ты побил меня почти на половину моих байтов. кажется ненужным .
СПП
@ngn Хорошо, я не могу вспомнить, что заставило меня думать, что это было. Спасибо!
H.PWiz