列出*所有*元组!


35

给定输入n编写程序,将使用自然数生成所有可能的n元组。

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)... 
  • 输出的顺序可以不违反任何其他规则。
  • 从理论上讲,该程序必须永久运行并列出所有适用的元组一次。
    • 实际上,您的程序将达到整数类型的限制并崩溃。只要只有整数类型是无限的,程序可以无限长地运行,这是可以接受的。
    • 如果只允许程序运行那么长时间,则必须在有限时间内列出每个有效的元组。
  • 您可以选择输出,除了自然数外还包括零。
  • 为了方便起见,您可以选择程序的输出格式,只要元组和每个元组内的数字之间的分隔清晰且一致即可。(例如,每行一个元组。)
  • 输入(n)是1到6的整数。对于超出此范围的输入,未定义所需的行为。
  • 适用代码高尔夫球规则,以最短的程序获胜。

感谢“ Artemis Fowl”在沙盒阶段的反馈。


我认为如果程序崩溃时除到目前为止打印的元组之外还产生了一些多余的输出,这是有效的,对吗?
Luis Mendo

1
我们必须继续输出,还是在时间结束时产生无限列表的函数足够?
乔纳森·艾伦

6
“只要您方便地选择程序的输出格式,只要元组和每个元组内的数字之间的分隔清晰且一致即可” –我们是否可以输出不同的(尽管始终不同)分隔(例如,这样)?
乔纳森·艾伦

@JonathanAllan我将不得不将该对象的无限内容的输出作为程序的一部分。
billpg

1
相关(整数而不是自然数)
硕果累累

Answers:


24

外壳,2个字节

πN

在线尝试!

说明

N是自然数的无限列表[1,2,3,4,..π是笛卡尔的力量。结果是列表的无限列表。所需长度的每个列表仅出现一次,因为这样π很酷。输入和输出是隐式的。


1
哇,这也不做[1,1,n]。输出的顺序是否有模式?
billpg

1
@billpg它递归地建立元组:n-元组是通过将原始列表和n-1-tuple 列表的笛卡尔积按索引和的升序获得的。
Zgarb

“指数总和的升序”-您能澄清一下吗?我很难弄清楚为什么2,2,2要跟在4,1,2和之后5,1,1
乔纳

2
@Jonah递归是这样的。您从1元组开始N。对于2元组,您采用笛卡尔积,其N乘积按索引的总和排序。在两个列表中,每个数字n都位于索引处,n因此对于长度2,结果恰好是按和排序的。要获得3元组,请采用笛卡尔乘积N和2元组的列表,该列表按这些列表中元素索引的总和排序。它不查看元组的总和,而是查看其在元组列表中的位置。
Zgarb

2
“找出此任务中无穷大的不同维度,找到将其减小为可数无穷大的模式,然后编写一个在此模式上迭代的程序。” -“嘿,我有内置功能!”
FabianRöling

10

Haskell,62个字节

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

在线尝试!

n!s生成n总和为的所有-tuple s

那么答案是([1..]>>=).(!),即\n -> [t | s<-[1..], t<-n!s]

这是一个将整数映射n到无限懒惰的元组列表(整数列表)的函数。


5

Haskell,50个字节

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

在线尝试!

列出n按总和排序的元组。mapM进行繁重的工作以生成n从0到k的所有数字元组。该<$f诀窍是这里解释

Haskell,51个字节

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

在线尝试!

通过以各种可能的方式将每个-tuple 的第一个数字分成两个求和的数字,以递归方式将所有n-1-tuple扩展为所有n-tuple 。an-1a-k,k


4

Pyth-9个字节

感谢@FryAmTheEggman参加高尔夫

遍历所有x,并取[1..x] ^ n。这将导致重复,因此仅保留x的新内容,也就是在其中包含x。格式有点怪异,但可以再加一个字节将其设置为标准格式,.V1j}#b^Sb

.V1}#b^Sb

在线尝试


1
f}bT-> }#b另外,您的字节数目前似乎不正确?
FryAmTheEggman

@FryAmTheEggman等待,为什么不正确?如果您在谈论TIO链接,则包括使用进行格式化j(b)。另外,感谢您的高尔夫。
Maltysen

啊,那是让我困惑的事情,对不起!
FryAmTheEggman

3

Brachylog(v2),9个字节

~l.ℕᵐ+≜∧≜

在线尝试!

这是一个无限生成器,它生成所有可能的元组。TIO链接有一个标头,该标头使用生成器生成1000个元素并打印(但是如果我要求生成器可以无限期继续; Brachylog的整数是无界的)。

感觉应该有一个更简单的方法,但是有很多限制,这是我可以将它们组合到单个程序中的最糟糕的条件。

说明

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

顺便说一句,尽管我从Brachylog的角度来看做的完全一样,但我对两者的解释却有多么不同,这让我感到很有趣。第一个是程序中的第一个非确定性谓词,因此它设置结果的顺序。在这种情况下,它将以0、1、2、3…的顺序计算列表总和的所有可能的显式值,并用于确保列表以总和的顺序输出(这确保了每个列表会在一定数量的输出之后出现)。第二个用于计算列表的所有显式可能性(而不是输出指定列表元素之间如何关联的公式)。


↰₁ẉ⊥也是一个很好的标题,可以无限打印。
不相关的字符串

尽管我确实觉得这可能并不是一个完整的答案,但是由于此谓词的任何单个独立调用都只会生成零,而“生成全部”部分由标头中的or 来完成
不相关的字符串

1
@UnrelatedString但是,您的代码并未将谓词用作生成器。我们有明确的规则,允许使用generator进行列表输出。您在TIO链接中所做的就是在一个循环中调用谓词以获取1000个不同的生成器,然后从每个生成器中获取第一个输出。在生成器上执行该操作是非常不自然的,它不会让您看到它们可以生成的其他元素。
ais523

嗯,所以我一直都在误解Brachylog谓词在整个时间里的含义-我对“生成器”的想法一直停留在Python上。现在,这已经成为我的直觉,我想我会从一些旧答案中删除三个字节。
不相关的字符串

2

Perl 6、37个字节

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

在线尝试!

本质上可以polymod根据需要运行多个条目,其中模数始终大于输入,即0.polymod(1,1,1),1.polymod(2,2,2)等。这样,数字始终在范围。Perl6不会让我取模无穷大...


5
这不会完全列出每个元组一次(例如,(0, 1, 0, 0)未列出)。
bb94


2

C#(Visual C#交互式编译器),148个字节

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

在线尝试!

-3个字节,感谢@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);
}

您甚至是怎么做到的
Stackstuck

将其直接移植到.NET Core可能仍会为我节省很多字节。
Stackstuck

这里最大的技巧是递归。我见过的大多数生成“排列”的技术都使用它。我计划添加一个解释。
dana

Write与例如'<literal tab>'或是|相同的长度,并占用更少的行:P
仅ASCII的


1

果冻,10(9?)个字节

9如果我们可以使用不一致的分隔符(我已经询问过)输出-删除

‘ɼṗ³ċƇ®Ṅ€ß

在线尝试!

怎么样?

‘ɼṗ³ċƇ®Ṅ€ß - 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
基于“ 只要每个元组中的元组和数字之间的分隔清晰且一致。(例如,每行一个元组。) ”我以为不允许这样做,而这是必需的,但是让我们等待OP必须执行的操作说。
凯文·克鲁伊森

1

05AB1E15 11 字节

[¼¾LIãvy¾å—

通过创建@Maltysen端口来生成-4字节的Pyth答案

在线尝试。

说明:

[             # 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
程序什么时候到达[1,2,1]?请记住,它必须在有限的时间内。
billpg

@billpg现在应该修复。
凯文·克鲁伊森


1

Python 2中126个 112 106 101 100 83字节

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

在线尝试!

5个字节到mypetlion ; 距离ArBo的鹰眼1个字节; 来自17个字节 xnor的

通过选择带有s和s的二进制数,将的有序分区构造mnbin 。m = 0,1,2,3,...n-1 0m 1


if i==p:i=0;p*=2可以i%=p;p<<=i<1节省5个字节。
mypetlion

我很确定print b不需要后面的空间:D
ArBo

看起来i+p只是以一种复杂的方式累加了1,2,3 ...,因此可以只是一个变量。
xnor

@xnor:哦!被这个概念包住了,看不到森林覆盖树木。
Chas Brown

1

C#(.NET核心)608个570 567字节

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

在线尝试!

我的天,我做了什么(这么多循环,这就是我所做的)

不过应该可以!

如果将打印循环移回一个括号,它将在每次循环时向您显示列表的生成情况。(如果这样做,我建议添加换行符或其他内容来区分每个循环。)

老实说,很多我时间都花在了与语言的战斗上……没有漂亮的打印数组,==的各种行为……

希望此版本更易于阅读。

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

刚刚意识到我可以将打印循环粘贴在if语句中,这样它就可以按需打印。 facepalm片刻。
Stackstuck

等不了那不能做
Stackstuck

...哦,亲爱的,我不确定这段代码是否能正常工作了。
Stackstuck

aaaa,事实并非如此。
Stackstuck

1
祝您好运:)我开始用C#编写解决方案的代码,并意识到它比我希望的要复杂得多。为什么不使用“ Visual C#Interactive”解释器?通过不必包含类定义,可以节省很多时间。无论如何,请向我+1 :)
dana

1

Perl 6,50个字节

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

在线尝试!

返回懒惰无限列表的匿名代码块。这使用与Chas Brown的答案相同的策略。

说明:

{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字节

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

具有序列级联的递归集合理解

不在TIO上,您可以在程序中运行(如果您打开了nat类型的限制,否则它不会终止):

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

在回答中包括可选的0,否则在nat1上将绑定52个字节



0

perl -M5.010 122字节

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

出于可读性考虑,添加了一些换行符(不计入字节数)


0

Python 2,120字节

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

在线尝试!

比大多数其他答案要长一些,但是我喜欢它背后的想法。


0

Stax,6 个字节

£ƒ$↔┬ï

运行并调试

输入n的过程大致是

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字节

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

在线尝试!

万岁!最终在100以下得到它:)基本上是我的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)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.