最短的电源设置实施


22

问题定义

打印出给定集合的幂集。例如:

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

每个元素都将打印在单独的行上,因此上面的示例将打印为:

[]
[1]
[2]
...
[1, 2, 3]

示例代码(在D,这里是 python示例):

import std.stdio;

string[][] powerset(string[] set) {
    if (set.length == 1) {
        return [set, []];
    }

    string[][] ret;
    foreach (item; powerset(set[1 .. $])) {
        ret ~= set[0]~item;
        ret ~= item;
    }

    return ret;
}

void main(string[] argv) {
    foreach (set; powerset(argv[1 .. $]))
        writeln(set);
}

输入项

元素将作为参数传递。例如,上面提供的示例将传递给名为的程序powerset

powerset 1 2 3

参数将为字母数字。

规则

  1. io之外没有库
  2. 不必订购输出
  3. Powerset不必存储,只需打印
  4. 集合中的元素必须被分隔(例如1,2,3[1,2,3]['1','2','3']是可接受的,但123不是
    • 尾部定界符很好(例如1,2,3, == 1,2,3
  5. 最佳取决于字节数

最佳解决方案将在首次提交后的10天内决定。




2
如果仅对此挑战进行了更新以允许使用默认值,例如返回和函数。Python将是54个字节:lambda L:reduce(lambda r,x:r+[s+[x]for s in r],L,[[]])
mbomb007 '16

我不同意仅打印...为什么也不允许包含数据和变量。为什么不打印列而不行?
RosLuP

Answers:


15

Mathematica 16

Subsets 是Mathematica的原产地。

Column@Subsets@s

可以在WolframAlpha验证代码(无列)。(我必须使用方括号来代替@;它们含义相同。

用法

s={1,2,3}
Column@Subsets@s

output


此方法(55个字符)使用@ w0lf建议的方法。

s #&/@Tuples[{0,1},Length@s]/.{0:>Sequence[]}//Column

分解

生成由长度为0和的元组1Length[s]

Tuples[{0, 1}, Length@s]

{{0,0,0},{0,0,1},{0,1,0},{0,1,1},{1,0,0},{1,0,1},{ 1,1,0},{1,1,1}}

将原始列表(向量)乘以每个元组:

s # & /@ Tuples[{0, 1}, Length@s]

{{0,0,0},{0,0,3},{0,2,0},{0,2,3},{1,0,0},{1,0,3},{ 1,2,0},{1,2,3}}

删除0%是“先前输出”的简写。

%/。{0:>序列[]}

{{},{3},{2},{2、3},{1},{1、3},{1、2},{1、2、3}}

显示在列中:

Mathematica graphics


@tjameson我是否应该发布它有严重的疑问,但是我认为有些人知道它是内置的可能会很有趣。
DavidC 2012年

我觉得很有趣:)
belisarius博士2012年

您可以取消s输入,然后将输入放在行尾吗?
所罗门·乌科

15个字节:Subsets/*Column创建一个匿名函数,该函数接受一个列表并按列返回显示。
罗马

9

C,118 115

尽管可以用更简单的格式节省大约20个字符,但无论如何都不会赢得代码高尔夫方面的认可。

x,i,f;
main(int a,char**s){
    for(;x<1<<a;x+=2,puts("[]"+f))
        for(i=f=0;++i<a;)x&1<<i?f=!!printf("%c%s","[,"[f],s[i]):0;
}

测试:

/a.out 1 2 3
[]
[1]
[2]
[1,2]
[3]
[1,3]
[2,3]
[1,2,3]

真好 一些提示:K&R样式(main(a,s)char**s;{...}),f|=x&1<<i&&printf比短?:
ugoren

只需弄清楚背后是什么x+=2s[0]去了哪里)。真的很好。
ugoren

拒绝接受您的回答,因为它“无论如何都不会以代码形式赢得胜利”。使答案不是挑战获胜标准的严重竞争者。
pppery

7

GolfScript,22个 18个字符

~[[]]{{+}+1$%+}@/`

GolfScript中的另一种尝试是使用完全不同的算法。输入格式与w0lf的答案相同。(在线测试


+1很棒的解决方案!为了提高可读性,该矿井进行了重构:-P
Cristian Lupascu 2012年

5

GolfScript(43个字符)

这可能看起来很长,但这是遵循规范的第一个解决方案:输入来自命令行参数,而输出则以换行符分隔。

"#{ARGV.join('
')}"n/[[]]\1/{`{1$+.p}+%}%p;

例如

$ golfscript.rb powset.gs 1 2 3
["1"]
["2"]
["2" "1"]
["3"]
["3" "2"]
["3" "1"]
["3" "2" "1"]
[]

如果有区别的话,引号不是必需的。
beatgammit

@tjameson,引号来自使用最短的打印方式。这些值是字符串而不是整数的事实来自于GolfScript无法直接访问命令行参数:它必须依赖于解释器在Ruby中进行eval并将结果放入字符串中。
彼得·泰勒

4

awk(82)

{for(;i<2^NF;i++){for(j=0;j<NF;j++)if(and(i,(2^j)))printf "%s ",$(j+1);print ""}}

假定保存在文件powerset.awk中,用法

$ echo 1 2 3 | awk -f powerset.awk

1
2
1 2
3
1 3
2 3
1 2 3

ps,如果您的awk没有and()函数,请替换为,int(i/(2^j))%2但要增加两个。


(2^j)->为2^j您节省2个字节;该.awk文件也可以不带尾部运行\n,因此您可以删除另一个字节。
mklement0 '17

3

JavaScript的98

可悲的是,大量的代码都花在了输出格式化上。

for(n in a=eval(prompt(i=p=[[]])))
    for(j=i+1;j;)
        p[++i]=p[--j].concat(a[n]);
alert('[]'+p.join('\n'))

输入项

采用JavaScript数组。(例如[1,2,3])

输出量

[]
1
1,2
2
2,3
1,2,3
1,3
3

3

Python(74 70个字符)

def p(a,v):
 if a:i,*a=a;p(a,v);p(a,v+[i])
 else:print v
p(input(),[])

输入为1,2,3[1,2,3],输出为:

[]
[3]
[2]
[2, 3]
[1]
[1, 3]
[1, 2]
[1, 2, 3]

[a[0]]=a[:1]
ugoren 2012年

输入1,2,3 a[:1]不起作用。元组+列表不允许。存在更好的解决方案
AMK 2012年

+1i,*a=a
primo 2012年

是不是i,*a=aPython 3?在我的2.7.1上不起作用。
ugoren

在2.7.2上也不是。这也许可以解释为什么我以前从未见过这种窍门……大多数代码高尔夫服务器都运行2.7.x。
primo 2012年

3

Python 70 67字节

def p(a,*v):
 i=0;print v
 for n in a:i+=1;p(a[i:],n,*v)
p(input())

输入方式与ugoren的解决方案相同。样本I / O:

$ echo [1,2,3] | powerset.py
()
(1,)
(2, 1)
(3, 2, 1)
(3, 1)
(2,)
(3, 2)
(3,)

1
您可以先保存一些,def p(a,*v)然后再保存p(a[i:],n,*v)。输出变得有些难看,但仍然可以。
ugoren

非常聪明,谢谢小费。
primo 2012年

3

J,19个字符

   (<@#~#:@i.@(2&^)@#)

   (<@#~#:@i.@(2&^)@#) 1 2 3
┌┬─┬─┬───┬─┬───┬───┬─────┐
││3│2│2 3│1│1 3│1 2│1 2 3│
└┴─┴─┴───┴─┴───┴───┴─────┘

调用输出中的ascii装箱,boxing并提供异源收集(此处适用于不同长度的数组)。


2

高尔夫脚本48

~:x,:§2\?,{[2base.,§\-[0]*\+x\]zip{~{}{;}if}%p}%

该程序使用从0到length(输入)的数字的二进制表示形式来生成powerset项。

输入项

输入格式是Golfscript数组格式(例如: [1 2 3]

输出量

输出是由换行符分隔的数组的集合,代表幂集。例:

[]
[3]
[2]
[2 3]
[1]
[1 3]
[1 2]
[1 2 3]

在线测试

该程序可以在此处在线测试。


很棒,但是您可以用换行符定界吗?
Beatgammit 2012年

@tjameson我设法输出换行符分隔的字符,同时保持相同的字符数。请查看我的答案的更新。
克里斯蒂安·卢帕斯库

2

哈斯克尔(96)

导入Control.Monad
导入System.Environment
main = getArgs >> = mapM print.filterM(\ _-> [False ..])

如果Control.Monad不允许导入,则为100字符:

导入System.Environment
main = getArgs >> = mapM print.p
pz = {[]-> [[]]; x:y-> p y ++ map(x:)(py)}的大小写z

2

Mathematica 53

Column@Fold[#~Join~Table[x~Join~{#2},{x,#}]&,{{}},#]&

enter image description here


2

APL(26)

从键盘读取输入,因为没有argv等效项。

↑⍕¨(/∘T)¨↓⍉(M/2)⊤⍳2*M←⍴T←⎕

用法:

      ↑⍕¨(/∘T)¨↓⍉(M/2)⊤⍳2*M←⍴T←⎕
⎕:
      1 2 3
3    
2    
2 3  
1    
1 3  
1 2  
1 2 3

说明:

  • T←⎕:读取输入,存储在 T
  • M←⍴T:商店的长度TM
  • (M/2)⊤⍳2*M:使用位生成1最多可2^M使用的位模式M
  • ↓⍉:拆分矩阵,以便每个位模式都分开
  • (/∘T)¨:对于每个位模式,从中选择那些子项目T
  • ↑⍕¨:对于输出,获取每个元素的字符串表示形式(以便将使用空格而不是零填充),并设置为矩阵格式(以便每个元素位于单独的行)。

2

斯卡拉,81岁

def p[A](x:Seq[A]){x.foldLeft(Seq(Seq[A]()))((a,b)=>a++a.map(b+:_)).map(println)}

2

JavaScript(ES6)76

从此部分复制的内容:https : //codegolf.stackexchange.com/a/51502/21348

使用位图,因此它被限制为不超过32个元素。

在Firefox中运行代码段进行测试。

f=l=>{ 
  for(i=0;i<1<<l.length;i++)
    console.log(l.filter(v=>[i&m,m+=m][0],m=1))
}  

// TEST

// Redefine console to have output inside the page
console = { log: (...p) => O.innerHTML += p.join(' ') + '\n' }

test=()=>{
  var set = I.value.match(/[^ ,]+/g)
  O.innerHTML='';
  f(set);
}

test()
#I,#O { border: 1px solid #aaa; width: 400px; padding:2px}
Insert values, space or comma separated:<br>
<input id=I value='1 2 3'> <button onclick="test()">-></button>
<pre id=O></pre>


2

C#164

伙计,这在C#中很难!

void P<T>(T[]c){foreach(var d in c.Aggregate<T,IEnumerable<IEnumerable<T>>>(new[]{new T[0]},(a,b)=>a.Concat(a.Select(x=>x.Concat(new[]{b})))))Console.WriteLine(d);}

2

Python 2,64字节

使用逗号分隔的输入:

P=[[]]
for i in input():P+=[s+[i]for s in P]
for s in P:print s

Pyth,4字节(使用内置)或14字节(不使用)

正如@Jakube在评论中指出的,Pyth对于这个问题来说太新了。仍然是使用Pyth的内置powerset运算符的解决方案:

jbyQ

这里是一个没有它的人:

jbu+Gm+d]HGQ]Y

您可以在这里这里尝试两种解决方案。这是第二种解决方案的说明:

jb       # "\n".join(
 u       #  reduce(
  +G     #   lambda G,H: G+
   m     #    map(
    +d]H #     lambda d: d+[H],
    G    #     G),
  Q      #   input()
  ]Y     #   [[]]))

2

Brainfuck,94个字节

+[[<+>>+<-]++[>-<------]>-[>]<<[>>+>]>,]++++++++++[[[<]<]+[-[>[.>]]<[<]>+[>]>]<<
.[<<[<]>-]++>]

格式:

+
[
  [<+> >+<-]
  ++[>-<------]>-[>]
  <<[>>+>]
  >,
]
++++++++++
[
  [[<]<]
  +
  print
  [
    -[>[.>]]
    <[<]
    >+[>]
    >
  ]
  <<.
  increment
  [
    <<[<]
    >-
  ]
  ++>
]

期望输入的形式9,10,11没有尾随换行符,并以相同格式输出子集,有时带有尾随逗号。打印的第一行将始终为空,表示为空集。

在线尝试。

基本思想是在每个元素旁边放置一个位,然后重复递增二进制数,同时在每次递增之前打印相应的子集。(一个位指示元素是否在子集中。)数组左侧的前哨位用于终止程序。这个版本实际上创建了指数级的前哨以节省一些字节;在修订历史记录中可以找到一种更高效的仅使用一个哨兵的99字节解决方案。

每一位被编码为一个加它的值。即可以是12。磁带的布局是每个元素之前的位以及相邻元素之间的单个零单元格。磁带上包含逗号,表示非最终元素,因此我们可以方便地仅打印元素,而无需执行任何其他处理定界符的工作。


2

APL(Dyalog Classic),13个字节

⍪,⊃∘.,/⎕,¨⊂⊂⍬

在线尝试!

输出:

 1 2 3 
 1 2   
 1 3   
 1     
 2 3   
 2     
 3     

末尾有一个空白行代表空集。

说明:

评估输入

⎕,¨⊂⊂⍬ 在每个元素之后附加一个空的数字列表

∘., 笛卡尔积

/ 减少(文件夹)

披露(减少APL后需要)

此时,结果是一个n维2×...×2数组,其中n是输入的长度。

, 展平成向量

将向量转换为直立的2 n -1矩阵,因此每个子集位于单独的行上




1

Python,93 87个字符

Python使格式化变得简单,因为所需的输入/输出与其原始格式匹配。
仅支持使用Python文字的项目(例如1,2,'hello',不支持1,2,hello)。
读取标准输入,而不是参数。

f=lambda x:x and f(x[1:])+[x[:1]+a for a in f(x[1:])]or[()]
for l in f(input()):print l

print f(input())较短
AMK 2012年

@AMK,要求将每个元素打印在一行中。但list的确可以删除(如果还replacinf [[]][()]
ugoren

print'\n'.join(f(input()))保存两个字符
beary605

@ beary605不起作用,它f()包含元组而不是字符串。
ugoren


1

Haskell 89个字符

import System.Environment
main=getArgs>>=mapM print.p
p[]=[[]]
p(x:y)=(map(x:)$p y)++p y

获取参数很长:/


可以用剃除map(x:)(p y)++p y另外一个字符,而使用可以剃掉另外两个字符[(x:),id]<*>p y。显然<*>现在在前奏中。(filterM不是)。
Will Ness

1

R,63

y=lapply(seq(v),function(x)cat(paste(combn(v,x,s=F)),sep="\n"))

在这里,v代表一个向量。

用法

v <- c(1, 2, 3)
y=lapply(seq(v),function(x)cat(paste(combn(v,x,s=F)),sep="\n"))
1
2
3
c(1, 2)
c(1, 3)
c(2, 3)
c(1, 2, 3)

1

K,14个字节

{x@&:'!(#x)#2}

只要输入就生成所有0/1向量,收集1的索引,并使用这些索引从输入向量中选择元素。在实践中:

  {x@&:'!(#x)#2} 1 2 3
(!0
 ,3
 ,2
 2 3
 ,1
 1 3
 1 2
 1 2 3)

这对输出要求有点宽松,但我认为这是合法的。最值得怀疑的部分是,空集将以类型依赖的形式表示。!0K表示空数值向量的方式:

  0#1 2 3      / integers
!0
  0#`a `b `c   / symbols
0#`
  0#"foobar"   / characters
""

说明

所述(#x)#2构建的载体2,只要输入:

  {(#x)#2}1 2 3
2 2 2
  {(#x)#2}`k `d `b `"+"
2 2 2 2

将Monadic !应用于矢量时,它是“里程表”:

  !2 2 2
(0 0 0
 0 0 1
 0 1 0
 0 1 1
 1 0 0
 1 0 1
 1 1 0
 1 1 1)

然后,我们&在每个(')向量上使用“ where”()来收集其索引。冒号对于消除以下形式的单字和双字形式是必不可少的&

  &0 0 1 0 1 1
2 4 5

  {&:'!(#x)#2} 1 2 3
(!0
 ,2
 ,1
 1 2
 ,0
 0 2
 0 1
 0 1 2)

如果我们只想要组合向量,就可以完成,但是我们需要将它们用作原始集合的索引。幸运的是,K的索引运算符@可以接受复杂的索引结构,并将产生具有相同形状的结果:

  {x@&:'!(#x)#2} `a `c `e
(0#`
 ,`e
 ,`c
 `c `e
 ,`a
 `a `e
 `a `c
 `a `c `e)

优雅,不是吗?


1
这不再有效,因为OK中的“里程表”现在会生成一个翻转的矩阵。可以以单个字节为代价进行更正{x@&:'+!(#x)#2}。无关:较短相当于(#x)#2IS 2|~x
ngn

1

Mathematica,51岁

更多作弊:

Column@ReplaceList[Plus@@HoldForm/@#,x___+___->{x}]&

与一起使用@{1,2,3}


您的代码应将集合作为输入,而不仅仅是对其进行硬编码。另外,由于这是代码高尔夫球,因此应包括代码的字节数(并可能删除不必要的空格)。
Martin Ender 2015年

由于这场比赛已经结束,因此该帖子更多的是关于创意的,但是我已经对其进行了编辑。
LogicBreaker

1

JavaScript(ES6),68个字节

a=>alert(a.reduce((a,x)=>[...a,...a.map(y=>[...y,x])],[[]]).join`
`)

演示版


为什么alert呢?
毛茸茸的

@Shaggy挑战明确要求将每个元素打印在单独的行上,这可能与我们当前的标准不符。大多数答案似乎都遵循这一规则。
Arnauld

嗯,很公平;我将“打印”解释为“输出”。
毛茸茸的


0

Ruby数组方法组合(从1.9起)[50个字符]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
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.