Liste * tous * les tuples!


35

Écrire un programme, étant donné une entrée n , générera tous les n-uplets possibles en utilisant des nombres naturels.

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)... 
  • La sortie peut être dans n'importe quel ordre qui ne casse aucune autre règle.
  • Le programme doit être écrit pour fonctionner pour toujours et répertorier tous les nuplets applicables exactement une fois, en théorie.
    • En réalité, votre programme atteindra la limite et le crash de votre type entier. Ceci est acceptable tant que le programme serait courir infiniment long si seulement votre type entier était illimité.
    • Chaque tuple valide doit être répertorié dans un délai déterminé, si seul le programme est autorisé à exécuter ce processus.
  • La sortie peut, à votre choix, inclure des zéros en plus des nombres naturels.
  • Vous pouvez choisir le format de sortie de votre programme pour votre commodité, à condition que la séparation entre les n-uplets et les nombres à l'intérieur de chaque tuple soit claire et cohérente. (Par exemple, un tuple par ligne.)
  • L'entrée (n) est un entier de un à six. Le comportement requis n'est pas défini pour les entrées situées en dehors de cette plage.
  • Les règles du code-golf s'appliquent, le programme le plus court gagne.

Merci à "Artemis Fowl" pour ses commentaires pendant la phase de bac à sable.


Je suppose que c'est valable si, lorsque le programme se bloque, il produit des sorties superflues en plus des n-uplets imprimés jusqu'à présent, n'est-ce pas?
Luis Mendo

1
Doit-on sortir au fur et à mesure ou une fonction qui produit une liste infinie à la fin des temps est-elle suffisante?
Jonathan Allan

6
"Vous pouvez choisir le format de sortie de votre programme pour votre commodité, à condition que la séparation entre les n-uplets et les nombres à l'intérieur de chaque tuple soit claire et cohérente" - pouvons-nous produire une séparation différente (bien que toujours différente) (par exemple, comme ceci )?
Jonathan Allan

@ JonathanAllan Je devrais inclure la sortie du contenu infini de cet objet dans le cadre du programme.
billpg

1
Connexes (entiers au lieu de nombres naturels)
Fruit Esolanging

Réponses:


24

Husk , 2 octets

πN

Essayez-le en ligne!

Explication

Nest la liste infinie de nombres naturels [1,2,3,4,... πest le pouvoir cartésien. Le résultat est une liste infinie de listes. Chaque liste de la longueur souhaitée apparaît exactement une fois parce que πc'est cool comme ça. Les entrées et sorties sont implicites.


1
Wow, et cela ne fait pas [1,1, n] non plus. Existe-t-il un motif dans l'ordre de sortie?
billpg

1
@billpg Il construit les n-uplets de manière récursive: n- les n-uplets sont obtenus en prenant le produit cartésien de la liste d'origine et la liste des n-1-uuples, dans l'ordre croissant de la somme des indices.
Zgarb le

"ordre croissant de la somme des indices" - Pouvez-vous clarifier cela? J'ai du mal à comprendre pourquoi, par exemple, 2,2,2vient après 4,1,2et 5,1,1.
Jonah

2
@ Jonah La récursivité fonctionne comme ceci. Vous commencez avec 1-tuples plus N. Pour 2-tuples, vous prenez un produit cartésien avec Nordre par somme d'indices. Dans les deux listes, chaque nombre nest indexé, nainsi pour la longueur 2, le résultat est ordonné par somme. Pour obtenir 3-tuples, vous prenez le produit cartésien Net la liste des 2-tuples, classés par la somme des indices des éléments de ces listes. Il ne regarde pas la somme du tuple, mais sa position dans la liste des n-uplets.
Zgarb le

2
"Déterminez les différentes dimensions de l'infini dans cette tâche et trouvez un modèle qui le réduit à l'infini dénombrable, puis écrivez un programme qui itère sur ce modèle." - "Hey, j'ai un construit pour ça!"
Fabian Röling le

10

Haskell , 62 octets

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

Essayez-le en ligne!

n!sgénère tous les n-tuples qui totalisents .

Ensuite, la réponse est ([1..]>>=).(!), à savoir\n -> [t | s<-[1..], t<-n!s] .

Il s’agit d’une fonction mappant un entier nsur une liste infinie de n-uplets (listes d’entiers).


5

Haskell , 50 octets

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

Essayez-le en ligne!

Listes n-tuples triés par somme. mapMfait le gros du travail pour générer tous les ncouples de nombres de 0 à k. Le <$ftruc est expliqué ici .

Haskell , 51 octets

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

Essayez-le en ligne!

n-1Étend de manière récursive tous les -tuples en tous les n-tuples en divisant le premier nombre ade chaque n-1-tuple en deux nombres a-k,kqui le résument, de toutes les manières possibles.


4

Pyth - 9 octets

Merci à @FryAmTheEggman pour le golf

Parcourt tout x et prend [1..x] ^ n. Cela crée des doublons, donc ne conserve que ceux qui sont nouveaux pour ce x, c'est-à-dire qu'ils contiennent x. Le formatage est un peu bizarre, mais il peut être rendu standard avec un octet supplémentaire,.V1j}#b^Sb

.V1}#b^Sb

Essayez-le en ligne .


1
f}bT-> }#bDe plus, votre nombre d'octets semble être incorrect pour le moment?
FryAmTheEggman le

@FryAmTheEggman attendre, pourquoi est-ce incorrect? Si vous parlez du lien TIO, cela inclut le formatage avec j(b). Merci également pour le golf.
Maltysen

Ah, c'est ce qui m'a dérouté, désolé!
FryAmTheEggman le

3

Brachylog (v2), 9 octets

~l.ℕᵐ+≜∧≜

Essayez-le en ligne!

C'est un générateur infini qui génère tous les nuplets possibles. Le lien TIO a un en-tête qui utilise le générateur pour générer 1000 éléments et les imprime (mais le générateur pourrait continuer indéfiniment si je le demandais à la place; les entiers de Brachylog ne sont pas liés).

On sent qu'il devrait y avoir une marge de manoeuvre, mais il y a beaucoup de contraintes et c'est le plus difficile pour moi de pouvoir les intégrer dans un seul programme.

Explication

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

Incidemment, il me semble intéressant de voir à quel point mes explications sur les deux sont différentes, même si elles font exactement la même chose du point de vue de Brachylog. Le premier est le premier prédicat non déterministe du programme, il définit donc l'ordre des résultats; dans ce cas, il calcule toutes les valeurs explicites possibles pour la somme de la liste dans l’ordre 0, 1, 2, 3…, et est utilisé pour garantir que les listes sont éditées dans l’ordre de leur somme la liste apparaît après une quantité finie de sortie). La seconde est utilisée pour calculer toutes les possibilités explicites de la liste (plutôt que de générer une formule spécifiant le lien entre les éléments de la liste).


↰₁ẉ⊥est également un bon en-tête, pour imprimer à l'infini.
Unrelated String

Bien que j’ai l’impression que cela ne soit pas vraiment une réponse complète, puisqu’un seul appel indépendant de ce prédicat ne génère que des zéros , la partie "générer tout" étant exécutée par le ou dans l’en-tête.
Unrelated String

1
@UnrelatedString Votre code n'utilise cependant pas le prédicat en tant que générateur. Nous avons des règles explicites permettant la sortie de liste en utilisant un générateur . Dans votre lien TIO, vous appelez le prédicat dans une boucle pour obtenir 1000 générateurs différents, puis prenez la première sortie de chacun d'eux. C'est une opération vraiment contre nature sur les générateurs, et cela ne vous laisse pas voir les autres éléments qu'ils peuvent générer.
ais523 le

Ah, alors je viens de mal interpréter la sémantique de ce qu'est un prédicat de Brachylog tout ce temps - mon idée de "générateur" est bloquée sur Python. Maintenant que cela me va droit à la tête, je suppose que je vais raser trois octets de certaines de mes anciennes réponses.
Chaîne sans lien

2

Perl 6 , 37 octets

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

Essayez-le en ligne!

Fonctionne essentiellement polymodavec autant d'entrées que nécessaire, où le modulo est toujours supérieur à l'entrée, c'est-à-dire 0.polymod (1,1,1), 1.polymod (2,2,2), etc. Ainsi, le chiffre est toujours compris entre la gamme. Perl6 ne me laissera pas modulo l'infini ...


5
Ceci ne liste pas chaque tuple exactement une fois (par exemple, (0, 1, 0, 0)n'est pas listé).
bb94


2

C # (compilateur interactif Visual C #) , 148 octets

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);}

Essayez-le en ligne!

-3 octets grâce à @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);
}

comment avez-vous fait cela?
Stackstuck

le portage direct vers .NET Core me permettrait probablement encore de gagner beaucoup d'octets.
Stackstuck

Le plus gros problème ici est la récursivité. La plupart des techniques que j'ai vues pour générer des "permutations" l'utilisent. Je prévois d'ajouter une explication.
Dana

Writeavec eg '<literal tab>'ou a |la même longueur et prend beaucoup moins de lignes: P
ASCII uniquement


1

Gelée , 10 (9?) Octets

9 si nous pouvons sortir en utilisant une séparation non cohérente (sur laquelle je me suis renseigné) - suppression de .

‘ɼṗ³ċƇ®Ṅ€ß

Essayez-le en ligne!

Comment?

‘ɼṗ³ċƇ®Ṅ€ß - 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)

1
Basé sur " tant que la séparation entre les n-uplets et les nombres à l'intérieur de chaque tuple est claire et cohérente. (Par exemple, un tuple par ligne.) " J'ai supposé que cela n'était pas autorisé et qu'il était nécessaire, mais attendons de ce que OP doit dire.
Kevin Cruijssen le

1

05AB1E , 15 à 11 octets

[¼¾LIãvy¾å—

-4 octets en créant un port de @Maltysen réponse Pyth de .

Essayez-le en ligne.

Explication:

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

2
Quand le programme arrivera-t-il à [1,2,1]? Rappelez-vous que cela doit être dans un temps fini.
billpg

@billpg devrait être corrigé maintenant.
Kevin Cruijssen le


1

Python 2 , 126 112 106 101 100 83 octets

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

Essayez-le en ligne!

5 octets thypet à mypetlion ; 1 octet de l'oeil d'aigle d' ArBo ; 17 octets de xnor !

Construisez les partitions ordonnées de mdans des nbacs, m = 0,1,2,3,...en sélectionnant des nombres binaires avec n-1 0s et m 1s.


if i==p:i=0;p*=2peut devenir i%=p;p<<=i<1économiser 5 octets.
mypetlion

Je suis à peu près sûr que l'espace après print bn'est pas nécessaire: D
ArBo

On dirait que le nombre ne i+pfait que compter 1, 2, 3 ... de façon alambiquée et peut donc ne représenter qu'une seule variable.
xnor

@xnor: D'oh! Je suis tellement absorbé par le concept que je ne vois pas la forêt pour les arbres.
Chas Brown

1

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

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("]");}}}

Essayez-le en ligne!

mon dieu qu'est-ce que j'ai fait (tant de boucles, c'est ce que j'ai fait)

Cela devrait marcher!

Si vous déplacez la boucle d’impression d’un crochet vers l’autre, la liste sera affichée telle qu’elle est construite, à chaque boucle. (Je vous recommande d'ajouter une nouvelle ligne ou quelque chose pour distinguer chaque boucle si vous le faites.)

Honnêtement, beaucoup j'ai passé de temps à me battre avec la langue ... pas de jolies baies d'impression, des comportements assortis de == ...

Espérons que cette version est plus facile à lire.

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("]");
        }
    }
}

Je viens de me rendre compte que je peux coller la boucle d'impression dans l'instruction if afin qu'elle imprime au fur et à mesure. facepalm un moment.
Stackstuck

attendre Nope ne peut pas faire ça
Stackstuck

... oh mon dieu, je ne suis pas sûr que ce code fonctionne plus.
Stackstuck

aaaaet ça ne marche pas.
Stackstuck

1
Bonne chance avec ça :) J'ai commencé à coder une solution en C # et me suis rendu compte que c'était un peu plus compliqué que ce que j'espérais. Pourquoi ne pas utiliser l'interpréteur "Visual C # Interactive"? Cela permettrait d'économiser beaucoup de choses simplement en évitant d'inclure la définition de classe. Quoi qu'il en soit, +1 de moi :)
Dana

1

Perl 6 , 50 octets

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

Essayez-le en ligne!

Bloc de code anonyme qui renvoie une liste infinie paresseuse. Ceci utilise la même stratégie que la réponse de Chas Brown .

Explication:

{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

0

VDM-SL , 51 octets

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

Compréhension récursive des ensembles avec concaténation de séquences.

Pas sur TIO, vous pouvez exécuter un programme (si vous activez les limites pour le type nat ou si cela ne se termine pas):

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

Inclut les 0 facultatifs dans la réponse, sinon ce serait une liaison de 52 octets sur nat1



0

perl -M5.010 122 octets

$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}"

Ajout de nouvelles lignes pour des raisons de lisibilité (non prises en compte dans le nombre d'octets)


0

Python 2 , 120 octets

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

Essayez-le en ligne!

Un peu plus long que la plupart des autres réponses, mais j’ai aimé l’idée derrière tout ça.


0

Stax , 6 octets

£ƒ$↔┬ï

Exécuter et déboguer

Pour la saisie, nla procédure est approximativement

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

0

JavaScript (V8) , 98 octets

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)}

Essayez-le en ligne!

Hourra! Enfin obtenu moins de 100 :) Fondamentalement, un portage de ma réponse 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)
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.