Variasi N-bit pada Subset-Jumlah

14

Untuk tantangan lain yang saya tulis, saya perlu memverifikasi bahwa kasus uji dapat diselesaikan dengan bilangan bulat terbatas. Secara khusus, saya perlu memverifikasi yang berikut ini, untuk array integer yang tidak kosong Adan lebar bit integer n:

  1. Semua bilangan bulat adi Amemuaskan -2**(n-1) <= a < 2**(n-1)(representable dengan n-bit dua ini bilangan bulat pelengkap).
  2. Panjangnya Akurang dari 2**n.
  3. Jumlah Akepuasan -2**(n-1) <= sum(A) < 2**(n-1).
  4. Semua kombinasi elemen Amemenuhi semua kondisi di atas.

Secara alami, saya telah memutuskan untuk mengalihdayakan masalah ini kepada Anda!

Diberikan array bilangan bulat Adan lebar bit bilangan bulat positif n, verifikasi yang Amemenuhi kondisi di atas.

Uji Kasus

[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

Implementasi Referensi (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))

Cobalah online!

Mego
sumber
Sandbox
Mego
Haruskah kita menangani daftar kosong?
Tn. Xcoder
@ Mr.Xcoder Tidak, saya akan mengklarifikasi.
Mego

Jawaban:

7

Bahasa Wolfram (Mathematica) , 40 byte

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

Cobalah online!

Kondisi 1 tersirat dengan memeriksa kondisi 3 untuk semua himpunan bagian, termasuk yang satu elemen. Jadi kami mengambil maks

  • dua kali jumlah setiap subset,
  • satu kurang dari dua kali negatif dari jumlah masing-masing bagian, dan
  • panjang seluruh set

dan periksa apakah itu kurang dari 2^#2(di mana #2input bit-width).

Dengan biaya hanya 6 byte lebih, kita dapat menggantinya Subsets@#dengan GatherBy[#,Arg], yang jauh lebih efisien karena hanya menghitung dua himpunan bagian terburuk: himpunan bagian dari semua nilai non-negatif, dan himpunan bagian dari semua nilai negatif. (Ini berfungsi karena Argmemiliki nilai 0pada yang pertama dan πyang terakhir.)

Misha Lavrov
sumber
3

Jelly , 19 byte

ŒPS€;⁸L¤ḟ⁹’2*$ŒRṖ¤Ṇ

Cobalah online!

Sudah cukup untuk memeriksa bahwa mapped sum of powerset + length of setada dalam kisaran yang diperlukan.

Biarawati Bocor
sumber
1
Saya pikir (meskipun saya tidak yakin) Anda dapat menggunakan ÆẸalih-alih 2*$(belum teruji)
Tn. Xcoder
@ Mr.Xcoder Tidak berhasil.
user202729
3

05AB1E , 13 12 11 byte

Disimpan 1 byte berkat Tn. Xcoder

æO·D±¹gMIo‹

Cobalah online!

Penjelasan

æ             # 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
Emigna
sumber
@ Mr.Xcoder: Oh ya, terima kasih! (Saya terus lupa tentang ±)
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)

Jumlah dari setiap himpunan akebohongan antara jumlah dari elemen negatif dan nonnegatif, jadi memeriksa dua jumlah tersebut sudah cukup untuk semuanya kecuali case 2. Edit: Disimpan 12 17 byte berkat @Arnauld.

Neil
sumber
Jauh lebih baik daripada pendekatan naif saya. :-) Ini bisa disingkat menjadi 61 byte
Arnauld
Sebenarnya, kita bisa memproses tes di dalam loop selama 56 byte .
Arnauld
Diretas pada ([-2, -1, -2]) (3)
l4m2
@ l4m2 Tangkapan bagus. Perbaikan yang disarankan (57 byte)
Arnauld
@Arnauld Masalahnya di sini adalah yang [-2, -2], 3seharusnya benar, bukan?
Neil
1

Jelly , 21 20 byte

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

Cobalah online!

Solusi kompleksitas waktu linier. Ternyata saya terlalu memperkirakan kerumitan waktu

dalam The Nineteenth Byte, 2017-12-11 13-15-03Z, oleh user202729

@NewSandboxedPosts Masalah jumlah subset "Nyata" jauh lebih sulit. Yang ini dapat dilakukan dalam waktu linearitmik ...

karena sekarang saya menyadari bahwa menyortir array sama sekali tidak perlu.


Penjelasan:

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

pengguna202729
sumber
Sepertinya itu ~2¦bisa ;~. EDIT: Selesai.
user202729
@ user202729 Salah Tetap saja ;~$akan berhasil.
user202729
1

JavaScript (ES6), 114 byte

Mengambil input dalam sintaks currying (A)(n). Mengembalikan 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)

Uji kasus

Arnauld
sumber
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)))))

Yah itu agak bodoh, memecah menjadi nilai positif dan negatif jauh lebih baik daripada memilah. Asli, tetapi secara mengejutkan tidak lebih lama:

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

Ini bekerja dengan memeriksa jumlah awalan dari urutan dalam urutan naik dan turun, saya pikir itu tidak perlu untuk menghasilkan semua kombinasi elemen di A .

(into () S)berlaku sama dengan (reverse S), karena daftar tumbuh dari kepala. Saya tidak bisa menemukan cara untuk menggunakannya consdaripada concatketika ada dua daftar untuk consmelakukannya. : /

NikoNyrh
sumber
1

Jelly , 15 byte

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

Cobalah online!

Penjelasan

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

Disimpan 1 byte berkat caird coinheringaahing (membaca input kedua dari STDIN bukan CLA).

Tuan Xcoder
sumber
@ user202729 Saya telah meminta OP, dan kami tidak harus menangani daftar kosong
Tn. Xcoder
0

Sekam , 14 byte

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

Pergi dengan kekuatan kasar dengan mengulang semua sublists, karena membelah menjadi bagian positif dan negatif membutuhkan lebih banyak byte. Cobalah online!

Penjelasan

≥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
Zgarb
sumber