Gere combinações que somam um valor alvo

14

Desafio

Suponha que você tenha uma lista de números e um valor alvo. Encontre o conjunto de todas as combinações de seus números que somam o valor alvo, retornando-os como índices da lista.

Entrada e saída

A entrada terá uma lista de números (não necessariamente exclusivos) e um número de soma de destino. A saída será um conjunto de listas não vazias, cada lista contendo valores inteiros correspondentes à posição dos valores na lista de entrada original.

Exemplos

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: [ ]

Pontuação

Isso é , então o código mais curto vence!

soapergem
fonte
6
Relacionado , possivelmente um idiota.
Giuseppe
Eu acho que isso é uma bobagem, mas eu prefiro fechar a mais antiga porque está desatualizada.
Post Rock Garf Hunter
4
Os números de ponto flutuante realmente acrescentam algo ao desafio? Não sei ao certo qual é o consenso, mas eles provavelmente levarão a erros de precisão em vários idiomas.
Arnauld
Eu pretendia permitir pontos flutuantes, sim
soapergem
14
Bleh, índices? Eu acho que seria um desafio melhor retornar uma lista de valores, embora eu ache que isso levanta uma questão de como os valores repetidos são tratados em subconjuntos.
Xnor

Respostas:

3

Casca , 10 bytes

ηλfo=¹ṁ⁰tṖ

1 indexado. Experimente online!

Explicação

ηλ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.

Isso usa a mais recente adição ao Husk η(agir sobre índices). A idéia é ηpegar uma função de ordem superior α(aqui a função lambda embutida) e uma lista xe chamarα a função de indexação de x(que está no programa acima) e os índices de x. Por exemplo, ṁ⁰pega um subconjunto de índices, mapeia a indexação xsobre eles e soma os resultados.

Zgarb
fonte
9

JavaScript (ES6), 96 bytes

Recebe entrada na sintaxe de currying (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 teste

Isso falharia no segundo caso de teste se 4,8 e 10 fossem trocados devido a um erro de precisão IEEE 754 - ou seja, 14.8 - 4.8 - 10 == 0mas 14.8 - 10 - 4.8 != 0. Eu acho que isso está bem , embora possa haver uma referência mais relevante em algum lugar na 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
fonte
7
Não um, mas dois reduces? Eu tenho que aprovar isso.
Neil
1
@ Neil O menos conhecido "reduzirMapReduce"
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]

Experimente online!

Chas Brown
fonte
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}

Experimente online!

1 indexado.

combngeralmente retorna a matrix, mas a configuração simplify=Fretorna a em listvez disso, permitindo que nós cgeremos todos os resultados juntos. combn(I,i,,F)retorna todas as combinações de índices e levamos N(l,i,sum)==kcomo um índice para essa lista para determinar aqueles que são iguais k.

Giuseppe
fonte
7

J , 32 31 bytes

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

Experimente online!

                  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
fonte
Eu me sinto como uma definição explícita ajudaria dado todas as composições, mas infelizmente eu só tenho o mesmo comprimento: 4 :'<@I.t#~x=1#.y#~t=.#:}.i.2^#y'. Experimente online!
cole
5

Japonês , 14 bytes

m, à f_x!gU ¥V

Teste online!

Como 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
fonte
Bom truque com m,. Eu tinha Êo à k@VnXx@gXpela mesma contagem de bytes.
Salsicha
5

Limpo , 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]

Experimente online!

Furioso
fonte
[1, 2, -1, 5] 0 --> [[],[2,0]]É necessário um conjunto de listas não vazias.
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]]

Experimente online!

Cristian Lupascu
fonte
[1, 2, -1, 5]#0 --> [[],[0,2]]É necessário um conjunto de listas não vazias.
FrownyFrog
@FrownyFrog Thanks! Fixo.
Cristian Lupascu
4

Gelatina , 11 bytes

ị³S=
JŒPçÐf

Experimente online!

1 indexado. 4 bytes gastos no retorno de índices, em vez de apenas nos próprios elementos.

-1 byte graças a user202729
-1 byte graças a Jonathan Allan

HyperNeutrino
fonte
12 bytes
user202729
@ user202729 Legal, obrigado!
HyperNeutrino
1
-1 byte: é desnecessário se você usar em çvez de Ç.
Jonathan Allan
@JonathanAllan o good catch thanks!
precisa saber é o seguinte
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*

Experimente online!

Indexado a 0. 44 bytes gastos no retorno de índices em vez de apenas nos próprios elementos.

HyperNeutrino
fonte
2

Braquilog , 18 15 bytes

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

Experimente online!

-3 bytes, porque agora funciona como um gerador . (Provavelmente é possível jogar mais, mas contornar a necessidade de usar índices é complicado).

    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.
String não relacionada
fonte
hiᶠ⊇z+ʰXh~t?∧Xtsai com o mesmo comprimento.
String não relacionada
1

Perl 6 , 45 bytes

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

Teste-o

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
fonte
1

APL (NARS), 49 caracteres, 98 bytes

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

Indexado 1; teste:

  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│
└~┘

Comente:

{∨/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
fonte
0

Pitão, 11 bytes

fqvzs@LQTyU

Experimente on-line aqui ou verifique todos os casos de teste de uma vez aqui .

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
fonte