Реализация кратчайшего блока питания


22

Определение проблемы

Распечатайте powerset данного набора. Например:

[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. Нет библиотек, кроме IO
  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

Я не согласен только в печати ... Почему бы не разрешить иметь данные, переменную тоже .. Чем печатать в столбце, а не в строке?
Рослуп

Ответы:


15

Mathematica 16

Код

Subsets родом из Mathematica.

Column@Subsets@s

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

использование

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

выход


Этот метод (55 символов) использует подход, предложенный @ w0lf.

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

Сломать

Генерация кортежей, состоящих из 0и 1длиныLength[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}}

Показать в столбце:

Математическая графика


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

Я нахожу это интересным :)
Доктор Велизарий

Можете ли вы отключить 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 не имеет функции and (), замените его на, 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())

Ввод принимается так же, как и для решения Угорена . Пример ввода / вывода:

$ 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

Golfscript 48

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

Эта программа использует двоичные представления чисел от 0 до длины (входные) для генерации элементов powerset.

вход

Входной формат является Golfscript формат массива (пример: [1 2 3])

Выход

Вывод представляет собой набор массивов, разделенных символами новой строки, представляющих набор мощности. Пример:

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

Онлайн тест

Программу можно протестировать онлайн здесь .


Круто, но не могли бы вы разграничить символом новой строки?
beatgammit

@tjameson Мне удалось вывести разделенные символами новой строки, сохранив то же количество символов. Пожалуйста, смотрите обновление к моему ответу.
Кристиан Лупаску

2

Хаскелл (96)

импорт Control.Monad
импорт System.Environment
main = getArgs >> = mapM print.filterM (\ _-> [False ..])

Если импорт Control.Monadне разрешен, это становится 100 символами:

импорт System.Environment
main = getArgs >> = mapM print.p
pz = case z of {[] -> [[]]; x: y-> p y ++ map (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: Генерировать битовые шаблоны для 1ДО , 2^Mиспользуя Mбиты.
  • ↓⍉: разделить матрицу так, чтобы каждая битовая комбинация была отдельной
  • (/∘T)¨: для каждого шаблона битов выберите эти подпункты из T.
  • ↑⍕¨: для вывода получите строковое представление каждого элемента (чтобы он заполнялся с использованием пробелов, а не нулей) и отформатировали в виде матрицы (чтобы каждый элемент находился на отдельной строке).


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 байта

Использование ввода через запятую:

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-байтовое решение, в котором используется только один страж, можно найти в истории изменений.

Каждый бит кодируется как один плюс его значение; то есть, это может быть 1или 2. Лента размещается с битом перед каждым элементом и одной нулевой ячейкой между соседними элементами. Запятая включена в ленту для не конечных элементов, поэтому мы можем просто печатать элементы, не выполняя никакой дополнительной работы с разделителями.


2

APL (Dyalog Classic) , 13 байтов

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

Попробуйте онлайн!

Выход:

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

В конце есть пустая строка, представляющая пустой набор.

Объяснение:

оцененный вклад

⎕,¨⊂⊂⍬ добавить пустой числовой список после каждого элемента

∘., Декартово произведение

/ уменьшение (сгиб)

раскрыть (необходимо после снижения APL)

На этом этапе результат представляет собой n-мерный массив размером 2 на -...- на-2, где n - длина входных данных.

, сплющить в вектор

превратить вектор в прямую 2 n- by-1 матрицу, чтобы каждое подмножество находилось на отдельной строке




1

Питон, 93 87 символов

Python упрощает форматирование, поскольку требуемый ввод / вывод соответствует его собственному формату.
Поддерживает только те элементы, которые являются литералами Python (например 1,2,'hello', нет 1,2,hello).
Читает стандартный ввод, а не параметры.

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())короче
AMK

@AMK, требуется, чтобы каждый элемент был напечатан в одну строку. Но listдействительно может быть удален (если также заменить [[]]на [()].
Угорен

print'\n'.join(f(input()))сохраняет двух персонажей
beary605

@ beary605, не работает, f()содержит кортежи, а не строки.
Угорен


1

Haskell 89 символов

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

Получение параметров долго: /


еще один символ можно сбрить, map(x:)(p y)++p yа еще два - выше [(x:),id]<*>p y. Видимо <*>сейчас в прелюдии . ( filterMнет).
Уилл Несс

1

R, 63

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

Здесь vпредставляет вектор.

Использование :

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

К, 14 байтов

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

Сгенерируйте все 0/1 векторов за время ввода, соберите индексы 1 с и используйте их для выбора элементов из входного вектора. На практике:

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

Это немного либерально с требованиями к выходу, но я думаю, что это законно. Наиболее сомнительной является то, что пустой набор будет представлен в виде, зависящем от типа; !0как K обозначает пустой числовой вектор:

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

объяснение

(#x)#2Строит вектор 2тех пор , пока на входе:

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

Когда !к вектору применяется монадика, это «одометр»:

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

Затем мы используем «где» ( &) для каждого 'вектора ( ), чтобы собрать его индексы. Толстая кишка необходима для устранения неоднозначности между монадической и диадической формой &:

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

Если бы мы просто хотели комбинированные векторы, мы бы сделали, но нам нужно использовать их как индексы в исходном наборе. К счастью, оператор индексации K @может принять сложную структуру индексов и даст результат такой же формы:

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

Элегантно, нет?


1
Это больше не действует, так как «одометр» в ОК теперь генерирует перевернутую матрицу. Это может быть исправлено за счет одного байта: {x@&:'+!(#x)#2}. Несвязанный: более короткий эквивалент (#x)#2IS 2|~x.
августа

1

Математика, 51

Больше обмана:

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

Используйте с @{1,2,3}.


Ваш код должен принимать набор в качестве входных данных, а не просто жестко его кодировать. Кроме того, так как это кодовый гольф, вы должны включить количество байтов кода (и, возможно, удалить ненужные пробелы).
Мартин Эндер

Так как этот конкурс давно закончился, пост был больше для идеи, но я отредактировал его.
LogicBreaker

1

JavaScript (ES6), 68 байт

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

демонстрация


Почему то alert?
Лохматый

@Shaggy Задача явно требует печатать каждый элемент в отдельной строке - что, вероятно, будет противоречить нашим текущим стандартам. Большинство ответов, кажется, придерживаются этого правила.
Арнаулд

Ах, достаточно справедливо; Я интерпретировал «печать» как «вывод».
Лохматый


0

Комбинация методов Ruby Array (от 1.9) [50 символов]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.