Implementação mais curta do conjunto de potência

22

Definição de problema

Imprima o conjunto de potência de um determinado conjunto. Por exemplo:

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

Cada elemento deve ser impresso em uma linha separada, portanto, o exemplo acima seria impresso como:

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

Código de exemplo (em D, exemplo de python aqui ):

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

Entrada

Os elementos serão passados ​​como argumentos. Por exemplo, o exemplo fornecido acima seria passado para um programa chamado powersetcomo:

powerset 1 2 3

Os argumentos serão alfanuméricos.

Regras

  1. Nenhuma biblioteca além de io
  2. A saída não precisa ser solicitada
  3. O Powerset não precisa ser armazenado, apenas impresso
  4. Os elementos do conjunto devem ser delimitados (por exemplo 1,2,3, [1,2,3]e ['1','2','3']são aceitáveis, mas 123não são
    • Delimitadores à direita são bons (por exemplo 1,2,3, == 1,2,3)
  5. O melhor é determinado com base no número de bytes

A melhor solução será decidida pelo menos 10 dias após o primeiro envio.

beatgammit
fonte
Intimamente relacionado com codegolf.stackexchange.com/questions/6380 #
Peter Taylor
2
Se apenas esse desafio foi atualizado para permitir os padrões, como retorno e funções. Python seria de 54 bytes: lambda L:reduce(lambda r,x:r+[s+[x]for s in r],L,[[]]).
mbomb007
Não concordo apenas em imprimir ... Por que não permitir ter os dados, a variável também .. Do que por que imprimir na coluna e não na linha?
RosLuP

Respostas:

15

Mathematica 16

Código

Subsets é nativo do Mathematica.

Column@Subsets@s

O código (sem coluna) pode ser verificado no WolframAlpha . (Eu tive que usar colchetes em vez de @; eles significam a mesma coisa.

Uso

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

saída


Este método (55 caracteres) usa a abordagem sugerida por @ w0lf.

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

Demolir

Gere as tuplas, compostas por 0e 1de comprimentoLength[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}}

Multiplique a lista original (vetor) por cada 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}}

Exclua os 0. %é uma abreviação de "a saída anterior".

% /. {0:> Sequência []}

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

Exibir na coluna:

Gráficos do Mathematica

DavidC
fonte
@tjameson Eu tinha sérias dúvidas sobre se deveria publicá-lo, mas achei que algumas pessoas acham interessante saber que ele está embutido.
21312
Acho interessante :)
Dr. belisarius
Você pode deixar sa entrada e colocar a entrada no final da linha?
Solomon Ucko 5/01
15 bytes: Subsets/*Columncria uma função anônima que pega uma lista e retorna a exibição em colunas.
Roman
9

C, 118 115

Embora possa economizar aproximadamente 20 caracteres com formatação mais simples, ainda assim não será possível ganhar em termos de código de golfe.

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

Teste:

/a.out 1 2 3
[]
[1]
[2]
[1,2]
[3]
[1,3]
[2,3]
[1,2,3]
coelho bebê
fonte
Agradável. Algumas dicas: o estilo K&R ( main(a,s)char**s;{...}) f|=x&1<<i&&printfé menor que ?:.
ugoren
Apenas descobri o que está por trás x+=2(e para onde foi s[0]). Truque muito bom.
Ugoren
Recusando-se a jogar sua resposta porque "ainda não vai ganhar em termos de código de golfe de qualquer maneira". faz com que a resposta não seja um sério candidato aos critérios vencedores do desafio.
pppery
7

GolfScript, 22 18 caracteres

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

Outra tentativa no GolfScript com um algoritmo completamente diferente. O formato de entrada é o mesmo da resposta de w0lf. ( teste online )

Howard
fonte
+1 Ótima solução! O meu é refatorado para
facilitar a
5

GolfScript (43 caracteres)

Isso pode parecer bastante longo, mas é a primeira solução a seguir a especificação: a entrada é proveniente de argumentos da linha de comando e a saída é delimitada por nova linha.

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

Por exemplo

$ golfscript.rb powset.gs 1 2 3
["1"]
["2"]
["2" "1"]
["3"]
["3" "2"]
["3" "1"]
["3" "2" "1"]
[]
Peter Taylor
fonte
As cotações não são necessárias, se isso faz diferença.
beatgammit
@tjameson, as citações vêm do uso da maneira mais curta possível para imprimir. O fato de esses valores serem cadeias de caracteres, e não números inteiros, resulta da incapacidade do GolfScript de acessar diretamente os argumentos da linha de comando: ele precisa contar com o intérprete fazendo uma avaliação no Ruby e colocando o resultado em uma string.
21412 Peter Taylor em
4

awk (82)

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

suponha que seja salvo no arquivo powerset.awk, use

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

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

ps se o seu awk não tiver a função e (), substitua-o por, int(i/(2^j))%2mas acrescente dois à contagem.

karakfa
fonte
(2^j)-> 2^jeconomiza 2 bytes; o .awkarquivo também funciona sem rastro \n, para que você possa cortar outro byte.
precisa saber é o seguinte
3

JavaScript, 98

Infelizmente, um bom pedaço é gasto na formatação da saída.

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

Entrada

Toma uma matriz JavaScript. (por exemplo, [1,2,3])

Saída

[]
1
1,2
2
2,3
1,2,3
1,3
3
Paul Walls
fonte
3

Python ( 74 70 caracteres)

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

para entrada como 1,2,3ou [1,2,3], a saída é:

[]
[3]
[2]
[2, 3]
[1]
[1, 3]
[1, 2]
[1, 2, 3]
AMK
fonte
[a[0]]=a[:1]
ugoren
com entrada 1,2,3 a[:1]não funciona. tupla + lista não permitida. Existe melhor solução
AMK
+1 parai,*a=a
primo
Não é i,*a=aPython 3? Não funciona no meu 2.7.1.
ugoren
Nem no 2.7.2. Isso pode explicar por que nunca vi esse truque antes ... a maioria dos servidores de código de golfe executa o 2.7.x.
Primo
3

Python 70 67 bytes

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

A entrada é feita da mesma maneira que na solução da ugoren . E / S de amostra:

$ echo [1,2,3] | powerset.py
()
(1,)
(2, 1)
(3, 2, 1)
(3, 1)
(2,)
(3, 2)
(3,)
primo
fonte
1
Você pode salvar alguns com def p(a,*v)e depois p(a[i:],n,*v). A saída se torna um pouco mais feia, mas ainda está OK.
ugoren
Muito esperto, obrigado pela dica.
Primo
3

J, 19 caracteres

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

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

O boxe ascii na saída é chamado boxinge fornece coleta de heterogênio (para diferentes comprimentos de matrizes aqui).

randomra
fonte
2

Golfscript 48

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

Este programa usa as representações binárias de números de 0 a comprimento (entrada) para gerar itens do conjunto de energia.

Entrada

O formato de entrada é do formato de matriz Golfscript (exemplo: [1 2 3])

Saída

A saída é uma coleção de matrizes separadas por novas linhas, representando o conjunto de energia. Exemplo:

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

Teste Online

O programa pode ser testado online aqui .

Cristian Lupascu
fonte
Incrível, mas você pode delimitar com novas linhas?
beatgammit
@tjameson Eu consegui sair delimitado por novas linhas, mantendo a mesma contagem de caracteres. Por favor, veja a atualização para minha resposta.
21412 Cristian Lupascu
2

Haskell (96)

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

Se a importação Control.Monadnão for permitida, isso se tornará 100 caracteres:

import System.Environment
main = getArgs >> = mapM print.p
pz = caso z de {[] -> [[]]; x: y-> p y ++ mapa (x:) (py)}
Lambda Fairy
fonte
2

Mathematica 53

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

insira a descrição da imagem aqui

chyanog
fonte
2

APL (26)

Lê a entrada do teclado porque não há 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

Explicação:

  • T←⎕: ler entrada, armazenar em T
  • M←⍴T: tamanho da loja TemM
  • (M/2)⊤⍳2*M: gerar os padrões de bits para usar 1até bits.2^MM
  • ↓⍉: divida a matriz para que cada padrão de bit seja separado
  • (/∘T)¨: para cada padrão de bit, selecione os subitens de T.
  • ↑⍕¨: para saída, obtenha a representação de seqüência de caracteres de cada elemento (para que seja preenchida usando espaços em branco e não zeros) e formate como uma matriz (para que cada elemento esteja em sua própria linha).
marinus
fonte
2

Scala, 81

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

JavaScript ( ES6 ) 76

Parcialmente copiado deste: /codegolf//a/51502/21348

Usando um bitmap, ele fica limitado a não mais que 32 elementos.

Execute o trecho no Firefox para testar.

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>

edc65
fonte
2

C # 164

Cara, isso é difícil em 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);}
Ben Reich
fonte
2

Python 2, 64 bytes

Usando entrada separada por vírgula:

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

Pitão, 4 bytes (usando embutido) ou 14 bytes (sem)

Como observado por @Jakube nos comentários, Pyth é muito recente para esta pergunta. Ainda assim, aqui está uma solução usando o operador powerset embutido do Pyth:

jbyQ

E aqui está um sem ele:

jbu+Gm+d]HGQ]Y

Você pode tentar as duas soluções aqui e aqui . Aqui está uma explicação da segunda solução:

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

brainfuck, 94 bytes

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

Formatado:

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

Espera a entrada do formulário 9,10,11sem uma nova linha à direita e gera subconjuntos no mesmo formato, às vezes com uma vírgula à direita. A primeira linha impressa estará sempre vazia, significando o conjunto vazio.

Experimente online.

A idéia básica é colocar um pouco ao lado de cada elemento e incrementar repetidamente o número binário enquanto imprime o subconjunto correspondente antes de cada incremento. (Um bit indica se um elemento está no subconjunto.) Um bit sentinela à esquerda da matriz é usado para finalizar o programa. Esta versão realmente cria um número exponencial de sentinelas para salvar alguns bytes; uma solução mais eficiente de 99 bytes que usa apenas um sentinela pode ser encontrada no histórico de revisões.

Cada bit é codificado como um mais seu valor; ou seja, pode ser um 1ou 2. A fita é disposta com o bit antes de cada elemento e uma única célula zero entre os elementos adjacentes. A vírgula está incluída na fita para elementos não finais, para que possamos convenientemente apenas imprimir elementos sem fazer nenhum trabalho extra para manipular delimitadores.

Mitch Schwartz
fonte
2

APL (Dyalog Classic) , 13 bytes

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

Experimente online!

Saída:

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

Há uma linha em branco no final para representar o conjunto vazio.

Explicação:

entrada avaliada

⎕,¨⊂⊂⍬ anexar uma lista numérica vazia após cada elemento

∘., produto cartesiano

/ redução (foldr)

divulgar (necessário após redução no APL)

Nesse ponto, o resultado é uma matriz n-dimensional de 2 por -...- por-2, em que n é o comprimento da entrada.

, achatar em um vetor

transforme o vetor em uma matriz vertical de 2 n por 1, para que cada subconjunto esteja em uma linha separada

ngn
fonte
2

Haskell , 80 78 bytes

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

Experimente online!

Angs
fonte
Os requisitos de E / S são horríveis, no entanto, as pessoas os estão interpretando de maneira bastante vaga. Se você mudar para receber entrada via stdin, poderá salvar 15 bytes, veja isso .
ბიმო
1

Python, 93 87 caracteres

O Python simplifica a formatação, porque a entrada / saída necessária corresponde ao seu formato nativo.
Suporta apenas itens que são literais em Python (por exemplo 1,2,'hello', não 1,2,hello).
Lê entrada padrão, não parâmetros.

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
Ugoren
fonte
print f(input())mais curto
AMK
@AMK, o requisito é que cada elemento seja impresso em uma linha. Mas listpode realmente ser removido (se também replacinf [[]]com [()].
ugoren
print'\n'.join(f(input()))salva dois personagens
beary605
@ beary605, não funciona, f()contém tuplas, não seqüências de caracteres.
Ugoren
1

Ruby, 39

$*.map{p *$*.combination($.)
$.+=1}
p$*
Lowjacker
fonte
1

Haskell 89 chars

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

A obtenção de parâmetros é longa: /

Kyticka
fonte
mais um caractere pode ser raspado com map(x:)(p y)++p ye mais dois caracteres acima disso com [(x:),id]<*>p y. Aparentemente, <*>está no prelúdio agora. ( filterMnão é).
Will Ness
1

R, 63

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

Aqui, vrepresenta um vetor.

Uso :

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)
Sven Hohenstein
fonte
1

K, 14 bytes

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

Gere todos os vetores 0/1 desde a entrada, reúna os índices de 1s e use-os para selecionar elementos do vetor de entrada. Na prática:

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

Isso é um pouco liberal com os requisitos de saída, mas acho que é legal. A parte mais questionável é que o conjunto vazio será representado em uma forma dependente do tipo; !0é como K denota um vetor numérico vazio:

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

Explicação

O (#x)#2constrói um vector de 2tão longa como a de entrada:

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

Quando a monádica !é aplicada a um vetor, é "odômetro":

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

Em seguida, usamos "where" ( &) em cada 'vetor ( ) para reunir seus índices. O cólon é necessário para desambiguar entre a forma monádica e diádica de &:

  &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 apenas quiséssemos vetores de combinação, estaríamos prontos, mas precisamos usá-los como índices no conjunto original. Felizmente, o operador de indexação de K @pode aceitar uma estrutura complexa de índices e produzirá um resultado com a mesma forma:

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

Elegante, não?

JohnE
fonte
1
Isso não é mais válido, pois o "odômetro" no oK agora gera uma matriz invertida. Ele pode ser corrigido com o custo de um único byte: {x@&:'+!(#x)#2}. Não relacionado: um equivalente mais curto de (#x)#2é 2|~x.
NGN
1

Mathematica, 51

Mais trapaça:

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

Use com @{1,2,3}.

LogicBreaker
fonte
Seu código deve ter o conjunto como entrada, não apenas codificá-lo. Além disso, como se trata de código de golfe, você deve incluir a contagem de bytes do código (e provavelmente remover os espaços desnecessários).
Martin Ender
Como esse concurso já terminou há muito tempo, o post foi mais para a ideia, mas eu a editei.
LogicBreaker
1

JavaScript (ES6), 68 bytes

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

Demo

Arnauld
fonte
Por que o alert?
Shaggy
@Shaggy O desafio pede explicitamente para imprimir cada elemento em uma linha separada - o que provavelmente seria desaprovado pelos nossos padrões atuais. A maioria das respostas parece seguir essa regra.
Arnauld
Ah, é justo; Eu interpretei "impressão" como "saída".
Shaggy
0

Combinação de método Ruby Array (de 1.9) [50 caracteres]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
beginnerProg
fonte