Implementación de conjunto de potencia más corta

22

Definición del problema

Imprima el conjunto de potencia de un conjunto dado. Por ejemplo:

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

Cada elemento debe imprimirse en una línea separada, por lo que el ejemplo anterior se imprimirá como:

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

Código de ejemplo (en D, ejemplo de python aquí ):

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

Los elementos se pasarán como argumentos. Por ejemplo, el ejemplo proporcionado anteriormente se pasaría a un programa llamado powersetcomo:

powerset 1 2 3

Los argumentos serán alfanuméricos.

Reglas

  1. No hay bibliotecas además de io
  2. La salida no tiene que ser ordenada
  3. Powerset no tiene que ser almacenado, solo impreso
  4. Los elementos del conjunto deben estar delimitados (por ejemplo 1,2,3, [1,2,3]y ['1','2','3']son aceptables, pero 123no lo son
    • Los delimitadores finales están bien (p 1,2,3, == 1,2,3. Ej. )
  5. El mejor se determina en función del número de bytes

La mejor solución se decidirá no menos de 10 días después de la primera presentación.

beatgammit
fuente
Estrechamente relacionado con codegolf.stackexchange.com/questions/6380
Peter Taylor el
2
Si solo este desafío se actualizara para permitir los valores predeterminados, como regresar y funciones. Python sería 54 bytes: lambda L:reduce(lambda r,x:r+[s+[x]for s in r],L,[[]]).
mbomb007
No estoy de acuerdo en solo imprimir ... ¿Por qué no permitir tener los datos, la variable también ... Entonces, ¿por qué imprimir en columna y no en fila?
RosLuP

Respuestas:

15

Mathematica 16

Código

Subsets Es nativo de Mathematica.

Column@Subsets@s

El código (sin columna) se puede verificar en WolframAlpha . (Tuve que usar corchetes en lugar de @; significan lo mismo.

Uso

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

salida


Este método (55 caracteres) utiliza el enfoque sugerido por @ w0lf.

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

Descompostura

Genera las tuplas, compuestas de 0y 1's de longitudLength[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 la lista original (vector) 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}}

Eliminar los 0's. %es la abreviatura de "la salida anterior".

% /. {0:> Secuencia []}

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

Mostrar en columna:

Gráficos de Mathematica

DavidC
fuente
@tjameson Tenía serias dudas sobre si debería publicarlo, pero pensé que a algunas personas les podría resultar interesante saber que está integrado.
DavidC
Me parece interesante :)
Dr. belisarius
¿Puedes dejar el sy poner la entrada al final de la línea?
Solomon Ucko
15 bytes: Subsets/*Columncrea una función anónima que toma una lista y devuelve la visualización en columnas.
Romano
9

C, 118 115

Si bien puede guardar aproximadamente 20 caracteres con un formato más simple, de todos modos no va a ganar en términos de código de golf.

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

Pruebas:

/a.out 1 2 3
[]
[1]
[2]
[1,2]
[3]
[1,3]
[2,3]
[1,2,3]
conejo bebé
fuente
Agradable. Algunos consejos: el estilo K&R ( main(a,s)char**s;{...}), f|=x&1<<i&&printfes más corto que ?:.
Ugoren
Acabo de descubrir qué hay detrás x+=2(y dónde fue s[0]). Muy buen truco.
Ugoren
Negarse a jugar golf su respuesta porque "todavía no va a ganar en términos de golf de código de ninguna manera". hace que la respuesta no sea un contendiente serio para los criterios ganadores del desafío.
pppery
7

GolfScript, 22 18 caracteres

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

Otro intento en GolfScript con un algoritmo completamente diferente. El formato de entrada es el mismo que con la respuesta de w0lf. ( prueba en línea )

Howard
fuente
+1 ¡Gran solución! La mía se refactoriza para
facilitar la
5

GolfScript (43 caracteres)

Esto puede parecer bastante largo, pero es la primera solución para seguir la especificación: la entrada proviene de argumentos de la línea de comandos y la salida está delimitada por una nueva línea.

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

P.ej

$ golfscript.rb powset.gs 1 2 3
["1"]
["2"]
["2" "1"]
["3"]
["3" "2"]
["3" "1"]
["3" "2" "1"]
[]
Peter Taylor
fuente
Las citas no son necesarias, si eso hace la diferencia.
beatgammit
@tjameson, las citas provienen del uso de la forma más corta posible para imprimir. El hecho de que esos valores sean cadenas en lugar de enteros proviene de la incapacidad de GolfScript para acceder directamente a los argumentos de la línea de comandos: tiene que confiar en que el intérprete realice una evaluación en Ruby y coloque el resultado en una cadena.
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 ""}}

asumir guardado en el archivo powerset.awk, uso

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

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

ps si su awk no tiene la función y (), reemplácela con int(i/(2^j))%2pero agrega dos a la cuenta.

karakfa
fuente
(2^j)-> 2^jte ahorra 2 bytes; el .awkarchivo también funciona sin un final \n, por lo que puede eliminar otro byte.
mklement0
3

JavaScript, 98

Lamentablemente, se gasta una buena parte en el formato de salida.

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 una matriz de JavaScript. (por ejemplo, [1,2,3])

Salida

[]
1
1,2
2
2,3
1,2,3
1,3
3
Paul Walls
fuente
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,3o [1,2,3], la salida es:

[]
[3]
[2]
[2, 3]
[1]
[1, 3]
[1, 2]
[1, 2, 3]
AMK
fuente
[a[0]]=a[:1]
ugoren
con entrada 1,2,3 a[:1]no funciona. tupla + lista no permitida. Existe una mejor solución
AMK
+1 parai,*a=a
primo
¿No es i,*a=aPython 3? No funciona en mi 2.7.1.
ugoren
Tampoco en 2.7.2. Eso podría explicar por qué nunca he visto ese truco antes ... la mayoría de los servidores de golf de código ejecutan 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())

La entrada se toma de la misma manera que para la solución de ugoren . Muestra de E / S:

$ echo [1,2,3] | powerset.py
()
(1,)
(2, 1)
(3, 2, 1)
(3, 1)
(2,)
(3, 2)
(3,)
primo
fuente
1
Puede guardar algunos con def p(a,*v)y luego p(a[i:],n,*v). La salida se vuelve algo más fea, pero aún así está bien.
Ugoren
Muy inteligente, gracias por el dato.
primo
3

J, 19 caracteres

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

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

El boxeo ascii en la salida se llama boxingy proporciona una colección heterogénea (para diferentes longitudes de matrices aquí).

randomra
fuente
2

Golfscript 48

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

Este programa utiliza las representaciones binarias de números del 0 al largo (entrada) para generar elementos de conjunto de potencia.

Entrada

El formato de entrada es la Golfscript formato de matriz (ejemplo: [1 2 3])

Salida

La salida es una colección de matrices separadas por líneas nuevas, que representan el conjunto de potencia. Ejemplo:

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

Prueba en línea

El programa se puede probar en línea aquí .

Cristian Lupascu
fuente
Impresionante, pero ¿podrías delimitar con nuevas líneas?
beatgammit
@tjameson Logré generar una salida delimitada por líneas nuevas manteniendo el mismo recuento de caracteres. Por favor, vea la actualización de mi respuesta.
Cristian Lupascu
2

Haskell (96)

Control de importación.
Sistema de importación.
main = getArgs >> = mapM print.filterM (\ _-> [False ..])

Si Control.Monadno se permite importar , esto se convierte en 100 caracteres:

Sistema de importación.
main = getArgs >> = mapM print.p
pz = caso z de {[] -> [[]]; x: y-> p y ++ mapa (x:) (py)}
Hada lambda
fuente
2

Mathematica 53

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

ingrese la descripción de la imagen aquí

chyanog
fuente
2

APL (26)

Lee la entrada del teclado porque no hay 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

Explicación:

  • T←⎕: leer entrada, almacenar en T
  • M←⍴T: longitud de la tienda de TenM
  • (M/2)⊤⍳2*M: genera los patrones de bits para usar 1hasta2^MM bits.
  • ↓⍉: divide la matriz para que cada patrón de bits esté separado
  • (/∘T)¨: para cada patrón de bits, seleccione los subelementos de T .
  • ↑⍕¨: para la salida, obtenga la representación de cadena de cada elemento (para que se llene usando espacios en blanco y no ceros), y formatee como una matriz (para que cada elemento esté en su propia línea).
marinus
fuente
2

Scala, 81

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

JavaScript ( ES6 ) 76

Parcialmente copiado de este: /codegolf//a/51502/21348

Usando un mapa de bits, por lo que está limitado a no más de 32 elementos.

Ejecute el fragmento en Firefox para probar.

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
fuente
2

C # 164

Hombre, esto es difícil en 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
fuente
2

Python 2, 64 bytes

Usando una entrada separada por comas:

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

Pyth, 4 bytes (usando incorporado) o 14 bytes (sin)

Como señaló @Jakube en los comentarios, Pyth es demasiado reciente para esta pregunta. Aún así, aquí hay una solución que utiliza el operador de conjunto de potencia incorporado de Pyth:

jbyQ

Y aquí hay uno sin él:

jbu+Gm+d]HGQ]Y

Puedes probar ambas soluciones aquí y aquí . Aquí hay una explicación de la segunda solución:

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
fuente
2

brainfuck, 94 bytes

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

Formateado:

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

Espera la entrada del formulario 9,10,11sin una nueva línea final y genera subconjuntos en el mismo formato, a veces con una coma final. La primera línea impresa siempre estará vacía, lo que significa el conjunto vacío.

Pruébalo en línea.

La idea básica es colocar un bit al lado de cada elemento, luego incrementar repetidamente el número binario mientras imprime el subconjunto correspondiente antes de cada incremento. (Un bit indica si un elemento está en el subconjunto). Se utiliza un bit centinela a la izquierda de la matriz para terminar el programa. Esta versión en realidad crea un número exponencial de centinelas para guardar algunos bytes; En el historial de revisiones se puede encontrar una solución más eficiente de 99 bytes que solo usa un centinela.

Cada bit está codificado como uno más su valor; es decir, puede ser 1o 2. La cinta se presenta con el bit antes de cada elemento y una sola celda cero entre elementos adyacentes. La coma se incluye en la cinta para elementos no finales, por lo que podemos imprimir convenientemente elementos sin hacer ningún trabajo adicional para manejar delimitadores.

Mitch Schwartz
fuente
2

APL (Dyalog Classic) , 13 bytes

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

Pruébalo en línea!

Salida:

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

Hay una línea en blanco al final para representar el conjunto vacío.

Explicación:

entrada evaluada

⎕,¨⊂⊂⍬ agregar una lista numérica vacía después de cada elemento

∘., producto cartesiano

/ reducción (foldr)

revelar (necesario después de la reducción de APL)

En este punto, el resultado es una matriz n-dimensional de 2 por -...- por-2, donde n es la longitud de la entrada.

, aplanar en un vector

convertir el vector en una matriz vertical 2 n -by-1, de modo que cada subconjunto esté en una línea separada

ngn
fuente
2

Haskell , 80 78 bytes

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

Pruébalo en línea!

Angs
fuente
Los requisitos de E / S son horribles, sin embargo, las personas los interpretan con bastante soltura. Si cambia a tomar entrada a través de stdin , podría guardar 15 bytes, vea esto .
ბიმო
1

Python, 93 87 caracteres

Python simplifica el formateo, porque la entrada / salida requerida coincide con su formato nativo.
Solo admite elementos que son literales de Python (por ejemplo 1,2,'hello', no 1,2,hello).
Lee entradas estándar, no 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
fuente
print f(input())más corto
AMK
@AMK, el requisito es que cada elemento se imprima en una línea. Pero listtampoco puede ser eliminado (si también replacinf [[]]con [()].
ugoren
print'\n'.join(f(input()))salva dos personajes
beary605
@ beary605, no funciona, f()contiene tuplas, no cadenas.
Ugoren
1

Ruby, 39

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

Haskell 89 caracteres

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

Obtener parámetros es largo: /

Kyticka
fuente
se puede eliminar un carácter más con map(x:)(p y)++p yy aún dos caracteres más por encima de eso con [(x:),id]<*>p y. Aparentemente <*>está en el preludio ahora. ( filterMno es)
Will Ness
1

R, 63

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

Aquí, vrepresenta un vector.

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
fuente
1

K, 14 bytes

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

Genere todos los vectores 0/1 siempre que la entrada, recopile los índices de 1s y utilícelos para seleccionar elementos del vector de entrada. En la práctica:

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

Esto es un poco liberal con los requisitos de salida, pero creo que es legal. La parte más cuestionable es que el conjunto vacío se representará en una forma dependiente del tipo; !0es cómo K denota un vector numérico vacío:

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

Explicación

El (#x)#2construye un vector 2tan largo como la entrada:

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

Cuando !se aplica monádico a un vector, es "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)

Luego usamos "where" ( &) en cada ( ') vector para recopilar sus índices. El colon es necesario para desambiguar entre la forma monádica y la 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)

Si solo quisiéramos combinar vectores, estaríamos listos, pero necesitamos usarlos como índices en el conjunto original. Afortunadamente, el operador de indexación de K @puede aceptar una estructura compleja de índices y producirá un resultado con la misma forma:

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

Elegante, no?

JohnE
fuente
1
Esto ya no es válido, ya que el "odómetro" en OK ahora genera una matriz invertida. Se puede corregir a costa de un solo byte: {x@&:'+!(#x)#2}. Sin relación: un equivalente más corto de (#x)#2is 2|~x.
ngn
1

Mathematica, 51

Más trampas:

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

Usar con @{1,2,3}.

LogicBreaker
fuente
Su código debe tomar el conjunto como entrada, no solo codificarlo. Además, dado que este es el código de golf, debe incluir el recuento de bytes del código (y probablemente eliminar los espacios innecesarios).
Martin Ender
Dado que este concurso terminó hace mucho, la publicación fue más para la idea, pero la he editado.
LogicBreaker
1

JavaScript (ES6), 68 bytes

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

Manifestación

Arnauld
fuente
¿Por qué el alert?
Shaggy
@Shaggy El desafío pide explícitamente imprimir cada elemento en una línea separada, lo que probablemente estaría mal visto con nuestros estándares actuales. La mayoría de las respuestas parecen apegarse a esta regla.
Arnauld
Ah, bastante justo; Interpreté "imprimir" como "salida".
Shaggy
0

Combinación de métodos de Ruby Array (desde 1.9) [50 caracteres]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
principianteProg
fuente