Варіація N-бітів на підмножині


14

Для іншого завдання, про який я пишу, мені потрібно переконатися, що тестові випадки вирішуються з обмеженими цілими числами. Зокрема, мені потрібно перевірити наступне для не порожнього масиву цілих чисел Aта цілої ширини бітів n:

  1. Всі цілі числа aу Aзадоволенні -2**(n-1) <= a < 2**(n-1)(представлені з n-бітними цілими цілими числами-два).
  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))

Спробуйте в Інтернеті!



Чи повинні ми обробляти порожній список?
Містер Xcoder

@ Mr.Xcoder Ні, я уточню.
Мего

Відповіді:


7

Мова Вольфрама (Mathematica) , 40 байт

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

Спробуйте в Інтернеті!

Умова 1 має на увазі перевірку умови 3 для всіх підмножин, включаючи одноелементні. Отже, ми беремо макс

  • подвоєна сума кожного підмножини,
  • один менший, ніж удвічі більше, від суми кожного підмножини, і
  • довжина всього набору

і перевірте, чи не менше 2^#2(де #2вхідна ширина біта).

Коштуючи лише 6 байтів, ми можемо замінити Subsets@#їх GatherBy[#,Arg], що набагато ефективніше, оскільки він обчислює лише два найгірших підмножини: підмножину всіх негативних значень та підмножину всіх негативних значень. (Це працює, оскільки Argмає значення 0як для першого, так і πдля другого.)


3

Желе , 19 байт

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

Спробуйте в Інтернеті!

Досить перевірити, mapped sum of powerset + length of setчи знаходиться в необхідному діапазоні.


1
Я думаю (хоча я не впевнений) ви можете використовувати ÆẸзамість 2*$(неперевірений)
Містер Xcoder

@ Mr.Xcoder Це працює.
user202729

3

05AB1E , 13 12 11 байт

Збережено 1 байт завдяки панові Xcoder

æ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

JavaScript (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. Редагувати: Збережено 12 17 байт завдяки @Arnauld.


Набагато краще, ніж мій наївний підхід. :-) Це може бути скорочено до 61 байта
Арнольд

Насправді ми можемо просто обробити тест у циклі на 56 байт .
Арнольд

Зламаний ([-2, -1, -2]) (3)
l4m2

@ l4m2 Хороший улов. Запропонований виправлення (57 байт)
Арнольд

@Arnauld Проблема тут у тому, що [-2, -2], 3має бути правдою, ні?
Ніл

1

Желе , 21 20 байт

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

Спробуйте в Інтернеті!

Рішення лінійної складності в часі. Виявляється, я переоцінив складність часу

у дев'ятнадцятому байті, 2017-12-11 13-15-03Z, користувачем202729

@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¦може бути ;~. EDIT: Готово.
користувач202729

@ user202729 Неправильно. Все-таки ;~$буде працювати.
користувач202729

1

JavaScript (ES6), 114 байт

Здійснює введення в синтаксис currying (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

Clojure, 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замість того, concatколи є два списки cons. : /


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

Збережено 1 байт завдяки caird coinheringaahing (зчитування другого вводу зі STDIN замість CLA).



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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.