최단 전력 세트 구현


22

문제 정의

주어진 세트의 전원 세트를 인쇄하십시오. 예를 들면 다음과 같습니다.

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

각 요소는 별도의 줄에 인쇄되므로 위의 예는 다음과 같이 인쇄됩니다.

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

예제 코드 (D에서 파이썬 예제는 여기 ) :

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. 전원을 저장할 필요가없고 인쇄 만 가능
  4. 세트의 요소는 예를 들어 (구분해야 1,2,3, [1,2,3]['1','2','3']허용하지만 123아니다
    • 후행 구분 기호가 정상입니다 (예를 들어 1,2,3, == 1,2,3)
  5. 최고 는 바이트 수에 따라 결정됩니다.

최상의 솔루션은 첫 번째 제출 후 10 일 이내에 결정됩니다.




2
이 도전 과제 만 반환 및 기능과 같은 기본값을 허용하도록 업데이트 된 경우. 파이썬은 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

고장

01길이 로 구성된 튜플 생성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}}

열에 표시 :

Mathematica graphics


@ tjameson 나는 그것을 게시 해야하는지에 대해 심각하게 의심했지만 일부 사람들은 그것이 내장되어 있다는 것을 알고 흥미로울 것이라고 생각했습니다.
DavidC

흥미로운
점이 있습니다

줄을 s끝내고 줄 끝에 입력을 넣을 수 있습니까 ?
솔로몬 Ucko

15 바이트 : Subsets/*Column목록을 가져 와서 열로 표시를 리턴하는 익명 함수를 작성합니다.
로마

9

C, 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에서 eval을 수행하고 결과를 문자열에 넣는 인터프리터에 의존해야합니다.
피터 테일러

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를 더합니다.


(2^j)-> 2^j2 바이트를 절약합니다. .awk파일은 후행없이 작동 \n다른 바이트를 면도 할 수 있도록.
mklement0

3

자바 스크립트, 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'))

입력

자바 스크립트 배열을받습니다. (예 : [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

i,*a=a
primo에

아닌가 i,*a=a파이썬 3? 내 2.7.1에서는 작동하지 않습니다.
ugoren

2.7.2도 마찬가지입니다. 그것은 내가 왜 그 트릭을 본 적이 없는지 설명 할 수 있습니다 ... 대부분의 코드 골프 서버는 2.7.x를 실행합니다.
primo

3

파이썬 70 67 바이트

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

입력은 ugoren의 솔루션 과 동일한 방식으로 수행됩니다 . 샘플 I / O :

$ 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). 출력이 다소 추악하지만 여전히 정상입니다.
ugoren

매우 영리합니다. 팁 주셔서 감사합니다.
primo

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)

Import Control.Monad
수입 System.Environment
main = getArgs >> = mapM print.filterM (\ _-> [거짓 ..])

가져 오기 Control.Monad가 허용되지 않으면 100자가 됩니다.

수입 System.Environment
main = getArgs >> = mapM print.p
pz = case z of {[]-> [[]]; x : y-> p y ++ map (x :) (py)}

2

매스 매 티카 53

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

enter image description here


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:의 저장 길이 TM
  • (M/2)⊤⍳2*M: 대한 비트 패턴을 생성 1개까지 2^M사용하여 M비트.
  • ↓⍉: 각 비트 패턴이 분리되도록 행렬을 분할
  • (/∘T)¨: 각 비트 패턴에 대해에서 해당 하위 항목을 선택하십시오 T.
  • ↑⍕¨: 출력을 위해 각 요소의 문자열 표현을 가져 와서 (0이 아닌 공백을 사용하여 채움) 매트릭스로 형식화하십시오 (각 요소가 자체 행에 있음).

2

스칼라, 81

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

2

자바 스크립트 ( 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

파이썬 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

brainfuck, 94 바이트

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

형식화 :

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

9,10,11후행 줄 바꿈없이 양식 을 입력 하고 후행 쉼표와 함께 동일한 형식의 서브 세트를 출력합니다. 인쇄 된 첫 번째 줄은 항상 비어 있으며 빈 세트를 나타냅니다.

온라인으로 사용해보십시오.

기본 아이디어는 각 요소 옆에 비트를 배치 한 다음 각 증분 전에 해당하는 하위 세트를 인쇄하면서 이진수를 반복적으로 증가시키는 것입니다. 비트는 요소가 서브 세트에 있는지 여부를 나타냅니다. 배열 왼쪽의 센티넬 비트는 프로그램을 종료하는 데 사용됩니다. 이 버전은 실제로 몇 바이트를 절약하기 위해 지수의 센티넬을 생성합니다. 하나의 센티넬 만 사용하는보다 효율적인 99 바이트 솔루션은 개정 히스토리에서 찾을 수 있습니다.

각 비트는 1에 그 값을 더한 값으로 인코딩됩니다. 즉, 1또는 일 수 있습니다 2. 테이프는 각 요소 앞의 비트와 인접한 요소 사이의 단일 제로 셀로 배치됩니다. 최종 요소가 아닌 요소의 경우 쉼표가 테이프에 포함되어 있으므로 구분자를 처리하기 위해 추가 작업을 수행하지 않고도 요소를 편리하게 인쇄 할 수 있습니다.


2

APL (Dyalog Classic) , 13 바이트

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

온라인으로 사용해보십시오!

산출:

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

빈 세트를 나타내는 빈 줄이 끝에 있습니다.

설명:

평가 된 입력

⎕,¨⊂⊂⍬ 각 요소 뒤에 빈 숫자 목록을 추가하십시오.

∘., 카티 전 곱

/ 축소 (폴더)

공개 (APL 축소 후 필요)

이 시점에서 결과는 n 차원 2x ... x2 배열이며, 여기서 n은 입력 길이입니다.

, 벡터로 평평하게하다

2 직립으로 벡터를 반전 N 서브 세트 각각은 별도의 행에 있도록 그래밍 1 행렬


2

하스켈 , 80 78 바이트

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

온라인으로 사용해보십시오!


I / O 요구 사항은 끔찍하지만 사람들은 그것들을 상당히 느슨하게 해석하고 있습니다. 당신이를 통해 입력을 복용 변경하는 경우 stdin을 사용하면 15 바이트를 절약 할 수있다, 이 참조 .
ბიმო


1

파이썬, 93 87 자

파이썬은 필요한 입력 / 출력이 기본 형식과 일치하기 때문에 형식을 간단하게 만듭니다.
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또한 replacinf 경우 참 (제거 할 수 있습니다 [[]][()].
ugoren

print'\n'.join(f(input()))2 개의 문자를 저장합니다
beary605

@ beary605는 작동하지 f()않으며 문자열이 아닌 튜플을 포함합니다.
우고 렌


1

하스켈 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. 분명히 <*>Prelude에 있습니다. ( filterM그렇지 않습니다).
Will Ness

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

K, 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)

이것은 출력 요구 사항에 약간 자유롭지 만 합법적이라고 생각합니다. 가장 의심스러운 부분은 빈 세트가 유형 의존적 형식으로 표시된다는 것입니다. !0K가 빈 숫자 형 벡터를 나타내는 방법입니다.

  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

수도원 일 때 ! 이 벡터에 적용 "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)

그런 다음 &각 위치에 "where"( )를 사용합니다 (' ) 벡터 하여 색인을 수집합니다. 콜론은 monadic과 dyadic 형식을 명확하게하기 위해 필요합니다 &.

  &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
oK의 "odometer"는 이제 뒤집힌 행렬을 생성하므로 더 이상 유효하지 않습니다. 단일 바이트 비용으로 수정할 수 있습니다 {x@&:'+!(#x)#2}. 관련이 없음 : 더 짧은 것은 (#x)#2is 2|~x입니다.
ngn

1

매스 매 티카, 51

더 많은 부정 행위 :

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

와 함께 사용하십시오 @{1,2,3}.


코드는 하드 코딩뿐만 아니라 입력을 세트로 가져와야합니다. 또한 이것은 코드 골프이기 때문에 코드의 바이트 수를 포함해야합니다 (그리고 불필요한 공간을 제거해야합니다).
Martin Ender 2016 년

이 콘테스트는 오래 걸리기 때문에 게시물에 대한 아이디어가 많았지 만 편집했습니다.
LogicBreaker 2016 년

1

자바 스크립트 (ES6), 68 바이트

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

데모


alert?
얽히고 설킨

@Shaggy이 과제는 각 요소를 별도의 줄에 인쇄 하도록 요구합니다. 이는 현재 표준에서 눈에 띄게 될 것입니다. 대부분의 답변은이 규칙을 따르는 것 같습니다.
Arnauld

아, 충분히 공평합니다. "print"를 "output"으로 해석했습니다.
얽히고 설킨


0

루비 배열 메소드 조합 (1.9 ~) [50 자]

0.upto(ARGV.size){|a|ARGV.combination(a){|v| p v}}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.