Variazione N-bit su Somma sottoinsieme


14

Per un'altra sfida che sto scrivendo, devo verificare che i casi di test siano risolvibili con numeri interi limitati. In particolare, devo verificare quanto segue, per una matrice non vuota di numeri interi Ae una larghezza di bit di numero intero n:

  1. Tutti gli interi ain Asoddisfano -2**(n-1) <= a < 2**(n-1)(rappresentabili con nnumeri interi complementi di -bit due).
  2. La lunghezza di Aè inferiore a 2**n.
  3. La somma delle Asoddisfazioni -2**(n-1) <= sum(A) < 2**(n-1).
  4. Tutte le combinazioni di elementi Asoddisfano tutte le condizioni di cui sopra.

Naturalmente, ho deciso di esternalizzare questo problema a te!

Data una matrice di numeri interi Ae una larghezza di bit intera positiva n, verificare che Asoddisfi le condizioni sopra.

Casi test

[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

Implementazione di riferimento (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))

Provalo online!



Dobbiamo gestire l'elenco vuoto?
Mr. Xcoder il

@ Mr.Xcoder No, chiarirò.
Mego

Risposte:


7

Wolfram Language (Mathematica) , 40 byte

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

Provalo online!

La condizione 1 è implicita controllando la condizione 3 per tutti i sottoinsiemi, compresi quelli a un elemento. Quindi prendiamo il massimo di

  • il doppio della somma di ciascun sottoinsieme,
  • uno meno del doppio del negativo della somma di ciascun sottoinsieme e
  • la lunghezza dell'intero set

e controlla se è inferiore a 2^#2(dov'è #2l'input della larghezza di bit).

Al costo di soli 6 byte in più, possiamo sostituirlo Subsets@#con GatherBy[#,Arg], il che è molto più efficiente perché calcola solo i due sottoinsiemi del caso peggiore: il sottoinsieme di tutti i valori non negativi e il sottoinsieme di tutti i valori negativi. (Questo funziona perché Argha un valore 0sul primo e πsul secondo.)


3

Gelatina , 19 byte

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

Provalo online!

È sufficiente verificare che mapped sum of powerset + length of setsia compreso nell'intervallo richiesto.


1
Io penso (anche se non sono sicuro) è possibile utilizzare ÆẸal posto di 2*$(non testato)
Mr. Xcoder

@ Mr.Xcoder Funziona.
user202729

3

05AB1E , 13 12 11 byte

Salvato 1 byte grazie a Mr. Xcoder

æO·D±¹gMIo‹

Provalo online!

Spiegazione

æ             # 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: Oh sì, grazie! (Continuo a dimenticare ±)
Emigna il

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)

La somma di ogni sottoinsieme di abugie tra le somme degli elementi negativi e non negativi, quindi controllare le due somme è sufficiente per tutto tranne il caso 2. Modifica: Salvato 12 17 byte grazie a @Arnauld.


Molto meglio del mio approccio ingenuo. :-) Questo potrebbe essere ridotto a 61 byte
Arnauld il

In realtà, possiamo semplicemente elaborare il test all'interno del loop per 56 byte .
Arnauld,

Hacked on ([-2, -1, -2]) (3)
l4m2

@ l4m2 Buona cattura. Correzione suggerita (57 byte)
Arnauld

@Arnauld Il problema qui è che [-2, -2], 3dovrebbe essere vero, no?
Neil,

1

Gelatina , 21 20 byte

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

Provalo online!

Soluzione di complessità temporale lineare. Risulta che ho sopravvalutato la complessità temporale

in The Nineteenth Byte, 13-12-03Z 2017-12-12, user202729

@NewSandboxedPosts Il problema della somma dei sottoinsiemi "reali" è molto più difficile. Questo può essere fatto in tempo linearitmico ...

perché ora mi rendo conto che l'ordinamento dell'array è completamente inutile.


Spiegazione:

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


Sembra che ~2¦possa essere ;~. EDIT: Fatto.
user202729,

@ user202729 Sbagliato. Comunque ;~$funzionerà.
user202729,

1

JavaScript (ES6), 114 byte

Accetta input nella sintassi del curry (A)(n). Restituisce un valore booleano.

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)

Casi test



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

Beh, era un po 'stupido, dividere in valori positivi e negativi è molto meglio dell'ordinamento. Originale, ma sorprendentemente non molto più lungo:

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

Questo funziona controllando le somme dei prefissi della sequenza in ordine crescente e decrescente, penso che non sia necessario generare tutte le combinazioni di elementi in A.

(into () S)è in effetti lo stesso di (reverse S), poiché le liste crescono dalla testa. Non sono riuscito a capire un modo di usare consinvece di concatquando ci sono due liste da consfare. : /


1

Gelatina , 15 byte

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

Provalo online!

Spiegazione

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

Salvato 1 byte grazie a caird coinheringaahing (lettura del secondo input da STDIN invece di CLA).


@utente202729 Ho chiesto al PO, e non dobbiamo gestire la lista vuota
Mr. Xcoder

0

Buccia , 14 byte

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

Procedere con forza bruta eseguendo il ciclo su tutte le liste secondarie, poiché la suddivisione in parti positive e negative richiede più byte. Provalo online!

Spiegazione

≥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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.