Genera combinaciones que se suman a un valor objetivo

14

Desafío

Suponga que tiene una lista de números y un valor objetivo. Encuentre el conjunto de todas las combinaciones de sus números que se suman al valor objetivo, devolviéndolos como índices de lista.

Entrada y salida

La entrada tomará una lista de números (no necesariamente únicos) y un número de suma objetivo. La salida será un conjunto de listas no vacías, cada lista con valores enteros correspondientes a la posición de los valores en la lista de entrada original.

Ejemplos

Input: values = [1, 2, 1, 5], target = 8
Output: [ [0,1,3], [1,2,3] ]

Input: values = [4.8, 9.5, 2.7, 11.12, 10], target = 14.8
Output: [ [0,4] ]

Input: values = [7, 8, 9, -10, 20, 27], target = 17
Output: [ [1,2], [0,3,4], [3,5] ]

Input: values = [1, 2, 3], target = 7
Output: [ ]

Puntuación

Este es el , por lo que gana el código más corto.

Soapergem
fuente
66
Relacionado , posiblemente un engañado.
Giuseppe
Creo que esto es un engaño, pero preferiría cerrar el anterior porque está desactualizado.
Post Rock Garf Hunter
44
¿Los números de coma flotante realmente agregan algo al desafío? No estoy seguro de cuál es el consenso, pero probablemente conducirán a errores de precisión en muchos idiomas.
Arnauld
Tenía la intención de permitir puntos flotantes, sí
Soapergem
14
Bleh, índices? Creo que este sería un desafío más agradable al devolver una lista de valores, aunque supongo que eso plantea una pregunta sobre cómo se tratan los valores repetidos en los subconjuntos.
xnor

Respuestas:

3

Casco , 10 bytes

ηλfo=¹ṁ⁰tṖ

1 indexado. Pruébalo en línea!

Explicación

ηλfo=¹ṁ⁰tṖ  Inputs are a number n (explicit, accessed with ¹) and a list x (implicit).
η           Act on the incides of x
 λ          using this function:
         Ṗ   Take all subsets,
        t    remove the first one (the empty subset),
  f          and keep those that satisfy this:
      ṁ⁰      The sum of the corresponding elements of x
   o=¹        equals n.

Esto utiliza la última incorporación a Husk, η(actuar sobre índices). La idea es que ηtoma una función de orden superior α(aquí la función lambda en línea) y una lista x, y llama αa la función de indexación de x(que está en el programa anterior) y los índices de x. Por ejemplo, ṁ⁰toma un subconjunto de índices, asigna índices a xellos y suma los resultados.

Zgarb
fuente
9

JavaScript (ES6), 96 bytes

Toma entrada en la sintaxis de curry (list)(target).

a=>s=>a.reduce((b,_,x)=>[...b,...b.map(y=>[...y,x])],[[]]).filter(b=>!b.reduce((p,i)=>p-a[i],s))

Casos de prueba

Esto fallaría en el segundo caso de prueba si 4.8 y 10 se intercambiaran debido a un error de precisión IEEE 754, es decir, 14.8 - 4.8 - 10 == 0pero 14.8 - 10 - 4.8 != 0. Creo que esto está bien , aunque puede haber una referencia más relevante en algún lugar del meta.

Comentado

a => s =>                 // given an array a[] of length N and an integer s
  a.reduce((b, _, x) =>   // step #1: build the powerset of [0, 1, ..., N-1]
    [ ...b,               //   by repeatedly adding to the previous list b[]
      ...b                //   new arrays made of:
      .map(y =>           //     all previous entries stored in y[]
        [...y, x]         //     followed by the new index x
      )                   //   leading to:
    ],                    //   [[]] -> [[],[0]] -> [[],[0],[1],[0,1]] -> ...
    [[]]                  //   we start with a list containing an empty array
  )                       // end of reduce()
  .filter(b =>            // step #2: filter the powerset
    !b.reduce((p, i) =>   //   keeping only entries b
      p - a[i],           //     for which sum(a[i] for i in b)
      s                   //     is equal to s
    )                     //   end of reduce()
  )                       // end of filter()
Arnauld
fuente
77
¿No uno sino dos reduces? Tengo que votar esto.
Neil
1
@Neil El "reduceMapReduce" menos conocido
Lord Farquaad
7

Python 2 , 110 bytes

lambda a,n:[b for b in[[i for i in range(len(a))if j&1<<i]for j in range(2**len(a))]if sum(a[c]for c in b)==n]

Pruébalo en línea!

Chas Brown
fuente
7

R , 85 84 bytes

function(l,k){N=combn
o={}
for(i in I<-1:sum(l|1))o=c(o,N(I,i,,F)[N(l,i,sum)==k])
o}

Pruébalo en línea!

1 indexado.

combngeneralmente devuelve a matrix, pero la configuración simplify=Fdevuelve a listen su lugar, lo que nos permite concatenar todos los resultados juntos. combn(I,i,,F)devuelve todas las combinaciones de índices, y tomamos N(l,i,sum)==kcomo índice en esa lista para determinar los que son iguales k.

Giuseppe
fuente
7

J , 32 31 bytes

(=1#.t#])<@I.@#t=.1-[:i.&.#.1"0

Pruébalo en línea!

                  1-[:i.&.#.1"0         Make a list of all masks
                                        for the input list. We flip the bits
                                        to turn the unnecessary (0...0)         
                                        into (1...1) that would be missing.
                                        Define it as t.

(=1#.t#])                               Apply the masks, sum and
                                        compare with the target

         <@I.@#                         Turn the matching masks into 
                                        lists of indices
FrownyFrog
fuente
Me siento como una definición explícita ayudaría dado todas las composiciones, pero por desgracia sólo me dieron la misma longitud: 4 :'<@I.t#~x=1#.y#~t=.#:}.i.2^#y'. Pruébalo en línea!
cole
5

Japt , 14 bytes

m, à f_x!gU ¥V

¡Pruébalo en línea!

Cómo funciona

m, à f_x!gU ¥V   Implicit: U = input array, V = target sum
m,               Turn U into a range [0, 1, ..., U.length - 1].
   à             Generate all combinations of this range.
     f_          Filter to only the combinations where
       x           the sum of
        !gU        the items at these indices in U
            ¥V     equals the target sum.
                 Implicit: output result of last expression
ETHproductions
fuente
Buen truco con m,. Tenía Êo à k@VnXx@gXpara el mismo recuento de bytes.
Shaggy
5

Limpio , 104 102 98 bytes

import StdEnv
@n=[[]:[[i:b]\\i<-[0..n-1],b<- @i]]
?l n=[e\\e<-tl(@(length l))|sum(map((!!)l)e)==n]

Pruébalo en línea!

Οurous
fuente
[1, 2, -1, 5] 0 --> [[],[2,0]]Se requiere un conjunto de listas no vacías.
FrownyFrog
@FrownyFrog Fixed
--urous
4

Haskell , 76 bytes

x#t=[i|i<-tail$concat<$>mapM(\z->[[],[z]])[0..length x-1],t==sum[x!!k|k<-i]]

Pruébalo en línea!

Cristian Lupascu
fuente
[1, 2, -1, 5]#0 --> [[],[0,2]]Se requiere un conjunto de listas no vacías.
FrownyFrog
@FrownyFrog ¡Gracias! Fijo.
Cristian Lupascu
4

Jalea , 11 bytes

ị³S=
JŒPçÐf

Pruébalo en línea!

1 indexado. 4 bytes gastados en devolver índices en lugar de solo los elementos en sí.

-1 byte gracias al usuario202729
-1 byte gracias a Jonathan Allan

Hiperneutrino
fuente
12 bytes
user202729
@ user202729 ¡Genial, gracias!
HyperNeutrino
1
-1 byte: es innecesario si lo usa en çlugar de Ç.
Jonathan Allan
@ JonathanAllan o buena captura gracias!
HyperNeutrino
2

Python 3 , 144 bytes

lambda a,t:[[e for e,_ in x]for r in range(len(a))for x in combinations(list(enumerate(a)),r+1)if sum(y for _,y in x)==t]
from itertools import*

Pruébalo en línea!

0 indexado. 44 bytes gastados en devolver índices en lugar de solo los elementos en sí.

Hiperneutrino
fuente
2

Brachylog , 18 15 bytes

hiᶠ⊇Shᵐ+~t?∧Stᵐ

Pruébalo en línea!

-3 bytes porque ahora funciona como generador . (Probablemente sea posible jugar más al golf, pero evitar la necesidad de usar índices es incómodo).

    S              The variable S
   ⊇               is a sublist of
  ᶠ                the list of all
 i                 pairs [element, index] from
h                  the first element of
                   the input;
     hᵐ            the first elements of each pair
       +           add up to
        ~t         the last element of
          ?        the input
           ∧       which isn't necessarily
            S      S,
             tᵐ    from which the last elements of each pair
                   are output.
Cadena no relacionada
fuente
hiᶠ⊇z+ʰXh~t?∧Xtsale a la misma longitud.
Cadena no relacionada
1

Perl 6 , 45 bytes

->\a,\b{grep {a[$_].sum==b},^a .combinations}

Pruébalo

Expandido:

->
  \a, # input list
  \b, # input target
{

  grep

  {
      a[ $_ ].sum # use the list under test as indexes into 「a」
    ==
      b
  },

  ^a              # Range upto 「a」 (uses 「a」 as a number)
  .combinations   # get all of the combinations
}
Brad Gilbert b2gills
fuente
1

APL (NARS), 49 caracteres, 98 bytes

{∨/b←⍺=+/¨{∊⍵⊂w}¨n←{⍵⊤⍨k⍴2}¨⍳¯1+2*k←≢w←⍵:⍸¨b/n⋄⍬}

1 indexado; prueba:

  f←{∨/b←⍺=+/¨{∊⍵⊂w}¨n←{⍵⊤⍨k⍴2}¨⍳¯1+2*k←≢w←⍵:⍸¨b/n⋄⍬}
  ⎕fmt 8 f 1 2 1 5
┌2──────────────┐
│┌3────┐ ┌3────┐│
││2 3 4│ │1 2 4││
│└~────┘ └~────┘2
└∊──────────────┘
  ⎕fmt   14.8  f  4.8 9.5 2.7 11.12 10
┌1────┐
│┌2──┐│
││1 5││
│└~──┘2
└∊────┘
  ⎕fmt 17 f 7, 8, 9, ¯10, 20, 27
┌3──────────────────┐
│┌2──┐ ┌2──┐ ┌3────┐│
││4 6│ │2 3│ │1 4 5││
│└~──┘ └~──┘ └~────┘2
└∊──────────────────┘
  ⎕fmt 7 f 1 2 3
┌0┐
│0│
└~┘

comentario:

{∨/b←⍺=+/¨{∊⍵⊂w}¨n←{⍵⊤⍨k⍴2}¨⍳¯1+2*k←≢w←⍵:⍸¨b/n⋄⍬}
                             ⍳¯1+2*k←≢w←⍵         copy ⍵ in w, len(⍵) in k, return 1..2^(k-1) 
                 n←{⍵⊤⍨k⍴2}¨                     traslate in binary each element of  1..2^(k-1) and assign the result to n
          {∊⍵⊂w}¨                                for each binary element of n return the elemets of ⍵ in the place where there are the 1s
    b←⍺=+/¨                                       sum them and see if the sum is ⍺, that binary array saved in b
  ∨/                                     :⍸¨b/n   if or/b, get all the elements of n that are 1s for array b, and calculate each all indexs
                                               ⋄⍬ else return Zilde as void set
RosLuP
fuente
0

Pyth, 11 bytes

fqvzs@LQTyU

Pruébelo en línea aquí , o verifique todos los casos de prueba a la vez aquí .

fqvzs@LQTyUQ   Implicit: Q=input 1 (list of numbers), z=input 2 (target value, as string)
               Trailing Q inferred
          UQ   Generate range [0-<length of Q>)
         y     Powerset of the above
f              Keep elements of the above, as T, when the following is truthy:
      L T        Map elements of T...
     @ Q         ... to the indicies in Q
    s            Take the sum
 q               Is the above equal to...
  vz             z as an integer
               Implicit print of the remaining results
Sok
fuente