Listar * todas * as tuplas!

35

Escreva um programa, com uma entrada n , gerará todas as n-tuplas possíveis usando números naturais.

n=1
(1),(2),(3),(4),(5),(6)...

n=2
(1,1),(1,2),(2,1),(2,2),(1,3),(3,1),(2,3),(3,2),(3,3)...

n=6
(1,1,1,1,1,1) (1,1,1,1,2,1) (1,1,1,2,1,1)... 
  • A saída pode estar em qualquer ordem que não quebre outras regras.
  • O programa deve ser escrito para ser executado para sempre e listar todas as tuplas aplicáveis ​​exatamente uma vez, em teoria.
    • Na realidade, seu programa alcançará o limite e a falha do seu número inteiro. Isso é aceitável desde que o programa seja executado infinitamente, se apenas o seu tipo inteiro for ilimitado.
    • Cada tupla válida deve ser listada dentro de um tempo finito, se apenas o programa tiver permissão para executar esse período.
  • A saída pode, a seu critério, incluir zeros além dos números naturais.
  • Você pode escolher o formato de saída do seu programa para sua conveniência, desde que a separação entre tuplas e números dentro de cada tupla seja clara e consistente. (Por exemplo, uma tupla por linha.)
  • A entrada (n) é um número inteiro de um a seis. O comportamento necessário é indefinido para entradas fora desse intervalo.
  • Aplicam-se as regras do código-golfe, as vitórias mais curtas do programa.

Obrigado a "Artemis Fowl" pelo feedback durante a fase do sandbox.

billpg
fonte
Presumo que seja válido se, quando o programa falhar, produz alguma saída estranha, além das tuplas impressas até agora, certo?
Luis Mendo
11
Devemos produzir à medida que avançamos ou seria suficiente uma função que produza uma lista infinita no final dos tempos?
Jonathan Allan
6
"Você pode escolher o formato de saída do seu programa para sua conveniência, desde que a separação entre as tuplas e os números dentro de cada tupla seja clara e consistente" - podemos gerar uma separação diferente (embora sempre consistente) (por exemplo, assim )?
Jonathan Allan
@ JonathanAllan Eu teria que incluir a saída do conteúdo infinito desse objeto como parte do programa.
billpg
11
Relacionados (números inteiros em vez de números naturais)
Esolanging Fruit

Respostas:

24

Casca , 2 bytes

πN

Experimente online!

Explicação

Né a lista infinita de números naturais [1,2,3,4,... πé o poder cartesiano. Resultado é uma lista infinita de listas. Cada lista do comprimento desejado ocorre exatamente uma vez porque πé legal assim. Entrada e saída estão implícitas.

Zgarb
fonte
11
Uau, e isso também não [1,1, n]. Existe um padrão para a ordem que ele gera?
billpg
11
@billpg Constrói as tuplas recursivamente: n- as tuplas são obtidas pegando o produto cartesiano da lista original e da lista de n-1-tuples, em ordem crescente da soma dos índices.
Zgarb 16/04
"ordem crescente da soma dos índices" - Você pode esclarecer isso? Estou tendo problemas para ver por que, por exemplo, 2,2,2vem depois 4,1,2e 5,1,1.
Jonah
2
@Jonah A recursão funciona assim. Você começa com 1 tupla N. Para duas tuplas, você toma o produto cartesiano com a Nordem da soma dos índices. Nas duas listas, cada número nestá no índice; nportanto, para o comprimento 2, o resultado é ordenado pela soma. Para obter três tuplas, você pega o produto cartesiano Ne a lista de duas tuplas, ordenadas pela soma dos índices dos elementos nessas listas. Ele não olha para a soma da tupla, mas para sua posição na lista de tuplas.
Zgarb 16/04
2
"Descubra as diferentes dimensões do infinito nesta tarefa e encontre um padrão que o reduza ao infinito contável, depois escreva um programa que itere sobre esse padrão". - "Ei, eu tenho um construído para isso!"
Fabian Röling
10

Haskell , 62 bytes

([1..]>>=).(!)
0!s=[[]|s<1]
n!s=[a:p|a<-[1..s],p<-(n-1)!(s-a)]

Experimente online!

n!sgera todos os n-tuplos que somam s.

Então a resposta é ([1..]>>=).(!), ie \n -> [t | s<-[1..], t<-n!s].

Esta é uma função que mapeia um número inteiro n para uma lista lenta infinita de tuplas (listas de números inteiros).

Lynn
fonte
5

Haskell , 50 bytes

f n=[l|k<-[0..],l<-mapM([0..k]<$f)[0..n],sum l==k]

Experimente online!

Lista n-tuplos classificados por soma. mapMfaz o trabalho pesado para gerar todos os npares de números de 0 a k. O <$ftruque é explicado aqui .

Haskell , 51 bytes

f 1=pure<$>[0..]
f n=[a-k:k:t|a:t<-f$n-1,k<-[0..a]]

Experimente online!

Recursivamente estende todos os n-1-tuplos em todos n-tuplos, dividindo o primeiro número ade cada n-1-tuplo em dois números a-k,kque somam a ele, de todas as maneiras possíveis.

xnor
fonte
4

Pitão - 9 bytes

Obrigado a @FryAmTheEggman pelo golfe

Passa por todo x, e leva [1..x] ^ n. Isso cria duplicatas, portanto, apenas mantém as que são novas no x, também conhecidas como x. A formatação é um pouco estranha, mas pode ser padronizada com mais um byte,.V1j}#b^Sb

.V1}#b^Sb

Experimente online .

Maltysen
fonte
11
f}bT-> }#bAlém disso, sua contagem de bytes parece estar incorreta no momento?
FryAmTheEggman 16/04
@FryAmTheEggman espera, por que está incorreto? Se você está falando sobre o link TIO, isso inclui a formatação com j(b). Além disso, obrigado pelo golfe.
Maltysen 17/04
Ah, foi isso que me confundiu, desculpe!
FryAmTheEggman 17/04
3

Brachylog (v2), 9 bytes

~l.ℕᵐ+≜∧≜

Experimente online!

Este é um gerador infinito que gera todas as tuplas possíveis. O link TIO possui um cabeçalho que usa o gerador para gerar 1000 elementos e os imprime (mas o gerador poderia continuar indefinidamente se eu pedisse isso; os números inteiros de Brachylog são ilimitados).

Parece que deve haver uma maneira mais tersa, mas há muitas restrições e esse é o melhor que posso ajustá-las em um único programa.

Explicação

~l.ℕᵐ+≜∧≜
  .        Generate
        ≜  all explicit
~l         lists whose length is {the input}
    ᵐ      for which every element
   ℕ       is non-negative
     +     and whose sum
      ≜    is used to order the lists (closest to zero first)
       ∧   [remove unwanted implicit constraint]

Aliás, me parece interessante o quão diferentes são minhas explicações sobre os dois , apesar de fazerem exatamente a mesma coisa do ponto de vista de Brachylog. O primeiro é o primeiro predicado não determinístico do programa, portanto define a ordem dos resultados; nesse caso, calcula todos os valores explícitos possíveis para a soma da lista na ordem 0, 1, 2, 3… e está sendo usado para garantir que as listas sejam exibidas na ordem da sua soma (isso garante que cada possível lista aparece após uma quantidade finita de saída). O segundo é usado para calcular todas as possibilidades explícitas da lista (em vez de gerar uma fórmula especificando como os elementos da lista se relacionam).

ais523
fonte
↰₁ẉ⊥também é um bom cabeçalho, para impressão infinita.
String não relacionada
Embora eu ache que essa pode não ser uma resposta completa, uma vez que qualquer invocação independente independente desse predicado gera apenas zeros , com a parte "generate all" sendo executada pelo ou no cabeçalho.
String não relacionada
11
@UnrelatedString Seu código não usa o predicado como gerador. Temos regras explícitas que permitem a saída da lista usando um gerador . O que você está fazendo no seu link TIO é chamar o predicado em um loop para obter 1000 geradores diferentes e, em seguida, obter a primeira saída de cada um deles; essa é uma operação realmente antinatural a ser executada em geradores e não permitirá que você veja os outros elementos que eles podem gerar.
ais523 15/04
Ah, então acabei de interpretar mal a semântica do que é um predicado Brachylog esse tempo todo - minha ideia de "gerador" está presa no Python. Agora que isso está direto na minha cabeça, acho que vou raspar três bytes de algumas das minhas respostas antigas.
String não relacionada
2

Perl 6 , 37 bytes

{$++.polymod(1+$++ xx $_-1).say xx *}

Experimente online!

É executado essencialmente polymodcom o número de entradas necessárias, onde o módulo é sempre maior que a entrada, ou seja, 0.polymod (1,1,1), 1.polymod (2,2,2) etc. Dessa forma, o dígito está sempre dentro o intervalo. Perl6 não vai me deixar módulo infinito ...

Phil H
fonte
5
Isso não lista todas as tuplas exatamente uma vez (por exemplo, (0, 1, 0, 0)não está listado).
bb94 15/04
2

C # (compilador interativo do Visual C #) , 148 bytes

n=>{var a=new int[n];int j=0;void g(int k){if(k<n)for(int i=0;i++<j;g(k+1))a[k]=i;else if(a.Sum()==j)WriteLine(string.Join(' ',a));}for(;;j++)g(0);}

Experimente online!

-3 bytes graças a @ASCIIOnly!

// n: size of tuples to generate
n=>{
  // a: current tuple workspace
  var a=new int[n];
  // j: target sum value
  int j=0;
  // recursive function that works on slot k
  void g(int k){

    // tuple is not fully generated,
    if(k<n)

      // try all values from (0,j]
      for(int i=0;i++<j;
        // recursive call - generates all
        // values from (0,j] in the next slot
        g(k+1)
      )
        // update the kth slot
        a[k]=i;

    // tuple is fully generated, however
    // we should only display if the sum
    // is equal to the target sum. tuples
    // are generated many times, this
    // let's us enforce that they are only
    // displayed once.
    else if(a.Sum()==j)
      WriteLine(string.Join(' ',a));
  }
  // increment the high value forever
  // while continually starting the
  // recursive function at slot 0
  for(;;j++)
    g(0);
}
dana
fonte
como você fez isso
Stackstuck 18/04
A portabilidade direta para o .NET Core provavelmente ainda me pouparia muitos bytes.
Stackstuck 18/04
O maior truque aqui é a recursão. A maioria das técnicas que eu já vi para gerar "permutações" a usa. Eu pretendo adicionar uma explicação.
dana
Writecom, por exemplo, '<literal tab>'ou |tem o mesmo comprimento e ocupa muito menos linhas: P
ASCII-only
11
aw , 151
somente ASCII
1

Gelatina , 10 (9?) Bytes

9, se pudermos produzir usando separação não consistente (sobre a qual perguntei) - remoção do .

‘ɼṗ³ċƇ®Ṅ€ß

Experimente online!

Quão?

‘ɼṗ³ċƇ®Ṅ€ß - Main Link: some argument, x (initially equal to n, but unused)
 ɼ         - recall v from the register (initially 0), then set register to, and yield, f(v)
‘          -   f = increment
           - (i.e. v=v+1)
   ³       - program's third command line argument (1st program argument) = n
  ṗ        - (implicit range of [1..v]) Cartesian power (n)
           - (i.e. all tuples of length n with items in [1..v])
     Ƈ     - filter keep those for which:
    ċ      -   count
      ®    -   recall from register
           - (i.e. keep only those containing v)
       Ṅ€  - print €ach
         ß - call this Link with the same arity
           - (i.e. call Main(theFilteredList), again the argument is not actually used)
Jonathan Allan
fonte
11
Com base em " desde que a separação entre as tuplas e os números dentro de cada tupla seja clara e consistente. (Por exemplo, uma tupla por linha.) " Presumi que não era permitido e é necessário, mas vamos aguardar o que o OP deve fazer dizer.
Kevin Cruijssen 15/04
1

05AB1E , 15 11 bytes

[¼¾LIãvy¾å—

-4 bytes através da criação de uma porta de @Maltysen resposta Pyth 's .

Experimente online.

Explicação:

[             # Start an infinite loop:
 ¼            #  Increase the counter_variable by 1 (0 by default)
  ¾L          #  Create a list in the range [1, counter_variable]
    Iã        #  Take the cartesian power of this list with the input
      v       #  Loop over each list `y` in this list of lists:
       y¾å    #   If list `y` contains the counter_variable:
             #    Print list `y` with trailing newline
Kevin Cruijssen
fonte
2
Quando o programa chegará a [1,2,1]? Lembre-se de que deve ser dentro de um tempo finito.
billpg 15/04
@billpg Deve ser corrigido agora.
Kevin Cruijssen 15/04
1

MATL , 16 bytes

`@:GZ^t!Xs@=Y)DT

As tuplas são ordenadas por soma crescente e, dentro de uma determinada soma, são ordenadas lexicograficamente.

Experimente online!

Luis Mendo
fonte
1

Python 2 , 126 112 106 101 100 83 bytes

n=input()
i=1
while 1:
 b=map(len,bin(i)[3:].split('0'));i+=1
 if len(b)==n:print b

Experimente online!

5 bytes thx para mypetlion ; 1 byte do olho de águia do ArBo ; 17 bytes do xnor !

Construa as partições ordenadas de mem ncompartimentos para m = 0,1,2,3,..., selecionando números binários com n-1 0s e m 1s.

Chas Brown
fonte
if i==p:i=0;p*=2pode tornar i%=p;p<<=i<1- se para salvar 5 bytes.
mypetlion 15/04
Tenho certeza de que o espaço depois print bnão é necessário: D
ArBo 16/04
Parece que i+pestá apenas contando 1, 2, 3 ... de uma maneira complicada e, portanto, pode ser apenas uma variável única.
xnor 16/04
@xnor: D'oh! Fiquei tão envolvido com o conceito que não conseguia ver a floresta para as árvores.
Chas Brown
1

C # (.NET Core) , 608 570 567 bytes

using C=System.Console;using L=System.Collections.Generic.List<int[]>;class A{static void Main(){L x=new L(),y=new L(),z=new L();int i=int.Parse(C.ReadLine()),j=0,k,l,m;x.Add(new int[i]);while(i>0){j++;for(m=0;m++<i;){foreach(var a in y)x.Add(a);y=new L();foreach(var a in x){for(k=0;k<i;){int[] t=new int[i];System.Array.Copy(a,t,i);t[k++]=j;var b=true;z.AddRange(x);z.AddRange(y);foreach(var c in z){for(l=0;l<i;l++)if(c[l]!=t[l])break;if(l==i)b=false;}if(b)y.Add(t);}}}}for(k=0;k<x.Count;k++){C.Write("[ ");for(l=0;l<i;l++)C.Write(x[k][l]+" ");C.WriteLine("]");}}}

Experimente online!

meu deus, o que eu fiz (tantas voltas, foi o que eu fiz)

Deve funcionar, no entanto!

Se você mover o loop de impressão de volta para um suporte, ele mostrará a lista conforme ela é criada, toda vez que ele faz um loop. (Eu recomendo adicionar uma nova linha ou algo para distinguir cada loop, se você o fizer.)

Sinceramente, passei muito do meu tempo lutando com a linguagem ... nenhuma matriz bonita de impressão, comportamentos variados de == ...

Espero que esta versão seja mais fácil de ler.

using C=System.Console;
using L=System.Collections.Generic.List<int[]>;
class A{
    static void Main(){
        L x=new L(),y=new L(),z=new L();
        int i=int.Parse(C.ReadLine()),j=0,k,l,m;
        x.Add(new int[i]);
        while(i>0){
            j++;
            for(m=0;m++<i;){
                foreach(var a in y) x.Add(a);
                y=new L();
                foreach(var a in x){
                    for(k=0;k<i;){
                        int[] t=new int[i];
                        System.Array.Copy(a,t,i);
                        t[k++]=j;
                        var b=true;
                        z.AddRange(x);
                        z.AddRange(y);
                        foreach(var c in z){
                            for(l=0;l<i;l++) if(c[l]!=t[l])break;
                            if(l==i)b=false;
                        }
                        if(b)y.Add(t);
                    }
                }
            }
        }
        for(k=0;k<x.Count;k++){
            C.Write("[ ");
            for(l=0;l<i;l++)C.Write(x[k][l]+" ");
            C.WriteLine("]");
        }
    }
}
Stackstuck
fonte
Eu apenas dei conta de que pode furar o loop de impressão na instrução if para que ele imprime como ela vai. facepalm um momento.
Stackstuck 17/04
Não espere, não posso fazer isso
Stackstuck 17/04
... oh querido, não tenho mais certeza se esse código funciona mais.
Stackstuck 17/04
aaaaand não faz.
Stackstuck 17/04
11
Boa sorte com isso :) Comecei a codificar uma solução em C # e percebi que era um pouco mais complicado do que eu esperava. Por que não usar o intérprete "Visual C # Interactive"? Isso economizaria muito ao simplesmente não precisar incluir a definição de classe. De qualquer forma, +1 de mim :)
dana
1

Perl 6 , 50 bytes

{grep $_,{S/.//.split(0)>>.chars}($++.base(2))xx*}

Experimente online!

Bloco de código anônimo que retorna uma lista infinita lenta. Isso usa a mesma estratégia da resposta de Chas Brown .

Explicação:

{grep $_,{S/.//.split(0)>>.chars}($++.base(2))xx*}
{                                                } # Anonymous code block
                                              xx*  # Repeat indefinitely
                                 ($++        )     # From the current index
                                     .base(2)      # Get the binary form
         {S/.//                 }   # Remove the first digit
               .split(0)            # And split by zeroes
                        >>.chars    # And get the length of each section
 grep   ,   # From this infinite list, filter:
      $_      # The groups with length the same as the input
Brincadeira
fonte
0

VDM-SL , 51 bytes

g(i)==if i=0then{}else{[x]^y|x:nat,y in set g(i-1)}

Compreensão recursiva de conjuntos com concatenação de sequências.

Não no TIO, você pode executar um programa (se você ativar limites para o tipo nat ou ele não será finalizado):

functions 
g:nat->set of ?
g(i)==if i=0then{}else{[x]^y|x:nat,y in set g(i-1)}

Inclui os 0s opcionais na resposta, caso contrário, seriam 52 bytes de ligação em nat1

Dados expirados
fonte
0

perl -M5.010 122 bytes

$n=shift;
$s.="for\$x$_(1..\$m){"for 1..$n;
$t.="\$x$_ "for 1..$n;
$u.='}'x$n;
eval"{\$m++;$s\$_=qq' $t';/ \$m /&&say$u;redo}"

Adicionadas algumas novas linhas para facilitar a leitura (não contadas na contagem de bytes)


fonte
0

Python 2 , 120 bytes

from random import*
m=n=input()
a=()
while 1:
 m+=len(a)==m**n;t=[randint(1,m)for _ in[1]*n]
 if(t in a)<1:a+=t,;print t

Experimente online!

Um pouco mais do que a maioria das outras respostas, mas gostei da ideia por trás disso.

ArBo
fonte
0

Stax , 6 bytes

£ƒ$↔┬ï

Execute e depure

Para entrada, no procedimento é aproximadamente

for i in [0..infinity]:
    get all the distinct n length arrays of positive integers that sum to i
    for each
        join with spaces
        implicitly output
recursivo
fonte
0

JavaScript (V8) , 98 bytes

n=>{for(a=[],b=[j=1];;b.push(++j))(g=k=>k<n?b.map(i=>(a[k]=i)|g(k+1)):a.includes(j)&&print(a))(0)}

Experimente online!

Viva! Finalmente consegui menos de 100 :) Basicamente, uma porta da minha resposta em C # .

// n: length of tuples to generate
n=>{
  // a: workspace for current tuple
  // b: range of numbers that grows
  //     - iteration 1: [1]
  //     - iteration 2: [1,2]
  //     - iteration 3: [1,2,3]
  // j: largest number in b
  for(a=[],b=[j=1];;b.push(++j))
    // g: recursive function to build tuples
    // k: index of slot for current recursive call
    (g=k=>
       // current slot less than the tuple size? 
       k<n?
         // tuple generation not complete
         // try all values in current slot and
         // recurse to the next slot
         b.map(i=>(a[k]=i)|g(k+1)):
         // tuple generation complete
         // print tuple if it contains the
         // current high value
         a.includes(j)&&print(a)
    // start recursive function at slot 0
    )(0)
}
dana
fonte