Tuplas, percorrendo sequencialmente as entradas na lista de listas

9

Desafio:

Dada uma lista de listas não vazias de números inteiros, retorne uma lista de tuplas da seguinte forma: Primeira lista de tuplas começando com cada elemento da primeira lista, seguida pelo primeiro elemento de cada lista subseqüente, portanto a i-ésima tupla [ith element of first list, first element of second list, ... , first element of last list]. Por exemplo:

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

Em seguida, faça tuplas do formulário [last element of first list, ith element of second list, first element of third list, ..., first element of last list], portanto, em nosso exemplo, isso seria:

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

Continue com cada lista restante até chegar a [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]]

A saída completa é a seguinte:

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

Alguns boilerplate para uma boa medida:

  • Se você deseja que a entrada seja listas de strings ou listas de números inteiros positivos, tudo bem. A questão é sobre manipulação de listas, não sobre o que está nas listas.
  • A entrada e a saída podem estar em qualquer formato aceitável .
  • É permitido um programa ou função completo.
  • As brechas padrão não são permitidas por padrão.
  • Esta questão é código de golfe, portanto, a menor contagem de bytes vence.

Exemplos:

[] => [[]] (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]]

Se alguém tiver um título melhor, me avise.

de capuz
fonte
11
Tenho um sentimento que [] => []realmente deveria ser, [] => [[]]mas não consigo encontrar as palavras para explicar o porquê.
NGN
11
@ngn Você está certo, deve ser [[]]porque existe uma única tupla vazia com uma entrada de cada uma das sublistas (zero). Provavelmente é muito chato exigir que os programas produzam corretamente isso, então direi que não é necessário.
Hood
11
Sim [], estritamente falando, é uma lista vazia de listas não vazias, mas a saída é ambígua entre []e [[]]se é uma entrada permitida. ( "Primeira lista tuplas começando com cada elemento da primeira lista ..." - não há primeira lista, de modo que estamos a fazer -> [])
Jonathan Allan
11
@ JonathanAllan Agora estou convencido de que a saída "correta" para []deveria ser [[]]. Por exemplo, o número de tuplas de saída é o sum(inner list lengths) - length of outer list + 1que, no caso vazio, fornece 1, qual é o comprimento, [[]]mas não o comprimento []. Porém, isso é um problema pedante ...
Hood
11
Podemos assumir que todas as entradas são distintas? Ou, mais fortemente, uma permutação em 1..n como em seus exemplos?
Xnor

Respostas:

5

JavaScript (ES6), 59 bytes

Espera uma lista de listas de números inteiros positivos .

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

Experimente online!

Como?

Em cada iteração:

  • Nós produzimos uma nova lista que consiste no primeiro elemento de cada lista.
  • Removemos o primeiro elemento da primeira lista que contém pelo menos 2 elementos e repetimos o processo. Ou paramos a recursão se essa lista não existir.
Arnauld
fonte
11
Esse a.sometruque é incrível!
ETHproductions
11
@ETHproductions Agora, olhando para um desafio onde o uso awe.somenão seria um desperdício de bytes ... :)
Arnauld
2

Gelatina , 15 bytes

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

Experimente online! (o rodapé exibe a lista retornada real em vez de uma representação Jelly)

Como?

Índices no produto cartesiano das listas nos pontos necessários ...

ẈṚṪ×€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 bytes) falha para entradas com o comprimento (não final) de uma lista; mas talvez ṣ1T$possa ser substituído por outra coisa?

Jonathan Allan
fonte
2

K (ngn / k) , 40 21 19 18 bytes

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

Experimente online!

usa idéias da resposta de H.PWiz

{ } função com argumento x

#:' comprimento de cada

| marcha ré

! todas as tuplas de índice para uma matriz com essas dimensões como colunas em uma matriz (lista de listas)

| marcha ré

+ transpor

|\ maxima em execução

? único

x@'/: use cada tupla à direita como índices nas listas correspondentes de x

ngn
fonte
1

Carvão , 33 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

Converta os números inteiros em seqüências de caracteres antes de imprimir implicitamente, usando o formato de saída padrão para listas, que é cada item em sua própria linha, e listas aninhadas em espaço duplo.

E⊕ΣEθ⊖Lι

Pegue a soma dos comprimentos das listas e subtraia o comprimento da lista de listas. Em seguida, faça um loop de 0 a esse valor, inclusive.

Eθ§λ

Mapeie a lista de listas e o índice em cada lista.

⌈⟦⁰⌊⟦⊖Lλ

Fixar o índice em 0 e o último índice na lista. (Os colchetes estão implícitos.)

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

Após a primeira lista, subtraia os comprimentos decrescentes de todas as listas anteriores do índice mais externo. (Isso não funciona para a primeira lista porque o comprimento das listas está vazio e a soma não é um número.)

Neil
fonte
1

Python 2 , 72 bytes

f=lambda a:zip(*a)[:1]+(any(len(u)>1and u.pop(0)for u in a)and f(a)or[])

Experimente online!

Esta é uma porta Python do excelente algoritmo Javascript de Arnauld .

Chas Brown
fonte
1

APL (Dyalog Classic) , 32 30 27 bytes

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

Experimente online!

programa completo, a entrada é do teclado ( )

para []saídas de entrada [[]](seus equivalentes APL são 0⍴⊂⍬e ,⊂⍬)

assume exclusividade de números na entrada

ngn
fonte
11
Não que isso faz a diferença para a saída, mas acho que a entrada para o segundo teste deve ser,⊂,1
H.PWiz
@ H.PWiz isso mesmo, fixo,
felicidades
1

JavaScript (ES6), 58 54 bytes

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

Após mais de 14 tentativas de descartar meu código (removendo todas as instâncias de while loops,, pushe concat), cheguei a uma iteração algoritmicamente semelhante à resposta de @ Arnauld , sem surpresa, dada a sua sucessão!

Aceita uma lista de listas de números inteiros positivos. Experimente online!

58 bytes

Por mais 1 byte, substituir s = y.shift()por y.shift(s = 1)deve lidar com todos os números inteiros (presumivelmente, como eu não o testei pessoalmente).

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

58 bytes

Versão bônus, com leve reorganização:

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

Explicação

As primeiras versões do código tentavam modificar um clone (de uma matriz) dos primeiros elementos de cada matriz, mas a etapa extra de inicializar essa matriz era cara ... até eu perceber que o mapeamento dos primeiros elementos de cada matriz era aproximadamente a operação "única" necessária se eu alterar as matrizes originais.

Usa um sinalizador booleano para verificar se alguma matriz foi deslocada (ou seja, reduzida) ainda. Golpeou ainda mais a verificação condicional observando que JS coage matrizes com um valor numérico como seu único elemento nesse número, enquanto coagindo matrizes com vários valores como 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
    ]
redundância
fonte
1

APL (Dyalog) , 15 bytes ( SBCS )

Obrigado ngn por apontar um byte desnecessário

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

Experimente online!

{∪⌈\,⍉⍳≢¨⍵}gera listas para indexar na entrada. por exemplo(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)

≢¨⍵: o comprimento de cada lista na entrada

,⍉⍳cria todas as combinações de números até a entrada. por exemplo2 3 -> (0 0) (1 0) (0 1) (1 1) (0 2) (1 2)

⌈\: digitalize com o máximo. por exemplo, o exemplo acima seria agora(0 0) (1 0) (1 1) (1 1) (1 2) (1 2)

: remover duplicatas

⊃¨¨⊂ faz a indexação, atento à profundidade de qualquer argumento

H.PWiz
fonte
Ótima resposta! Você me venceu quase pela metade dos meus bytes. parece desnecessário .
NGN
@ngn Nice, não me lembro o que me levou a pensar que era. Obrigado!
H.PWiz
0

Python 2 , 91 bytes

f=lambda a,p=():a and[p+(q,)+zip(*a)[0][1:]for q in a[0][p>():]]+f(a[1:],p+(a[0][-1],))or[]

Experimente online!

Chas Brown
fonte