En kısa güç seti uygulaması


22

Problem tanımı

Belirli bir setin güç ünitesini yazdırın. Örneğin:

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

Her eleman ayrı bir satıra basılacaktır, bu nedenle yukarıdaki örnek şöyle basılacaktır:

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

Örnek kod (D'de python örneği burada ):

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

Giriş

Öğeler argüman olarak iletilir. Örneğin, yukarıda verilen örnek şu şekilde adlandırılan bir programa geçirilir powerset:

powerset 1 2 3

Argümanlar alfanümerik olacaktır.

kurallar

  1. İo dışında kitaplık yok
  2. Çıktı sipariş etmek zorunda değil
  3. Powerset'in saklanması gerekmiyor, yalnızca basılı
  4. Kümesindeki elemanlar, örneğin (ayrılmış gerekir 1,2,3, [1,2,3]ve ['1','2','3']kabul edilebilir, ancak 123değil
    • İz sınırlayıcıları iyi (örn. 1,2,3, == 1,2,3)
  5. En iyi bayt sayısına göre belirlenir

İlk başvurudan en az 10 gün sonra en iyi çözüme karar verilecektir.




2
Keşke ve işlevler gibi varsayılanlara izin vermek için sadece bu zorluk güncellendiyse. Python 54 byte olacaktır: lambda L:reduce(lambda r,x:r+[s+[x]for s in r],L,[[]]).
mbomb007

Sadece baskıda hemfikir değilim ... Neden verilere, değişkene de sahip olmama izin verilmiyor.
RosLuP

Yanıtlar:


15

Mathematica 16

kod

Subsets Mathematica'ya özgüdür.

Column@Subsets@s

Kod ( sütunsuz) WolframAlpha'da doğrulanabilir . (Yerine parantez kullanmak zorunda kaldım @; aynı şey demek istiyorlar.

kullanım

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

output


Bu yöntem (55 karakter) @ w0lf tarafından önerilen yaklaşımı kullanır.

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

Yıkmak

Oluşan 0ve 1uzunluğunu gösteren tülleri oluşturunLength[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}}

Orijinal listeyi (vektör) her demetle çarpın:

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'Yi silin . %"önceki çıktı" için kısayol.

% /. {0:> Sıra []}

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

Sütunda göster:

Mathematica graphics


@tjameson Göndermem gerekip gerekmediği konusunda ciddi şüphelerim vardı, ancak bazı insanların yerleşik olduğunu bilmenin ilginç olabileceğini düşündüm.
DavidC

İlginç buluyorum :)
Dr. belisarius 23:12

Çıkıp sgirişi satır sonuna koyabilir misiniz?
Solomon Ucko

15 bayt: Subsets/*Columnbir liste alan ve ekranı sütunlar halinde döndüren isimsiz bir işlev yapar.
Roma,

9

C, 118 115

Daha kolay biçimlendirme ile yaklaşık 20 karakter kaydedebilir, ancak yine de kod golf açısından hiçbir şekilde kazanamayacaksınız.

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

Test yapmak:

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

Güzel. Bazı ipuçları: K & R tarzı ( main(a,s)char**s;{...}), f|=x&1<<i&&printfdaha kısa ?:.
ugoren

Sadece geride neler olduğunu anladım x+=2(ve nereye gitti s[0]). Gerçekten güzel numara.
ugoren

Cevabınızı golf atmayı reddetmek, çünkü "yine de her şekilde kod golf açısından kazanmayacak." cevabı, mücadelenin kazanan kriterleri için ciddi bir rakip değil.
pppery

7

GolfScript, 22 18 karakter

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

GolfScript'te tamamen farklı bir algoritma ile başka bir girişim. Giriş formatı w0lf cevabı ile aynıdır. ( çevrimiçi test )


+1 Harika bir çözüm! Maden okunabilirliği için refactored :-P
Cristian Lupascu 21:12

5

GolfScript (43 karakter)

Bu oldukça uzun görünebilir, ancak spec'i izleyen ilk çözümdür: input komut satırı argümanlarından ve output newline ile sınırlıdır.

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

Örneğin

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

Bir fark yaratırsa, alıntılar gerekli değildir.
Beatgammit

@tjameson, alıntılar yazdırmak için mümkün olan en kısa yoldan geliyor. Bu değerlerin tamsayılardan ziyade dizge olması, GolfScript'in doğrudan komut satırı argümanlarına erişememesinden kaynaklanmaktadır: Ruby'de bir değerlendirme yapan ve sonucu bir dizeye yerleştiren tercümana dayanması gerekir.
Peter Taylor

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 dosyasına kaydedilmiş, kullanım

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

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

eğer awk'nizin ve () fonksiyonu yoksa ps ile değiştirin, int(i/(2^j))%2ancak sayıya iki ekler.


(2^j)-> 2^jsize 2 bayt kaydeder; .awkdosyası da bir eğik olmadan çalışır \nbaşka byte tıraş böylece.
mklement0

3

JavaScript, 98

Ne yazık ki, çıktı biçimlendirmesi için iyi bir yığın harcanıyor.

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

Giriş

Bir JavaScript dizisini alır. (örneğin, [1,2,3])

Çıktı

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

3

Python ( 74 70 karakter)

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

giriş için 1,2,3veya [1,2,3]çıkış olarak:

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

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

giriş ile 1,2,3 a[:1]çalışmıyor. tuple + listesine izin verilmez. Daha iyi bir çözüm
bulun

+1i,*a=a
primo

i,*a=aPython 3 değil mi? Benim 2.7.1 üzerinde çalışmıyor.
ugoren

2.7.2 de. Bu neden daha önce hiç bu numarayı görmediğimi açıklayabilir ... çoğu kod golf sunucusu 2.7.x'i çalıştırır.
primo

3

Python 70 67 bayt

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

Giriş, ugoren'in çözümüyle aynı şekilde alınır . Örnek I / O:

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

1
Sen bazı kaydedebilir def p(a,*v)ve daha sonra p(a[i:],n,*v). Çıktı biraz çirkin hale gelir, ancak yine de tamam.
12'de ugoren

Çok zekice, bahşiş için teşekkürler.
primo

3

J, 19 karakter

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

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

Çıktıdaki ascii boks adı verilir boxingve heterojen toplanmasını sağlar (burada farklı diziler için).


2

Golf Bülteni 48

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

Bu program, powerset öğeleri oluşturmak için 0'dan uzunluk (giriş) 'e kadar sayıların ikili gösterimini kullanır.

Giriş

Giriş biçimi Golfscript dizi formatı (örnek: bir [1 2 3])

Çıktı

Çıktı, güç setini temsil eden yeni satırlarla ayrılmış bir dizi koleksiyonudur. Örnek:

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

Çevrimiçi Test

Program burada çevrimiçi olarak test edilebilir .


Müthiş, ama yeni hatlarla sınırlandırabilir misiniz?
beatgammit

@tjameson Aynı karakter sayısını korurken yeni satırlarla sınırlandırılmış çıktılar çıkarmayı başardım. Lütfen cevabımın güncellemesini görün.
Cristian Lupascu

2

Haskell (96)

Control.Monad'ı içe aktar
System.Environment alma
main = getArgs >> = mapM print.filterM (\ _-> [Yanlış ..])

İçe aktarmaya Control.Monadizin verilmiyorsa, bu 100 karakter olur :

System.Environment alma
main = getArgs >> = mapM print.p
pz = {[] -> [[]] durumunun z durumu; x: y-> p y ++ haritası (x:) (py)}

2

Mathematica 53

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

görüntü tanımını buraya girin


2

APL (26)

argvEşdeğeri olmadığı için klavyeden giriş okur .

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

Kullanımı:

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

Açıklama:

  • T←⎕: girişi okumak, depolamak T
  • M←⍴T: Mağaza uzunluğu TbölgesindekiM
  • (M/2)⊤⍳2*M: Bit desenleri oluşturmak 1kadar 2^Mkullanarak Mbit.
  • ↓⍉: her bit desen ayrı olacak şekilde matrisi bölün
  • (/∘T)¨: her bir bit kalıbı için, o alt öğeleri seç T.
  • ↑⍕¨: çıktı için, her bir öğenin dize gösterimini alın (boşlukları kullanarak ve sıfır kullanmayacak şekilde doldurun) ve bir matris olarak biçimlendirin (böylece her öğe kendi satırında olacak şekilde).

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

Kısmen bundan kopyalandı: /codegolf//a/51502/21348

Bir bitmap kullanmak, bu nedenle en fazla 32 öğe ile sınırlıdır.

Test etmek için snippet'i Firefox'ta çalıştırın.

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

Adamım bu C # zor!

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 bayt

Virgülle ayrılmış giriş kullanma:

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

Pyth, 4 bayt (yerleşik kullanarak) veya 14 bayt (olmadan)

Yorumlarda @Jakube tarafından belirtildiği gibi, Pyth bu soru için çok yeni. Yine de Pyth'in yerleşik güç operatörü kullanan bir çözüm var:

jbyQ

Ve işte onsuz bir tane:

jbu+Gm+d]HGQ]Y

Her iki çözümü de burada ve burada deneyebilirsiniz . İşte ikinci çözümün açıklaması:

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 bayt

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

biçimlendirilmiş:

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

9,10,11Sondaki yeni satır olmadan formun girilmesini bekler ve bazen sondaki virgülle aynı formatta alt kümeleri çıkarır. Basılan ilk satır, her zaman boş olacak ve boş seti belirten olacaktır.

Çevrimiçi deneyin.

Temel fikir, her elemanın yanına bir bit yerleştirmek ve ardından her bir artıştan önce karşılık gelen alt takımı yazdırırken ikili sayıyı art arda artırmaktır. (Bit, bir öğenin alt kümede olup olmadığını gösterir.) Dizinin solundaki sentinel biti, programı sonlandırmak için kullanılır. Bu sürüm aslında bazı baytları kurtarmak için üstel bir sayıda nöbetçi yaratıyor; revizyon tarihinde sadece bir nöbetçi kullanan daha verimli 99 baytlık bir çözüm bulunabilir.

Her bit bir artı bir değer olarak kodlanır; yani, ya olabilir ya 1da 2. Bant, her bir elemanın önündeki bit ile bitişik elemanlar arasında tek bir sıfır hücresiyle yerleştirilir. Virgül, son olmayan elemanlar için kasete dahil edilmiştir, böylece sınırlayıcıları işlemek için fazladan bir iş yapmadan öğeleri kolayca yazdırabiliriz.


2

APL (Dyalog Klasik) , 13 bayt

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

Çevrimiçi deneyin!

Çıktı:

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

Boş kümeyi temsil etmek için sonunda boş bir satır var.

Açıklama:

değerlendirilmiş girdi

⎕,¨⊂⊂⍬ her elemandan sonra boş bir sayısal liste ekle

∘., Kartezyen ürün

/ azaltma (kat)

ifşa (APL’de azaltmadan sonra gerekli)

Bu noktada, sonuç n-boyutlu 2x -...- -2 dizisidir, burada n, girişin uzunluğudur.

, vektör haline getirmek

vektörü dik bir 2 n -by-1 matrisine dönüştürün, böylece her alt küme ayrı bir satırda kalır


2

Haskell , 80 78 bayt

import System.Environment
main=getArgs>>=mapM(print.concat).mapM(\a->[[a],[]])

Çevrimiçi deneyin!


G / Ç gereklilikleri korkunç, ancak insanlar onları oldukça gevşek yorumluyorlar. Stdin üzerinden giriş almaya geçerseniz, 15 byte tasarruf edebilirsiniz, buna bakın .
ბიმო


1

Python, 93 87 karakter

Python biçimlendirmeyi basitleştirir, çünkü gerekli girdi / çıktı yerel biçimiyle eşleşir.
Yalnızca Python değişmezleri olan öğeleri destekler (örn . 1,2,'hello'Değil 1,2,hello).
Parametreleri değil standart girişi okur.

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())kısa
AMK

@ AMK, gereksinim her elemanın bir satırda basılmasıdır. Ama listaynı zamanda replacinf eğer gerçekten (kaldırılabilir [[]]ile [()].
ugoren

print'\n'.join(f(input()))iki karakter kazandırır
beary605

@ beary605, çalışmıyor f(), ipler içeriyor, teller içeriyor.
ugoren


1

Haskell 89 karakter

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

Parametreleri almak uzun: /


bir tane daha char ile traş edilebilir map(x:)(p y)++p yve bununla birlikte iki tane daha char olabilir [(x:),id]<*>p y. Görünüşe göre şimdi <*>Prelude . ( filterMdeğil).
Ness,

1

R, 63

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

Burada vbir vektörü temsil eder.

Kullanım :

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 bayt

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

Girdi olduğu sürece tüm 0/1 vektörleri oluşturun, 1'lerin indekslerini toplayın ve giriş vektöründen elemanlar seçmek için bunları kullanın. Uygulamada:

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

Bu çıktı gereksinimleri ile biraz liberal, ancak bunun yasal olduğunu düşünüyorum. En tartışmalı kısım, boş kümenin türe bağımlı bir formda gösterileceği; !0K, boş bir sayısal vektörü nasıl ifade eder:

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

açıklama

(#x)#2Bir vektör oluşturur 2sürece giriş olarak:

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

Monadik !bir vektöre uygulandığında, "kilometre sayacı" dır:

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

Sonra dizinlerini toplamak &için her ( ') vektöründe "where" ( ) kullanırız . Kolon, monadik ve diyadik formlar arasında ayrıştırmak için gereklidir &:

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

Eğer sadece kombinasyon vektörleri isteseydik, yapılmalıydık, ancak bunları orijinal sette indeksler olarak kullanmamız gerekiyor. Neyse ki, K'nin indeksleme operatörü @endekslerin karmaşık bir yapısını kabul edebilir ve aynı şekilde bir sonuç üretecektir:

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

Zarif, hayır?


1
Bu artık geçerli değildir, çünkü OK'de "kilometre sayacı" şimdi çevrilmiş bir matris oluşturur. Tek bir bayt pahasına düzeltilebilir: {x@&:'+!(#x)#2}. İlgisiz: daha kısa bir eşdeğer (#x)#2DİR 2|~x.
ngn

1

Mathematica, 51

Daha fazla hile:

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

İle kullanın @{1,2,3}.


Kodunuz sadece kodlama yerine seti girdi olarak almalıdır. Ayrıca, bu kod golf olduğundan, kodun bayt sayısını eklemelisiniz (ve muhtemelen gereksiz boşlukları kaldırın).
Martin Ender

Bu yarışma çok uzun sürdüğü için, yazı fikir için daha fazlaydı, ama ben düzenlemiştim.
LogicBreaker

1

JavaScript (ES6), 68 bayt

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

gösteri


Neden alert?
Shaggy,

@Shaggy Yarışma açıkça her bir öğenin ayrı bir satıra yazdırılmasını istiyor - bu da muhtemelen mevcut standartlarımıza göre kaşlarını çattıracak . Cevapların çoğu bu kurala bağlı görünüyor.
Arnauld

Ah, yeterince adil; "Print" i "output" olarak yorumladım.
Shaggy,


0

Ruby Array yöntemi kombinasyonu (1.9 dan) [50 karakter]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.