Implémentation du jeu d'alimentation le plus court

22

Définition du problème

Imprimez le jeu de puissance d'un ensemble donné. Par exemple:

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

Chaque élément doit être imprimé sur une ligne distincte, donc l'exemple ci-dessus serait imprimé comme suit:

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

Exemple de code (en D, exemple python ici ):

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

Contribution

Les éléments seront passés comme arguments. Par exemple, l'exemple fourni ci-dessus serait passé à un programme appelé powersetcomme:

powerset 1 2 3

Les arguments seront alphanumériques.

Règles

  1. Pas de bibliothèques à part io
  2. La sortie n'a pas besoin d'être commandée
  3. Le PowerSet ne doit pas être stocké, seulement imprimé
  4. Les éléments de l'ensemble doivent être délimités (par exemple 1,2,3, [1,2,3]et ['1','2','3']sont acceptables, mais 123ne sont pas
    • Les délimiteurs de fin sont corrects (par exemple 1,2,3, == 1,2,3)
  5. Le meilleur est déterminé en fonction du nombre d'octets

La meilleure solution sera décidée au moins 10 jours après la première soumission.

beatgammit
la source
Étroitement lié à codegolf.stackexchange.com/questions/6380
Peter Taylor
2
Si seulement ce défi était mis à jour pour autoriser les valeurs par défaut, comme le retour et les fonctions. Python serait 54 octets: lambda L:reduce(lambda r,x:r+[s+[x]for s in r],L,[[]]).
mbomb007
Je ne suis pas d'accord uniquement en impression ... Pourquoi ne pas permettre d'avoir les données, la variable aussi ... Que pourquoi imprimer en colonne et pas en ligne?
RosLuP

Réponses:

15

Mathematica 16

Code

Subsets est originaire de Mathematica.

Column@Subsets@s

Le code (sans colonne) peut être vérifié sur WolframAlpha . (J'ai dû utiliser des crochets au lieu de @; ils signifient la même chose.

Usage

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

output


Cette méthode (55 caractères) utilise l'approche suggérée par @ w0lf.

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

Panne

Générer les tuples, composés de 0et 1de longueurLength[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}}

Multipliez la liste d'origine (vecteur) par chaque tuple:

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

Supprimez les 0. %est un raccourci pour "la sortie précédente".

% /. {0:> séquence []}

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

Afficher dans la colonne:

Mathematica graphics

DavidC
la source
@tjameson J'avais de sérieux doutes quant à savoir si je devais le publier, mais j'ai pensé que certaines personnes pourraient trouver intéressant de savoir qu'il est intégré.
DavidC
Je trouve ça intéressant :)
Dr belisarius
Pouvez-vous laisser le set mettre l'entrée à la fin de la ligne?
Solomon Ucko
15 octets: Subsets/*Columncrée une fonction anonyme qui prend une liste et renvoie l'affichage en colonnes.
Roman
9

C, 118 115

Bien que vous puissiez enregistrer environ 20 caractères avec un formatage plus simple, vous ne gagnerez toujours pas en termes 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;
}

Essai:

/a.out 1 2 3
[]
[1]
[2]
[1,2]
[3]
[1,3]
[2,3]
[1,2,3]
bébé-lapin
la source
Agréable. Quelques conseils: le style K&R ( main(a,s)char**s;{...}), f|=x&1<<i&&printfest plus court que ?:.
ugoren
Je viens de comprendre ce qui se cache x+=2(et où est s[0]allé). Truc vraiment sympa.
ugoren
Refusant de jouer au golf, votre réponse, car elle "ne va toujours pas gagner en termes de golf de code de toute façon". ne répond pas sérieusement aux critères gagnants du défi.
pppery
7

GolfScript, 22 18 caractères

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

Une autre tentative dans GolfScript avec un algorithme complètement différent. Le format d'entrée est le même qu'avec la réponse de w0lf. ( test en ligne )

Howard
la source
+1 Excellente solution! La mienne est refactorisée pour plus de lisibilité :-P
Cristian Lupascu
5

GolfScript (43 caractères)

Cela peut sembler assez long, mais c'est la première solution à suivre la spécification: l'entrée provient d'arguments de ligne de commande et la sortie est délimitée par des sauts de ligne.

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

Par exemple

$ golfscript.rb powset.gs 1 2 3
["1"]
["2"]
["2" "1"]
["3"]
["3" "2"]
["3" "1"]
["3" "2" "1"]
[]
Peter Taylor
la source
Les citations ne sont pas nécessaires, si cela fait une différence.
beatgammit
@tjameson, les citations proviennent de l'utilisation de la manière la plus courte possible d'imprimer. Le fait que ces valeurs soient des chaînes plutôt que des entiers vient de l'incapacité de GolfScript d'accéder directement aux arguments de la ligne de commande: il doit compter sur l'interpréteur effectuant une évaluation dans Ruby et mettant le résultat dans une chaîne.
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 ""}}

supposons enregistré dans le fichier powerset.awk, utilisation

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

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

ps si votre awk n'a pas la fonction and (), remplacez-la par int(i/(2^j))%2mais ajoutez deux au nombre.

karakfa
la source
(2^j)-> 2^jvous enregistre 2 octets; le .awkfichier fonctionne également sans fin \n, vous pouvez donc raser un autre octet.
mklement0
3

JavaScript, 98

Malheureusement, une bonne partie est dépensée pour le formatage de sortie.

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

Contribution

Prend un tableau JavaScript. (par exemple [1,2,3])

Sortie

[]
1
1,2
2
2,3
1,2,3
1,3
3
Paul Walls
la source
3

Python ( 74 70 caractères)

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

pour l'entrée en tant que 1,2,3ou [1,2,3], la sortie est:

[]
[3]
[2]
[2, 3]
[1]
[1, 3]
[1, 2]
[1, 2, 3]
AMK
la source
[a[0]]=a[:1]
ugoren
avec entrée 1,2,3 a[:1]ne fonctionne pas. tuple + liste non autorisé. Existe une meilleure solution
AMK
+1 pouri,*a=a
primo
N'est-ce pas i,*a=aPython 3? Cela ne fonctionne pas sur mon 2.7.1.
ugoren
Ni sur 2.7.2. Cela pourrait expliquer pourquoi je n'ai jamais vu cette astuce avant ... la plupart des serveurs de golf de code exécutent 2.7.x.
primo
3

Python 70 67 octets

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

L'entrée est prise de la même manière que pour la solution d' Ugoren . Exemple d'E / S:

$ echo [1,2,3] | powerset.py
()
(1,)
(2, 1)
(3, 2, 1)
(3, 1)
(2,)
(3, 2)
(3,)
primo
la source
1
Vous pouvez en sauvegarder avec def p(a,*v)puis p(a[i:],n,*v). La sortie devient un peu plus laide, mais reste OK.
ugoren
Très intelligent, merci pour la pointe.
primo
3

J, 19 caractères

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

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

La boxe ascii dans la sortie est appelée boxinget fournit une collection hétérogène (pour différentes longueurs de tableaux ici).

randomra
la source
2

Golfscript 48

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

Ce programme utilise les représentations binaires de nombres de 0 à la longueur (entrée) pour générer des éléments d'ensemble de puissance.

Contribution

Le format d'entrée est le format de tableau Golfscript (exemple: [1 2 3] )

Sortie

La sortie est une collection de tableaux séparés par des retours à la ligne, représentant l'ensemble de puissance. Exemple:

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

Test en ligne

Le programme peut être testé en ligne ici .

Cristian Lupascu
la source
Génial, mais pourriez-vous délimiter avec des nouvelles lignes?
beatgammit
@tjameson J'ai réussi à sortir délimité par des retours à la ligne tout en conservant le même nombre de caractères. Veuillez consulter la mise à jour de ma réponse.
Cristian Lupascu
2

Haskell (96)

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

Si l'importation Control.Monadn'est pas autorisée, cela devient 100 caractères:

importer System.Environment
main = getArgs >> = mapM print.p
pz = cas z de {[] -> [[]]; x: y-> p y ++ map (x:) (py)}
Fée lambda
la source
2

Mathematica 53

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

enter image description here

chyanog
la source
2

APL (26)

Lit l'entrée du clavier car il n'y a pas d' argvéquivalent.

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

Usage:

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

Explication:

  • T←⎕: lire l'entrée, stocker dans T
  • M←⍴T: Longueur du magasin de TdansM
  • (M/2)⊤⍳2*M: générer les modèles de bits pour 1jusqu'à 2^Mutiliser des Mbits.
  • ↓⍉: divise la matrice de sorte que chaque motif binaire soit séparé
  • (/∘T)¨: pour chaque motif binaire, sélectionnez ces sous-éléments dans T.
  • ↑⍕¨: pour la sortie, obtenez la représentation sous forme de chaîne de chaque élément (pour qu'il se remplisse en utilisant des blancs et non des zéros), et formatez-le comme une matrice (pour que chaque élément soit sur sa propre ligne).
marinus
la source
2

Scala, 81

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

JavaScript ( ES6 ) 76

Copié partiellement à partir de celui-ci: /codegolf//a/51502/21348

En utilisant un bitmap, il est donc limité à pas plus de 32 éléments.

Exécutez l'extrait dans Firefox pour tester.

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
la source
2

C # 164

Mec c'est dur 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
la source
2

Python 2, 64 octets

Utilisation d'une entrée séparée par des virgules:

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

Pyth, 4 octets (en utilisant la fonction intégrée) ou 14 octets (sans)

Comme indiqué par @Jakube dans les commentaires, Pyth est trop récent pour cette question. Voici encore une solution utilisant l'opérateur de jeu de puissance intégré de Pyth:

jbyQ

Et en voici un sans ça:

jbu+Gm+d]HGQ]Y

Vous pouvez essayer les deux solutions ici et ici . Voici une explication de la deuxième solution:

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
la source
2

brainfuck, 94 octets

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

Formaté:

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

Attend l'entrée du formulaire 9,10,11sans retour à la ligne de fin et affiche des sous-ensembles dans le même format, parfois avec une virgule de fin. La première ligne imprimée sera toujours vide, signifiant l'ensemble vide.

Essayez-le en ligne.

L'idée de base est de placer un peu à côté de chaque élément, puis d'incrémenter à plusieurs reprises le nombre binaire tout en imprimant le sous-ensemble correspondant avant chaque incrément. (Un bit indique si un élément est dans le sous-ensemble.) Un bit sentinelle à gauche du tableau est utilisé pour terminer le programme. Cette version crée en fait un nombre exponentiel de sentinelles pour économiser quelques octets; une solution de 99 octets plus efficace qui n'utilise qu'une seule sentinelle peut être trouvée dans l'historique des révisions.

Chaque bit est codé comme un plus sa valeur; c'est-à-dire qu'il peut être soit 1ou 2. La bande est disposée avec le bit avant chaque élément et une seule cellule zéro entre les éléments adjacents. La virgule est incluse sur la bande pour les éléments non finaux, nous pouvons donc simplement imprimer les éléments sans faire de travail supplémentaire pour gérer les délimiteurs.

Mitch Schwartz
la source
2

APL (Dyalog Classic) , 13 octets

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

Essayez-le en ligne!

Sortie:

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

Il y a une ligne vierge à la fin pour représenter l'ensemble vide.

Explication:

entrée évaluée

⎕,¨⊂⊂⍬ ajouter une liste numérique vide après chaque élément

∘., produit cartésien

/ réduction (foldr)

divulguer (nécessaire après réduction de l'APL)

À ce stade, le résultat est un tableau n-dimensionnel 2 par -...- par-2, où n est la longueur de l'entrée.

, aplatir en vecteur

transformer le vecteur en une matrice verticale de 2 n -par-1, de sorte que chaque sous-ensemble se trouve sur une ligne distincte

ngn
la source
2

Haskell , 80 78 octets

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

Essayez-le en ligne!

Angs
la source
Les exigences d'E / S sont horribles, mais les gens les interprètent de manière assez vague. Si vous passez à la saisie via stdin, vous pourriez économiser 15 octets, voyez ceci .
2018 à 12h59
1

Python, 93 87 caractères

Python simplifie le formatage, car l'entrée / sortie requise correspond à son format natif.
Ne prend en charge que les éléments qui sont des littéraux Python (par exemple 1,2,'hello', pas 1,2,hello).
Lit l'entrée standard, pas les paramètres.

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
la source
print f(input())plus court
AMK
@AMK, l'exigence est que chaque élément soit imprimé sur une seule ligne. Mais listpeut en effet être supprimé (s'il est également remplacé [[]]par [()].
ugoren
print'\n'.join(f(input())) saves two characters
beary605
@beary605, doesn't work, f() contains tuples, not strings.
ugoren
1

Ruby, 39

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

Haskell 89 chars

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

Getting parameters is long :/

kyticka
la source
one more char can be shaved off with map(x:)(p y)++p y and yet two more chars above that with [(x:),id]<*>p y. Apparently <*> is in the Prelude now. (filterM isn't).
Will Ness
1

R, 63

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

Here, v represents a vector.

Usage:

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
la source
1

K, 14 bytes

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

Generate all 0/1 vectors as long as the input, gather the indices of 1s and use those to select elements from the input vector. In practice:

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

C'est un peu libéral avec les exigences de sortie, mais je pense que c'est légal. La partie la plus discutable est que l'ensemble vide sera représenté sous une forme dépendante du type; !0est la façon dont K désigne un vecteur numérique vide:

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

Explication

Le (#x)#2construit un vecteur 2aussi long que l'entrée:

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

Quand monadique !est appliqué à un vecteur, c'est "odomètre":

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

Ensuite, nous utilisons "where" ( &) sur chaque 'vecteur ( ) pour rassembler ses indices. Le côlon est nécessaire pour lever l'ambiguïté entre la forme monadique et dyadique 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 nous voulions simplement des vecteurs de combinaison, nous aurions terminé, mais nous devons les utiliser comme indices dans l'ensemble d'origine. Heureusement, l'opérateur d'indexation de K @peut accepter une structure complexe d'indices et produira un résultat avec la même forme:

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

Élégant, non?

JohnE
la source
1
Ce n'est plus valable, car "odomètre" en oK génère désormais une matrice inversée. Il peut être corrigé au coût d'un seul octet: {x@&:'+!(#x)#2}. Sans rapport: un équivalent plus court de (#x)#2is 2|~x.
ngn
1

Mathematica, 51

Plus de tricherie:

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

À utiliser avec @{1,2,3}.

LogicBreaker
la source
Your code should take the set as input, not just hardcode it. Also, since this is code golf, you should include the byte count of the code (and probably remove the unnecessary spaces).
Martin Ender
Since this contest is long over, the post was more for the idea, but I've edited it.
LogicBreaker
1

JavaScript (ES6), 68 bytes

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

Demo

Arnauld
la source
Why the 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}}
beginnerProg
la source