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


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.