Найкоротша реалізація набору потужності


22

Визначення проблеми

Роздрукуйте живлення даного набору. Наприклад:

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

Кожен елемент повинен бути надрукований на окремому рядку, тому приклад, що наведено вище, буде надрукований як:

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

Приклад коду (в D, приклад python тут ):

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

Вхідні дані

Елементи будуть передані як аргументи. Наприклад, наведений вище приклад буде переданий програмі під назвоюpowerset назвою:

powerset 1 2 3

Аргументи будуть буквено-цифровими.

Правила

  1. Жодної бібліотеки, крім іо
  2. Вихідні дані не потрібно замовляти
  3. Powerset не потрібно зберігати, а лише друкувати
  4. Елементи в наборі повинні бути обмежені (наприклад 1,2,3, [1,2,3]і ['1','2','3']є прийнятними, але123 ні
    • Трейлінг-роздільники прекрасні (наприклад 1,2,3, == 1,2,3)
  5. Кращий визначається на основі кількості байтів

Найкраще рішення буде прийнято не менше ніж через 10 днів після першого подання.




2
Якби тільки це завдання було оновлено, щоб дозволити значення за замовчуванням, як повернення та функції. Python буде 54 байт: lambda L:reduce(lambda r,x:r+[s+[x]for s in r],L,[[]]).
mbomb007

Я не згоден лише в друку ... Чому б не дозволити мати дані, змінну теж .. Чому для того, щоб друкувати в стовпці, а не в рядку?
RosLuP

Відповіді:


15

Математика 16

Код

Subsets є рідним для Mathematica.

Column@Subsets@s

Код (без стовпця) можна перевірити на WolframAlpha . (Мені довелося використовувати дужки замість @; вони означають те саме.

Використання

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

output


Цей метод (55 символів) використовує підхід, запропонований @ w0lf.

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

Зламатися

Створіть кортежі, складені з довжини 0і 1'sLength[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}}

Помножте початковий список (вектор) на кожен кортеж:

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.%є скороченням для "попереднього виходу".

% /. {0:> Послідовність []}

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

Відображення в стовпці:

Mathematica graphics


@tjameson У мене були серйозні сумніви щодо того, чи варто це публікувати, але я подумав, що деяким людям може бути цікаво знати, що він вбудований.
DavidC

Мені це цікаво :)
Доктор belisarius

Чи можете ви відмовитися від sі поставити вхід у кінці рядка?
Соломон Учко

15 байт: Subsets/*Columnробить анонімну функцію, яка бере список і повертає відображення у стовпцях.
Роман

9

С, 118 115

Хоча ви можете заощадити приблизно 20 символів при більш простому форматуванні, але все одно не вигравати в кодовому вигляді гольфу в будь-якому випадку.

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

Тестування:

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

Приємно. Деякі поради: стиль K&R ( main(a,s)char**s;{...}) f|=x&1<<i&&printfкоротший, ніж ?:.
угорен

Просто з’ясував, що позаду x+=2(і куди s[0]пішов). Дійсно приємний трюк.
угорен

Відмовляючись від гольфу у своїй відповіді, оскільки "все одно не виграти в кодовому вигляді гольфу в будь-якому випадку". робить відповідь несерйозним претендентом на виграшні критерії виклику.
pppery

7

GolfScript, 22 18 символів

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

Ще одна спроба у GolfScript із зовсім іншим алгоритмом. Формат введення такий же, як і у відповіді w0lf. ( онлайн-тест )


+1 Відмінне рішення! Шахта реконструюється для читабельності :-P
Крістіан Лупаску

5

GolfScript (43 символи)

Це може здатися досить довгим, але це перше рішення, яке слід виконати за специфікацією: введення - з аргументів командного рядка, а вихід - з обмеженим рядком.

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

Напр

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

Котирування не потрібні, якщо це має значення.
beatgammit

@tjameson, цитати походять з використання найкоротшого можливого способу друку. Той факт, що ці значення є рядками, а не цілими числами, виникає з-за неможливості GolfScript отримати прямий доступ до аргументів командного рядка: він повинен покладатися на те, що інтерпретатор виконує оцінку в Ruby і вводить результат у рядок.
Пітер Тейлор

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, використання

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

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

ps, якщо у вашого awk немає та () функції, замініть його, int(i/(2^j))%2але додайте два до рахунку.


(2^j)-> 2^jекономить 2 байти; .awkфайл також працює без завершального \n, так що ви могли б збрити інші байти.
mklement0

3

JavaScript, 98

На жаль, хороший шматок витрачається на форматування вихідних даних.

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

Вхідні дані

Займає масив JavaScript. (наприклад, [1,2,3])

Вихідні дані

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

3

Пітон ( 74 70 символів)

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

для введення як 1,2,3або [1,2,3], вихід:

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

[a[0]]=a[:1]
угорен

з введенням 1,2,3 a[:1]не працює. кортеж + список не дозволений Є найкраще рішення
AMK

+1 заi,*a=a
прим

Чи не i,*a=aPython 3? Не працює на моєму 2.7.1.
угорен

Ні на 2.7.2. Це може пояснити, чому я ніколи не бачив цього трюку раніше ... більшість серверів з кодом для гольфу працюють 2.7.x.
прим

3

Python 70 67 байт

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

Введення приймається таким же чином, як і для розчину ugoren . Зразок вводу / виводу:

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

1
Ви можете зберегти деякі з, def p(a,*v)а потім p(a[i:],n,*v). Вихід стає дещо потворнішим, але все одно гаразд.
угорен

Дуже розумно, дякую за пораду.
прим

3

J, 19 символів

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

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

Бокс Ascii на виході називається boxingі забезпечує збір гетерогену (для різної довжини масивів тут).


2

Гольфскрипт 48

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

Ця програма використовує двійкові представлення чисел від 0 до довжини (вхідних даних) для генерування елементів живлення.

Вхідні дані

Формат введення - це формат масиву Golfscript (приклад: [1 2 3] )

Вихідні дані

Вихід - це сукупність масивів, розділених новими рядками, що представляють набір потужності. Приклад:

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

Інтернет-тест

Програму можна перевірити онлайн тут .


Дивовижно, але ви могли б розмежуватись з новими рядками?
beatgammit

@tjameson Мені вдалося вивести обмежені новими рядками, зберігаючи однаковий кількість символів. Будь ласка, дивіться оновлення моєї відповіді.
Крістіан Лупаску

2

Хаскелл (96)

імпорт Control.Monad
Система імпорту. Навколишнє середовище
main = getArgs >> = mapM print.filterM (\ _-> [False ..])

Якщо імпорт Control.Monadзаборонено, це стає 100 символів:

Система імпорту. Навколишнє середовище
main = getArgs >> = mapM print.p
pz = випадок z {[] -> [[]]; x: y-> p y ++ карта (x:) (py)}


2

APL (26)

Читає дані з клавіатури, тому що немає argvеквівалента.

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

Використання:

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

Пояснення:

  • T←⎕: читати вхід, зберігати в T
  • M←⍴T: довжина магазину TвM
  • (M/2)⊤⍳2*M: генерувати бітові шаблони для 1upto 2^Mза допомогою Mбітів.
  • ↓⍉: розділіть матрицю так, щоб кожен бітовий шаблон був окремим
  • (/∘T)¨: для кожного бітового шаблону виберіть ці підпункти з T.
  • ↑⍕¨: для виводу отримайте рядкове подання кожного елемента (так що він заповнюватиметься пробілами, а не нулями) та відформатувати як матрицю (так, щоб кожен елемент знаходився у власному рядку).

2

Скала, 81

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

2

JavaScript ( ES6 ) 76

Частково скопійовано з цього: /codegolf//a/51502/21348

Використовуючи растрову карту, вона обмежується не більше 32 елементами.

Запустіть фрагмент у Firefox для тестування.

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

Людина це важко в 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 bytes

Використовуючи розділений комою вхід:

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

Pyth, 4 байти (використовуючи вбудований) або 14 байт (без)

Як зазначив @Jakube в коментарях, Pyth є занадто останнім для цього питання. Ще є рішення з використанням вбудованого оператора набору потужностей Pyth:

jbyQ

І ось один без цього:

jbu+Gm+d]HGQ]Y

Ви можете спробувати обидва рішення тут і тут . Ось пояснення другого рішення:

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

2

мозковий ебать, 94 байти

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

Відформатовано:

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

Очікує введення форми 9,10,11 без закінчення нового рядка та виводить підмножини у тому самому форматі, іноді із комою. Перший рядок, надрукований завжди буде порожнім, означає порожній набір.

Спробуйте в Інтернеті.

Основна ідея полягає в тому, щоб розмістити трохи поруч з кожним елементом, а потім повторно збільшувати двійкове число під час друку відповідного підмножини перед кожним збільшенням. (Біт вказує, чи є елемент у підмножині.) Біт дозорного зліва від масиву використовується для завершення програми. Ця версія фактично створює експоненціальну кількість дозорних, щоб зберегти деякі байти; в історії версій можна знайти більш ефективне 99-байтове рішення, яке використовує лише один дозорний.

Each bit is encoded as one plus its value; i.e., it can be either 1 or 2. The tape is laid out with the bit before each element and a single zero cell between adjacent elements. The comma is included on the tape for non-final elements, so we can conveniently just print elements without doing any extra work to handle delimiters.


2

APL (Dyalog Classic), 13 bytes

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

Try it online!

Output:

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

There's a blank line at the end to represent the empty set.

Explanation:

evaluated input

⎕,¨⊂⊂⍬ append an empty numeric list after each element

∘., Cartesian product

/ reduction (foldr)

disclose (necessary after reduction in APL)

At this point the result is an n-dimensional 2-by-...-by-2 array, where n is the length of the input.

, flatten into a vector

turn the vector into an upright 2n-by-1 matrix, so each subset is on a separate line


2

Haskell, 80 78 bytes

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

Try it online!


The I/O requirements are horrible, however people are interpreting them quite loosely. If you change to taking input via stdin you could save 15 bytes, see this.
ბიმო


1

Python, 93 87 chars

Python makes formatting simple, because the required input/output matches its native format.
Only supports items which are Python literals (e.g. 1,2,'hello', not 1,2,hello).
Reads standard input, not parameters.

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()) shorter
AMK

@AMK, the requirement is for each element to be printed in one line. But list can indeed be removed (if also replacinf [[]] with [()].
ugoren

print'\n'.join(f(input())) saves two characters
beary605

@beary605, doesn't work, f() contains tuples, not strings.
ugoren


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 :/


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)

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)

This is a bit liberal with the output requirements, but I think it's legal. The most questionable part is that the empty set will be represented in a type dependent form; !0 is how K denotes an empty numeric vector:

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

Explanation

The (#x)#2 builds a vector of 2 as long as the input:

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

When monadic ! is applied to a vector, it is "odometer":

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

Then we use "where" (&) on each (') vector to gather its indices. The colon is necessary to disambiguate between the monadic and dyadic form of &:

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

If we just wanted combination vectors, we'd be done, but we need to use these as indices into the original set. Fortunately, K's indexing operator @ can accept a complex structure of indices and will produce a result with the same shape:

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

Elegant, no?


1
This is no longer valid, as "odometer" in oK now generates a flipped matrix. It can be corrected at the cost of a single byte: {x@&:'+!(#x)#2}. Unrelated: a shorter equivalent of (#x)#2 is 2|~x.
ngn

1

Mathematica, 51

More cheating:

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

Use with @{1,2,3}.


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


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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.