부분 집합 합의 N 비트 변형


14

필자가 작성중인 또 다른 과제에 대해서는 테스트 사례가 제한된 정수로 해결할 수 있는지 확인해야합니다. 특히 비어 있지 않은 정수 배열 A과 정수 비트 너비에 대해 다음을 확인해야합니다 n.

  1. 모든 정수 aA충족 -2**(n-1) <= a < 2**(n-1)(로 표현할 수있는 n비트 2의 보수 정수).
  2. 길이 A가보다 작습니다 2**n.
  3. 의 합이 A만족 -2**(n-1) <= sum(A) < 2**(n-1)됩니다.
  4. 원소들의 모든 조합은 A상기 조건을 모두 만족시킨다.

당연히이 문제를 당신에게 아웃소싱하기로 결정했습니다!

정수 배열을 감안 A하고 양의 정수 비트 폭 n, 즉 검증A 위 조건 만족 하십시오.

테스트 사례

[0, 0, 0], 2: True
[0, 0, 0, 0], 2: False (violates #2)
[1, 2, 3, 4, 5], 8: True
[1, 2, 3, 4, 5], 2: False (violates all conditions)
[1, 2, 3, 4, 5], 5: True
[-3, 4, 1], 4: True
[10, 0, -10], 4: False (violates #1 and #4)
[27, -59, 20, 6, 10, 53, -21, 16], 8: False (violates #4)
[-34, 56, 41, -4, -14, -54, 30, 38], 16: True
[-38, -1, -11, 127, -35, -47, 28, 89, -8, -12, 77, 55, 75, 75, -80, -22], 7: False (violates #4)
[-123, -85, 6, 121, -5, 12, 52, 31, 64, 0, 6, 101, 128, -72, -123, 12], 12: True

참조 구현 (Python 3)

#!/usr/bin/env python3
from itertools import combinations
from ast import literal_eval


def check_sum(L, n):
  return -2**(n-1) <= sum(L) < 2**(n-1)


def check_len(L, n):
  return len(L) < 2**n


def check_elems(L, n):
  return all(-2**(n-1) <= a < 2**(n-1) for a in L)


A = literal_eval(input())
n = int(input())
OUTPUT_STR = "{}, {}: {}".format(A, n, "{}")

if not (check_elems(A, n) and check_len(A, n) and check_sum(A, n)):
  print(OUTPUT_STR.format(False))
  exit()

for k in range(1, len(A)):
  for b in combinations(A, k):
    if not check_sum(b, n):
      print(OUTPUT_STR.format(False))
      exit()

print(OUTPUT_STR.format(True))

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



빈 목록을 처리해야합니까?
Mr. Xcoder

@ Mr.Xcoder 아니요, 명확히하겠습니다.
Mego

답변:


7

Wolfram Language (Mathematica) , 40 바이트

Max[x=2Tr/@Subsets@#,-x-1,Tr[1^#]]<2^#2&

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

요소 1을 포함하여 모든 서브 세트에 대해 조건 3을 점검하여 조건 1을 내포합니다. 그래서 우리는

  • 각 부분 집합의 합의 두 배
  • 각 하위 집합의 합의 음수의 두 배보다 작은 것
  • 전체 세트의 길이

그리고 비트 너비 입력 2^#2위치 보다 작은 지 확인하십시오 #2.

단지 6 개 바이트의 비용에서, 우리는 대체 할 수 Subsets@#GatherBy[#,Arg]모든 음이 아닌 값의 집합, 모든 음의 값의 집합이 : 그것은 단지 두 개의 최악의 부분 집합을 계산하기 때문에 훨씬 더 효율적이다. (이것은 전자와 후자 Arg의 가치가 있기 때문에 작동합니다 .)0π



3

05AB1E , 13 12 11 바이트

Mr. Xcoder 덕분에 1 바이트 절약

æO·D±¹gMIo‹

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

설명

æ             # powerset of first input
 O            # sum each subset
  ·           # multiply each element by 2
   D          # duplicate
    ±         # bitwise negation of each element in the copy
     ¹g       # push length of first input
       M      # get the maximum value on the stack
        Io    # push 2**<second input>
          ‹   # compare

@ Mr.Xcoder : 예, 감사합니다! (나는 계속 잊어 ±
버린다

2

자바 스크립트 (ES6), 75 63 58 바이트

a=>n=>!a.some(e=>(a.length|2*(e<0?l-=e:u+=e))>>n,u=0,l=-1)

부분 집합의 a합은 음의 요소와 음이 아닌 요소의 합 사이에 있으므로 두 합을 확인하면 대소 문자 2를 제외한 모든 항목에 충분합니다. 편집 : @Arnauld 덕분에 12 17 바이트가 절약되었습니다.


나의 순진한 접근 방식보다 훨씬 낫습니다. :-) 이것은 61 바이트
Arnauld

실제로 루프 내에서 56 바이트 동안 테스트를 처리 할 수 ​​있습니다 .
Arnauld

해킹 ([-2, -1, -2]) (3)
l4m2

@ l4m2 잘 잡습니다. 제안 된 수정 (57 바이트)
Arnauld

@Arnauld 여기서 문제는 [-2, -2], 3사실입니다.
Neil

1

젤리 , 21 20 바이트

»0,«0$S€~2¦Ḥ;LṀ<2*Ɠ¤

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

선형 시간 복잡성 솔루션. 시간 복잡성을 과대 평가했다는 것이 밝혀졌습니다.

2017 년 9 월 11 일 13-15-03Z, 19 번째 바이트에서, user202729에 의해

@NewSandboxedPosts "실제"하위 집합 합계 문제는 훨씬 어렵습니다. 이것은 선형 시간으로 할 수 있습니다 ...

이제 배열 정렬이 완전히 필요하지 않다는 것을 알기 때문입니다.


설명:

»0,«0$S€~2¦Ḥ;LṀ<2*Ɠ¤    Main link. Example list: [-1, 0, 1]
»0                      Maximize with 0. Get [0, 0, 1]
  ,                     Pair with
   «0$                    minimize with 0. Get [-1, 0, 0]
      S€                Sum €ach. Get [1, -1]
        ~               Inverse
          ¦               at element
         2                2. (list[2] = ~list[2]) Get [-1, 2]
           Ḥ            Unhalve (double, ×2). Get [-2, 4]
            ;           Concatenate with
             L            Length (3). Get [-2, 4, 3]
              Ṁ         Maximum of the list (4).
               <   ¤    Still less than
                2         two
                 *        raise to the power of
                  Ɠ       eval(input())


~2¦될 수있는 것 같습니다 ;~. 편집 : 완료
user202729

@ user202729 잘못되었습니다. 여전히 ;~$작동합니다.
user202729

1

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

카레 구문으로 입력을 (A)(n)받습니다. 부울을 반환합니다.

A=>n=>!(A.reduce((a,x)=>[...a,...a.map(y=>[x,...y])],[[]]).some(a=>(s=eval(a.join`+`),s<0?~s:s)>>n-1)|A.length>>n)

테스트 사례



1

클로저, 121 117 바이트

#(let[l(int(Math/pow 2(dec %2)))](every?(set(range(- l)l))(cons(count %)(for[i(vals(group-by pos? %))](apply + i)))))

음, 그것은 양손과 음의 값으로 나누는 것이 정렬보다 훨씬 좋습니다. 독창적이지만 놀라 울 정도로 길지 않습니다.

#(let[l(int(Math/pow 2(dec %2)))S(sort %)R reductions](every?(set(range(- l)l))(concat[(count S)](R + S)(R +(into()S)))))

이것은 시퀀스의 접두사 합계를 오름차순과 내림차순으로 확인하여 작동합니다 A. 에서 요소의 모든 조합을 생성 할 필요는 없다고 생각합니다 .

(into () S)(reverse S)목록이 헤드에서 커짐에 따라 와 동일 합니다. 두 개의 목록이있을 때 cons대신 사용하는 방법을 알 수 없었 습니다. : /concatcons


1

젤리 , 15 바이트

ŒPS€Ḥ;~$;LṀl2<Ɠ

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

설명

ŒPS€Ḥ;~$;LṀl2<Ɠ ~ Monadic full program.

ŒP              ~ Powerset.
  S€            ~ The sum of each subset.
    Ḥ           ~ Double (element-wise).
     ;~$        ~ Append the list of their bitwise complements.
        ;L      ~ Append the length of the first input.
          Ṁ     ~ And get the maximum.
           l2   ~ Base-2 logarithm.
             <Ɠ ~ Is smaller than the second input (from stdin)?

caird coinheringaahing (CLA 대신 STDIN에서 두 번째 입력을 읽음) 덕분에 1 바이트가 절약되었습니다 .


@ user202729 OP에게 요청했는데 빈 목록을 처리
Mr. Xcoder

0

껍질 , 14 바이트

≥Lḋ▲ṁ§eLöa→DΣṖ

양수 부분과 음수 부분으로 분할하면 더 많은 바이트가 필요하기 때문에 모든 하위 목록을 반복하여 무차별적인 힘을 발휘합니다. 온라인으로 사용해보십시오!

설명

≥Lḋ▲ṁ§eLöa→DΣṖ  Implicit inputs, say A=[1,2,3,4,5] and n=5
             Ṗ  Powerset of A: [[],[1],[2],[1,2],..,[1,2,3,4,5]]
    ṁ           Map and concatenate:
                  Argument: a sublist, say S=[1,3,4]
            Σ     Sum: 8
           D      Double: 16
          →       Increment: 17
        öa        Absolute value: 17
     §eL          Pair with length of S: [3,17]
                Result is [0,1,1,3,1,5,2,7,..,5,31]
   ▲            Maximum: 31
  ḋ             Convert to binary: [1,1,1,1,1]
 L              Length: 5
≥               Is it at most n: 1

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.