Variación de N bits en suma de subconjuntos


14

Para otro desafío que estoy escribiendo, necesito verificar que los casos de prueba se puedan resolver con enteros acotados. Específicamente, necesito verificar lo siguiente, para una matriz no Aentera de enteros y un ancho de bit entero n:

  1. Todos los enteros aen Asatisf -2**(n-1) <= a < 2**(n-1)(representables con nlos enteros complementarios de dos bits).
  2. La longitud de Aes menor que 2**n.
  3. La suma de las Asatisfacciones -2**(n-1) <= sum(A) < 2**(n-1).
  4. Todas las combinaciones de elementos Asatisfacen todas las condiciones anteriores.

¡Naturalmente, he decidido externalizar este problema!

Dada una matriz de enteros Ay un ancho de bit entero positivo n, verifique que Acumpla con las condiciones anteriores.

Casos de prueba

[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

Implementación de referencia (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))

Pruébalo en línea!



¿Debemos manejar la lista vacía?
Sr. Xcoder

@ Mr.Xcoder No, lo aclararé.
Mego

Respuestas:


7

Wolfram Language (Mathematica) , 40 bytes

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

Pruébalo en línea!

La condición 1 está implícita al verificar la condición 3 para todos los subconjuntos, incluidos los de un elemento. Entonces tomamos el máximo de

  • dos veces la suma de cada subconjunto,
  • uno menos del doble del negativo de la suma de cada subconjunto, y
  • la longitud de todo el conjunto

y verifique si es menor que 2^#2(donde #2está la entrada de ancho de bits).

A costa de sólo 6 bytes más, podemos reemplazar Subsets@#con GatherBy[#,Arg], que es mucho más eficiente, ya que sólo computa los dos subconjuntos peor de los casos: el subconjunto de todos los valores no negativos, y el subconjunto de todos los valores negativos. (Esto funciona porque Argtiene un valor 0en el primero y πen el segundo).



3

05AB1E , 13 12 11 bytes

Guardado 1 byte gracias al Sr. Xcoder

æO·D±¹gMIo‹

Pruébalo en línea!

Explicación

æ             # 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í, gracias! (Me sigo olvidando ±)
Emigna

2

JavaScript (ES6), 75 63 58 bytes

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

La suma de cualquier subconjunto de amentiras entre las sumas de los elementos negativos y no negativos, por lo que verificar las dos sumas es suficiente para todo excepto el caso 2. Editar: Guardado 12 17 bytes gracias a @Arnauld.


Mucho mejor que mi enfoque ingenuo. :-) Esto podría acortarse a 61 bytes
Arnauld

En realidad, podemos procesar la prueba dentro del ciclo para 56 bytes .
Arnauld

Hackeado ([-2, -1, -2]) (3)
l4m2

@ l4m2 Buena captura. Arreglo sugerido (57 bytes)
Arnauld

@Arnauld El problema aquí es que [-2, -2], 3debería ser cierto, ¿no?
Neil

1

Jalea , 21 20 bytes

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

Pruébalo en línea!

Solución de complejidad de tiempo lineal. Resulta que sobreestimé la complejidad del tiempo

en El decimonoveno byte, 2017-12-11 13-15-03Z, por usuario202729

@NewSandboxedPosts El problema de suma de subconjuntos "real" es mucho más difícil. Este se puede hacer en tiempo linealitmico ...

porque ahora me doy cuenta de que ordenar la matriz es completamente innecesario.


Explicación:

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


Parece que ~2¦puede ser ;~. EDITAR: Listo.
user202729

@ user202729 Incorrecto. Aún así, ;~$funcionará.
usuario202729

1

JavaScript (ES6), 114 bytes

Toma entrada en la sintaxis de curry (A)(n). Devuelve un 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)

Casos de prueba



1

Clojure, 121 117 bytes

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

Bueno, eso fue un poco tonto, dividir en valores positivos y negativos es mucho mejor que ordenar. Original, pero sorprendentemente no mucho más:

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

Esto funciona comprobando las sumas de prefijos de la secuencia en orden ascendente y descendente, creo que no es necesario generar todas las combinaciones de elementos A.

(into () S)es en efecto igual que (reverse S), a medida que las listas crecen desde la cabeza No pude encontrar una manera de usar en conslugar de concatcuando hay dos listas para conshacer. : /


1

Jalea , 15 bytes

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

Pruébalo en línea!

Explicación

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

Guardado 1 byte gracias a caird coinheringaahing (leyendo la segunda entrada de STDIN en lugar de CLA).


@ user202729 He preguntado al OP, y nosotros no tenemos que manejar la lista vacía
Sr. Xcoder,

0

Casco , 14 bytes

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

Ir con fuerza bruta recorriendo todas las sublistas, ya que dividir en partes positivas y negativas requiere más bytes. Pruébalo en línea!

Explicación

≥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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.