Implementazione del power set più breve


22

Definizione del problema

Stampa il powerset di un determinato set. Per esempio:

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

Ogni elemento deve essere stampato su una riga separata, quindi l'esempio sopra sarebbe stampato come:

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

Codice di esempio (in D, esempio di python qui ):

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

Ingresso

Gli elementi verranno passati come argomenti. Ad esempio, l'esempio fornito sopra verrebbe passato a un programma chiamato powersetcome:

powerset 1 2 3

Gli argomenti saranno alfanumerici.

Regole

  1. Nessuna biblioteca oltre a io
  2. L'output non deve essere ordinato
  3. Powerset non deve essere memorizzato, ma solo stampato
  4. Gli elementi nel set devono essere delimitati (ad esempio 1,2,3, [1,2,3]e ['1','2','3']sono accettabili, ma 123non lo sono
    • I delimitatori finali vanno bene (ad es. 1,2,3, == 1,2,3)
  5. La migliore è determinata in base al numero di byte

La soluzione migliore sarà decisa non meno di 10 giorni dopo la prima presentazione.




2
Se solo questa sfida fosse aggiornata per consentire le impostazioni predefinite, come il ritorno e le funzioni. Pitone sarebbe 54 byte: lambda L:reduce(lambda r,x:r+[s+[x]for s in r],L,[[]]).
mbomb007,

Non sono d'accordo solo nella stampa ... Perché non consentire di avere i dati, anche la variabile .. Perché stampare in colonna e non in riga?
RosLuP,

Risposte:


15

Mathematica 16

Codice

Subsets è originario di Mathematica.

Column@Subsets@s

Il codice (senza colonna) può essere verificato su WolframAlpha . (Ho dovuto usare le parentesi invece di @; significano la stessa cosa.

uso

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

output


Questo metodo (55 caratteri) utilizza l'approccio suggerito da @ w0lf.

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

Abbattersi

Genera le tuple, composte da 0e 1'di lunghezzaLength[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}}

Moltiplica l'elenco originale (vettore) per ciascuna tupla:

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

Elimina il 0. %è una scorciatoia per "l'output precedente".

% /. {0:> Sequenza []}

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

Visualizza nella colonna:

Mathematica graphics


@tjameson Avevo seri dubbi sull'opportunità di pubblicarlo, ma ho pensato che alcune persone potrebbero trovare interessante sapere che è integrato.
DavidC

Lo trovo interessante :)
Dr. belisarius,

Puoi lasciare se inserire l'input alla fine della riga?
Solomon Ucko,

15 byte: Subsets/*Columncrea una funzione anonima che accetta un elenco e restituisce la visualizzazione in colonne.
Roman

9

C, 118 115

Sebbene possa salvare circa 20 caratteri con una formattazione più semplice, non vincerà comunque in termini di codice golf in entrambi i modi.

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:

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

Bello. Alcuni consigli: K&R style ( main(a,s)char**s;{...}), f|=x&1<<i&&printfè più corto di ?:.
ugoren,

Ho appena capito cosa c'è dietro x+=2(e dove è s[0]andato). Davvero un bel trucco.
ugoren,

Rifiutando di golf la tua risposta perché "continua a non vincere in termini di codice golf in entrambi i modi". rende la risposta non un serio contendente per i criteri vincenti della sfida.
pepery

7

GolfScript, 22 18 caratteri

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

Un altro tentativo in GolfScript con un algoritmo completamente diverso. Il formato di input è lo stesso della risposta di w0lf. ( test online )


+1 Ottima soluzione! Il mio è refactored per leggibilità :-P
Cristian Lupascu,

5

GolfScript (43 caratteri)

Può sembrare piuttosto lungo, ma è la prima soluzione a seguire le specifiche: l'input proviene da argomenti della riga di comando e l'output è delimitato da newline.

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

Per esempio

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

Le citazioni non sono necessarie, se questo fa la differenza.
beatgammit,

@tjameson, le citazioni provengono dall'uso del modo più breve possibile per stampare. Il fatto che questi valori siano stringhe anziché numeri interi deriva dall'incapacità di GolfScript di accedere direttamente agli argomenti della riga di comando: deve fare affidamento sull'interprete che fa una valutazione in Ruby e inserisce il risultato in una stringa.
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 ""}}

si assume salvato nel file powerset.awk, utilizzo

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

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

ps se il tuo awk non ha e () funzione, sostituiscilo con int(i/(2^j))%2ma ne aggiunge due al conteggio.


(2^j)-> 2^jti salva 2 byte; il .awkfile funziona anche senza trascinamento \n, quindi è possibile radere via un altro byte.
mklement0

3

JavaScript, 98

Purtroppo, un buon pezzo viene speso per la formattazione dell'output.

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

Ingresso

Accetta un array JavaScript. (ad es. [1,2,3])

Produzione

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

3

Python ( 74 70 caratteri)

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

per input come 1,2,3o [1,2,3], output è:

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

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

con input 1,2,3 a[:1]non funziona. tupla + lista non consentita. Esiste una soluzione migliore
AMK,

+1 peri,*a=a
primo

i,*a=aPython 3 non è ? Non funziona sul mio 2.7.1.
ugoren,

Né il 2.7.2. Questo potrebbe spiegare perché non ho mai visto quel trucco prima ... la maggior parte dei server di golf di codice eseguono 2.7.x.
primo

3

Python 70 67 byte

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

L'input è preso allo stesso modo della soluzione di ugoren . I / O di esempio:

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

1
Puoi salvarne un po 'con def p(a,*v)e poi p(a[i:],n,*v). L'output diventa un po 'più brutto, ma comunque OK.
ugoren,

Molto intelligente, grazie per il suggerimento.
primo

3

J, 19 caratteri

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

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

Il boxe ascii nell'output viene chiamato boxinge fornisce la raccolta di eterogene (per diverse lunghezze di array qui).


2

Golfscript 48

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

Questo programma utilizza le rappresentazioni binarie di numeri da 0 a lunghezza (input) per generare elementi powerset.

Ingresso

Il formato di input è il formato dell'array Golfscript (esempio: [1 2 3] )

Produzione

L'output è una raccolta di matrici separate da newline, che rappresentano il gruppo di potenza. Esempio:

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

Test online

Il programma può essere testato online qui .


Fantastico, ma potresti delimitare con le nuove righe?
beatgammit,

@tjameson Sono riuscito a produrre delimitati da newline mantenendo lo stesso numero di caratteri. Si prega di consultare l'aggiornamento alla mia risposta.
Cristian Lupascu,

2

Haskell (96)

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

Se l'importazione Control.Monadnon è consentita, questo diventa 100 caratteri:

import System.Environment
main = getArgs >> = mapM print.p
pz = case z di {[] -> [[]]; x: y-> p y ++ map (x:) (py)}

2

Mathematica 53

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

enter image description here


2

APL (26)

Legge l'input dalla tastiera perché non esiste un argvequivalente.

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

Uso:

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

Spiegazione:

  • T←⎕: lettura input, memorizzazione in T
  • M←⍴T: memorizzare la lunghezza di TinM
  • (M/2)⊤⍳2*M: genera i modelli di bit per l' utilizzo 1fino ai bit.2^MM
  • ↓⍉: dividere la matrice in modo che ogni modello di bit sia separato
  • (/∘T)¨: per ogni modello di bit, selezionare quelle voci secondarie da T.
  • ↑⍕¨: per l'output, ottenere la rappresentazione in forma di stringa di ciascun elemento (in modo che si riempia usando spazi vuoti e non zero) e formattare come una matrice (in modo che ogni elemento sia sulla propria riga).

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

Parzialmente copiato da questo: /codegolf//a/51502/21348

Utilizzando una bitmap, quindi è limitata a non più di 32 elementi.

Esegui lo snippet in Firefox per testarlo.

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

Amico, questo è difficile in 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 byte

Utilizzando input separato da virgole:

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

Pyth, 4 byte (usando builtin) o 14 byte (senza)

Come notato da @Jakube nei commenti, Pyth è troppo recente per questa domanda. Ecco ancora una soluzione che utilizza l'operatore PowerSet incorporato di Pyth:

jbyQ

Ed eccone uno senza di esso:

jbu+Gm+d]HGQ]Y

Puoi provare entrambe le soluzioni qui e qui . Ecco una spiegazione della seconda soluzione:

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 byte

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

formattato:

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

Prevede l'input del modulo 9,10,11senza una nuova riga finale e genera sottoinsiemi nello stesso formato, a volte con una virgola finale. La prima riga stampata sarà sempre vuota, indicando il set vuoto.

Provalo online.

L'idea di base è di posizionare un po 'accanto a ciascun elemento, quindi incrementare ripetutamente il numero binario durante la stampa del sottoinsieme corrispondente prima di ogni incremento. (Un bit indica se un elemento si trova nel sottoinsieme.) Un bit sentinella a sinistra dell'array viene utilizzato per terminare il programma. Questa versione crea effettivamente un numero esponenziale di sentinelle per salvare alcuni byte; una soluzione più efficiente di 99 byte che utilizza solo una sentinella può essere trovata nella cronologia delle revisioni.

Ogni bit è codificato come uno più il suo valore; cioè, può essere 1o 2. Il nastro è disposto con il bit prima di ogni elemento e una singola cella zero tra elementi adiacenti. La virgola è inclusa nel nastro per gli elementi non finali, quindi possiamo comodamente stampare gli elementi senza fare alcun lavoro aggiuntivo per gestire i delimitatori.


2

APL (Dyalog Classic) , 13 byte

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

Provalo online!

Produzione:

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

Alla fine c'è una riga vuota per rappresentare l'insieme vuoto.

Spiegazione:

input valutato

⎕,¨⊂⊂⍬ aggiungere un elenco numerico vuoto dopo ogni elemento

∘., prodotto cartesiano

/ riduzione (foldr)

divulgare (necessario dopo la riduzione dell'APL)

A questo punto il risultato è un array n-dimensionale 2 per -...- per-2, dove n è la lunghezza dell'input.

, appiattire in un vettore

trasforma il vettore in una matrice verticale 2 n -da-1, quindi ogni sottoinsieme si trova su una linea separata


2

Haskell , 80 78 byte

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

Provalo online!


I requisiti di I / O sono orribili, tuttavia le persone li interpretano in modo abbastanza vago. Se si passa a prendere input tramite stdin, è possibile salvare 15 byte, vedere questo .
ბიმო


1

Python, 93 87 caratteri

Python semplifica la formattazione, poiché l'input / output richiesto corrisponde al suo formato nativo.
Supporta solo elementi che sono letterali Python (ad esempio 1,2,'hello', non 1,2,hello).
Legge l'input standard, non i parametri.

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())più breve
AMK

@AMK, il requisito è che ogni elemento sia stampato su una riga. Ma listpuò davvero essere rimosso (se si sostituisce anche [[]]con [()].
ugoren

print'\n'.join(f(input()))salva due personaggi
beary605

@ beary605, non funziona, f()contiene tuple, non stringhe.
ugoren,


1

Haskell 89 caratteri

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

Ottenere parametri è lungo: /


un altro carattere può essere rasato con map(x:)(p y)++p ye ancora altri due caratteri sopra quello con [(x:),id]<*>p y. Apparentemente <*>è nel Preludio ora. ( filterMnon lo è).
Will Ness,

1

R, 63

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

Qui, v rappresenta un vettore.

Utilizzo :

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 byte

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

Genera tutti i vettori 0/1 fintanto che l'input, raccoglie gli indici di 1s e usa quelli per selezionare elementi dal vettore di input. In pratica:

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

Questo è un po 'liberale con i requisiti di output, ma penso che sia legale. La parte più discutibile è che l'insieme vuoto verrà rappresentato in una forma dipendente dal tipo; !0è come K indica un vettore numerico vuoto:

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

Spiegazione

Il (#x)#2costruisce un vettore di 2fintanto che l'ingresso:

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

Quando il monadico !viene applicato a un vettore, è "contachilometri":

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

Quindi usiamo "where" ( &) su ogni 'vettore ( ) per raccogliere i suoi indici. Il colon è necessario per chiarire la forma monadica e diadica di &:

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

Se volessimo solo vettori di combinazioni, avremmo finito, ma dobbiamo usarli come indici nel set originale. Fortunatamente, l'operatore di indicizzazione di K @può accettare una struttura complessa di indici e produrrà un risultato con la stessa forma:

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

Elegante, no?


1
Questo non è più valido, poiché "odometro" in oK ora genera una matrice capovolta. Può essere corretto al costo di un singolo byte: {x@&:'+!(#x)#2}. Non correlato: un equivalente più breve di (#x)#2è 2|~x.
ngn

1

Mathematica, 51

Più imbrogli:

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

Utilizzare con @{1,2,3}.


Il tuo codice dovrebbe prendere il set come input, non solo codificarlo. Inoltre, poiché si tratta di code golf, è necessario includere il conteggio dei byte del codice (e probabilmente rimuovere gli spazi non necessari).
Martin Ender,

Dal momento che questo concorso è finito da molto tempo, il post è stato più per l'idea, ma l'ho modificato.
LogicBreaker,

1

JavaScript (ES6), 68 byte

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

dimostrazione


Perché il alert?
Shaggy,

@Shaggy The challenge explicitly asks to print each element on a separate line -- which would probably frowned upon with our current standards. Most answers seem to stick to this rule.
Arnauld

Ah, fair enough; I interpreted "print" as "output".
Shaggy


0

Ruby Array method combination (from 1.9 ) [50 chars]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.