Biến thể N-bit trên tập hợp con


14

Đối với một thử thách khác mà tôi đang viết, tôi cần xác minh rằng các trường hợp thử nghiệm có thể giải quyết được với các số nguyên bị ràng buộc. Cụ thể, tôi cần xác minh các điều sau đây, cho một mảng số nguyên không trống Avà độ rộng bit nguyên n:

  1. Tất cả các số nguyên atrong Athỏa mãn -2**(n-1) <= a < 2**(n-1)(biểu diễn với n-bit hai của số nguyên bổ sung).
  2. Độ dài Anhỏ hơn 2**n.
  3. Tổng số Athỏa mãn -2**(n-1) <= sum(A) < 2**(n-1).
  4. Tất cả sự kết hợp của các yếu tố trong Ađáp ứng tất cả các điều kiện trên.

Đương nhiên, tôi đã quyết định thuê ngoài vấn đề này cho bạn!

Cho một mảng các số nguyên Avà độ rộng bit nguyên dương n, xác minh rằng Athỏa mãn các điều kiện trên.

Các trường hợp thử nghiệm

[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

Tham chiếu thực hiện (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))

Hãy thử trực tuyến!



Chúng ta phải xử lý danh sách trống?
Ông Xcoder

@ Mr.Xcoder Không, tôi sẽ làm rõ.
Mego

Câu trả lời:


7

Ngôn ngữ Wolfram (Mathicala) , 40 byte

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

Hãy thử trực tuyến!

Điều kiện 1 được ngụ ý bằng cách kiểm tra điều kiện 3 cho tất cả các tập hợp con, bao gồm cả các phần tử một. Vì vậy, chúng tôi lấy tối đa

  • hai lần tổng của mỗi tập hợp con,
  • một ít hơn hai lần âm của tổng của mỗi tập hợp con và
  • chiều dài của cả bộ

và kiểm tra xem nó có nhỏ hơn không 2^#2( #2đầu vào có độ rộng bit).

Với chi phí chỉ có thêm 6 byte, chúng ta có thể thay thế Subsets@#bằng GatherBy[#,Arg], hiệu quả hơn nhiều vì nó chỉ tính hai tập hợp con xấu nhất: tập hợp con của tất cả các giá trị không âm và tập hợp con của tất cả các giá trị âm. (Điều này hoạt động vì Argcó giá trị của 0cái trước và πcái sau.)



3

05AB1E , 13 12 11 byte

Đã lưu 1 byte nhờ Mr. Xcoder

æO·D±¹gMIo‹

Hãy thử trực tuyến!

Giải trình

æ             # 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: Ồ vâng, cảm ơn! (Tôi tiếp tục quên về ±)
Emigna

2

JavaScript (ES6), 75 63 58 byte

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

Tổng của bất kỳ tập hợp con anằm giữa tổng của các phần tử âm và không âm, vì vậy kiểm tra hai tổng đủ cho tất cả mọi thứ trừ trường hợp 2. Chỉnh sửa: Đã lưu 12 17 byte nhờ @Arnauld.


Tốt hơn nhiều so với cách tiếp cận ngây thơ của tôi. :-) Điều này có thể được rút ngắn xuống còn 61 byte
Arnauld

Trên thực tế, chúng ta chỉ có thể xử lý kiểm tra trong vòng lặp cho 56 byte .
Arnauld

Bị tấn công vào ([-2, -1, -2]) (3)
l4m2

@ l4m2 Bắt tốt. Đề xuất sửa chữa (57 byte)
Arnauld

@Arnauld Vấn đề ở đây là [-2, -2], 3có đúng không?
Neil

1

Thạch , 21 20 byte

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

Hãy thử trực tuyến!

Giải pháp phức tạp thời gian tuyến tính. Hóa ra tôi đã ước tính quá mức độ phức tạp của thời gian

trong Byte thứ mười chín, 2017-12-11 13-15-03Z, bởi người dùng202729

@NewSandboxedPosts Vấn đề tổng hợp tập hợp con "thực" khó hơn nhiều. Điều này có thể được thực hiện trong thời gian tuyến tính ...

bởi vì bây giờ tôi nhận ra việc sắp xếp mảng là hoàn toàn không cần thiết.


Giải trình:

»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())


Có vẻ như ~2¦có thể ;~. EDIT: Xong.
dùng202729

@ user202729 Sai. Tuy nhiên, ;~$sẽ làm việc.
dùng202729

1

JavaScript (ES6), 114 byte

Đưa đầu vào theo cú pháp currying (A)(n). Trả về một boolean.

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)

Các trường hợp thử nghiệm



1

Clojure, 121 117 byte

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

Vâng, đó là một chút ngu ngốc, chia thành các giá trị tích cực và tiêu cực tốt hơn nhiều so với sắp xếp. Bản gốc, nhưng đáng ngạc nhiên không còn lâu nữa:

#(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)))))

Điều này hoạt động bằng cách kiểm tra các tổng tiền tố của chuỗi theo thứ tự tăng dần và giảm dần, tôi nghĩ rằng không cần thiết phải tạo ra tất cả các kết hợp các yếu tố trong A.

(into () S)có hiệu lực tương tự như (reverse S)khi danh sách phát triển từ đầu. Tôi không thể tìm ra cách sử dụng consthay vì concatkhi có hai danh sách cons. : /


1

Thạch , 15 byte

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

Hãy thử trực tuyến!

Giải trình

Œ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)?

Đã lưu 1 byte nhờ caird coinheringaahing (đọc đầu vào thứ hai từ STDIN thay vì CLA).


@ user202729 Tôi đã hỏi OP và chúng tôi không phải xử lý danh sách trống
Ông Xcoder

0

Husk , 14 byte

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

Đi với lực lượng vũ phu bằng cách lặp qua tất cả các danh sách con, vì việc chia thành các phần tích cực và tiêu cực cần nhiều byte hơn. Hãy thử trực tuyến!

Giải trình

≥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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.