最短電力セットの実装


22

問題定義

指定されたセットのpowersetを印刷します。例えば:

[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. 電源セットを保存する必要はなく、印刷するだけです
  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

回答:


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

壊す

01の長さで構成されるタプルを生成しますLength[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

おもしろいと思います:)
ベリサリウス博士12年

そのままにして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よりも短い?:
ウゴレン

背後にあるものx+=2(そしてどこに行ったのs[0]か)を把握しました。本当にすてきなトリック。
ugoren

「どちらの方法でもコードのゴルフ用語で勝つつもりはない」ので、あなたの答えをゴルフに拒否します。答えは、チャレンジの勝利基準の重大な候補ではありません。
pppery


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を追加します。


(2^j)-> 2^j2バイト節約できます。.awkファイルには、末尾なしで動作します\nので、あなたは別のバイトを剃り落とすことができます。
mklement0

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]
ウゴレン

入力で1,2,3 a[:1]は機能しません。tuple + listは許可されていません。よりよい解決策が存在する
AMK

+1i,*a=a
primo

i,*a=aPython 3ではありませんか?私の2.7.1では動作しません。
ウゴレン

2.7.2も。これは、私が以前にそのトリックを見たことがない理由を説明するかもしれません...ほとんどのコードゴルフサーバーは2.7.xを実行します。
プリモ

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

入力は、ウゴレンの解と同じ方法で取得されます。サンプル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)。出力はややいものになりますが、それでも大丈夫です。
ウゴレン

非常に賢い、ヒントをありがとう。
プリモ

3

J、19文字

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

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

出力のアスキーボクシングが呼び出されboxing、異種コレクションを提供します(ここでは配列の長さが異なります)。


2

Golfscript 48

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

このプログラムは、0からlength(input)までの数値のバイナリ表現を使用して、パワーセットアイテムを生成します。

入力

入力フォーマットはGolfscriptアレイフォーマット(例:あります[1 2 3]

出力

出力は、パワーセットを表す、改行で区切られた配列のコレクションです。例:

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

オンラインテスト

プログラムはここでオンラインテストできます


素晴らしいですが、改行で区切ることができますか?
-beatgammit

@tjameson同じ文字数を維持しながら、改行で区切って出力することに成功しました。私の答えの更新をご覧ください。
クリスチャンルパスク

2

ハスケル(96)

Control.Monadのインポート
System.Environmentのインポート
main = getArgs >> = mapM print.filterM(\ _-> [False ..])

インポートControl.Monadが許可されていない場合、これは100文字になります。

System.Environmentのインポート
main = getArgs >> = mapM print.p
pz = case z of {[]-> [[]]; x:y-> p y ++ map(x:)(py)}


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:ビットを使用して1upto のビットパターンを生成2^MMます。
  • ↓⍉:各ビットパターンが分離されるように行列を分割します
  • (/∘T)¨:各ビットパターンについて、からそれらのサブアイテムを選択しますT
  • ↑⍕¨:出力用に、各要素の文字列表現を取得し(ゼロではなく空白を使用して入力します)、行列としてフォーマットします(各要素が独自の行になるようにします)。

2

Scala、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

ここここで両方のソリューションを試すことができます。2番目のソリューションの説明は次のとおりです。

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末尾の改行なしでフォームの入力を予期し、同じ形式でサブセットを出力します。末尾にコンマが含まれることもあります。印刷される最初の行は常に空で、空のセットを示します。

オンラインでお試しください。

基本的な考え方は、各要素の隣にビットを配置し、各インクリメントの前に対応するサブセットを印刷しながら、繰り返しバイナリ値をインクリメントすることです。(ビットは、要素がサブセット内にあるかどうかを示します。)配列の左にあるセンチネルビットは、プログラムを終了するために使用されます。このバージョンでは、実際に指数関数的な数のセンチネルを作成して、いくつかのバイトを節約します。1つのセンチネルのみを使用するより効率的な99バイトのソリューションは、改訂履歴に記載されています。

各ビットは、1とその値としてエンコードされます。つまり、1またはのいずれか2です。テープは、各要素の前のビットと、隣接する要素間の単一のゼロセルでレイアウトされます。非最終要素のコンマはテープに含まれているので、区切り文字を処理するために余分な作業を行うことなく、要素を簡単に印刷できます。


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

@AMK、要件は各要素が1行で印刷されることです。しかしlistreplacinfもあれば確かに(削除することができ[[]]持つ[()]
ugoren

print'\n'.join(f(input()))2文字を保存します
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

パラメータの取得が長い:/


でもう1つの文字を削ることができmap(x:)(p y)++p y、さらにその上でさらに2つの文字を削ることができます[(x:),id]<*>p y。どうやら今<*>プレリュードにあります。(そうでfilterMはありません)。
ウィルネス

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

モナド!がベクトルに適用されるとき、それは「オドメーター」です。

  !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の「走行距離計」が反転したマトリックスを生成するようになったため、これはもはや有効ではありません。1バイトのコストで修正できます{x@&:'+!(#x)#2}。無関係:の短縮版は(#x)#2です2|~x
NGN

1

Mathematica、51

より多くの不正行為:

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

で使用し@{1,2,3}ます。


コードは、ハードコードするだけでなく、入力としてセットを取る必要があります。また、これはコードゴルフなので、コードのバイトカウントを含める必要があります(おそらく、不要なスペースを削除します)。
マーティンエンダー

このコンテストはもう長いので、この投稿はそのアイデアに向いていましたが、私はそれを編集しました。
LogicBreaker

1

JavaScript(ES6)、68バイト

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

デモ


なぜalert
シャギー

@Shaggyこのチャレンジは、各要素を個別の行に印刷するように明示的に要求します。これは、おそらく現在の標準では眉をひそめられるでしょう。ほとんどの答えはこのルールに固執しているようです。
アーナウルド

ああ、十分に公平です。「印刷」を「出力」と解釈しました。
シャギー


0

Ruby配列メソッドの組み合わせ(1.9から)[50文字]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.