Subseqüências somadas máximas com itens não adjacentes


23

Introdução:

Inspirado por essas duas perguntas do SO (sem dúvida da mesma classe): imprima os elementos na sub -matriz de soma máxima sem elementos adjacentes java e Soma máxima de elementos não adjacentes de uma matriz, a serem impressos .

Desafio:

Dada uma lista de números inteiros, imprima uma subsequência que consiste em elementos não adjacentes que possuem a soma mais alta. Aqui estão alguns exemplos:

  • [1,2,3,-1,-3,2,5]resultaria em [1,3,5](com uma soma de 9) nos índices baseados em 0 [0,2,6].
  • [4,5,4,3]resultaria em [4,4](com uma soma de 8) nos índices baseados em 0 [0,2]ou [5,3](também com uma soma de 8) nos índices baseados em 0 [1,3].
  • [5,5,10,100,10,5]resultaria em [5,100,5](com uma soma de 110) nos índices baseados em 0 [0,3,5]ou [1,3,5].

O que é mais importante sobre esses exemplos acima, os índices que contêm os elementos estão pelo menos 2 separados um do outro. Se examinarmos o exemplo [5,5,10,100,10,5]mais detalhadamente: temos a seguinte subsequência potencial contendo itens não adjacentes; com seus índices abaixo dele; com suas somas abaixo disso:

[[5],[10],[100],[10],[5],[5],[100,5],[10,5],[10,10],[5,5],[5,10],[5,100],[5,5],[5,10],[5,100],[5,10],[5,100,5],[5,100,5],[5,10,5],[5,10,10]]   // non-adjacent subsequences
[[5],[ 4],[  3],[ 2],[1],[0],[  3,5],[ 2,5],[ 2, 4],[1,5],[1, 4],[1,  3],[0,5],[0, 4],[0,  3],[0, 2],[1,  3,5],[0,  3,5],[0, 2,5],[0, 2, 4]]   // at these 0-based indices
[  5,  10,  100,  10,  5,  5,    105,    15,     20,   10,    15,    105,   10,    15,    105,    15,      110,      110,      20,       25]   // with these sums
                                                                                                            ^         ^                        // and these two maximums

Como as somas máximas são 110, produzimos [5,100,5]como resultado.

Regras do desafio:

  • Você tem permissão para gerar pares de valores-chave do índice + valor. Portanto, em vez de [5,100,5]você pode produzir [[0,5],[3,100],[5,5]]ou [[1,5],[3,100],[5,5]]como resultado (ou [[1,5],[4,100],[6,5]]/ [[2,5],[4,100],[6,5]]quando a indexação baseada em 1 é usada em vez de baseada em 0).
    • Se você usar pares de valores-chave, eles também poderão estar em ordem reversa ou aleatória, pois fica claro quais valores são devidos ao índice pareado.
    • Não é permitido emitir apenas os índices sem valores. Deverá emitir os valores ou os valores / índices como pares de valores-chave (ou duas listas separadas para 'chaves' e 'valores' do mesmo tamanho se pares de valores-chave não forem possíveis no idioma de sua escolha).
  • Você tem permissão para gerar todas as subsequências possíveis com a soma máxima em vez de apenas uma.
  • Como você pode ver nos exemplos, a lista de entrada também pode conter valores negativos e duplicados. Você pode assumir que os números inteiros de entrada estão dentro do intervalo [999,999] .
  • A lista de saída não pode estar vazia e sempre deve conter pelo menos um elemento (se uma lista contiver apenas valores negativos, uma lista contendo o menor valor negativo mais baixo será exibida como resultado - consulte os dois últimos casos de teste).
  • Se houver uma saída possível, mas para vários índices diferentes, é permitido gerar os dois, mesmo que pareçam duplicados. (ou seja, o exemplo acima, pode gerar [[5,100,5],[5,100,5]]ambas as combinações possíveis de índices).

Casos de teste:

Input:                   Possible outputs:       At 0-based indices:     With sum:

[1,2,3,-1,-3,2,5]        [1,3,5]                 [0,2,6]                 9
[4,5,4,3]                [4,4]/[5,3]             [0,2]/[1,3]             8
[5,5,10,100,10,5]        [5,100,5]               [0,3,5]/[1,3,5]         110
[10]                     [10]                    [0]                     10
[1,1,1]                  [1,1]                   [0,2]                   2
[-3,7,4,-2,4]            [7,4]                   [1,4]                   11
[1,7,4,-2]               [7]                     [1]                     7
[1,2,-3,-4,5,6,-7]       [2,6]                   [1,5]                   8
[800,-31,0,0,421,726]    [800,726]/[800,0,726]   [0,5]/[0,3,5]/[0,2,5]   1526
[-1,7,8,-5,40,40]        [8,40]                  [2,4]/[2,5]             48
[-5,-18,-3,-1,-10]       [-1]                    [3]                     -1
[0,-3,-41,0,-99,-2,0]    [0]/[0,0]/[0,0,0]       [0]/[3]/[6]/[0,3]/
                                                  [0,6],[3,6]/[0,3,6]    0

Se houver mais de um conjunto idêntico (mas com índices diferentes), está tudo bem listar todos eles? por exemplo, [5,100,5]duas vezes para o seu terceiro exemplo.
Nick Kennedy

1
powerseté um conjunto de subconjuntos, não é? mas parece que você está retornando um conjunto de subsequências? [4,5,4,3] resultaria em [4,4] onde [4,4] claramente não é um conjunto.
Dados expirados

1
@ Arnauld Sim, se os valores são pares de valores-chave com seus índices, fica claro quais valores indexados são significados na entrada, para que possam estar em qualquer ordem. Também editará isso na descrição do desafio.
Kevin Cruijssen 17/04

2
Só para ter certeza: a saída dos índices não é uma opção, é?
Shaggy

1
O termo clássico é "subsequência" . Isso tem o mesmo problema de as pessoas pensarem em subsequências contíguas. Eu diria "subconjunto" se estivéssemos trabalhando com conjuntos aqui, mas essas são definitivamente sequências - assuntos de ordem e duplicatas são permitidos.
user2357112 suporta Monica 18/04

Respostas:


6

Casca , 11 bytes

►Σ†!¹mü≈tṖŀ

Experimente online!

Explicação

►Σ†!¹mü≈tṖŀ  Implicit input, say L=[4,5,3,4].
          ŀ  Indices: [1,2,3,4]
         Ṗ   Powerset: [[],[1],[2],[1,2],..,[1,2,3,4]]
        t    Tail (remove the empty list): [[1],[2],[1,2],..,[1,2,3,4]]
     m       For each,
      ü      de-duplicate by
       ≈     differing by at most 1.
             For example, [1,2,4] becomes [1,4].
  †          Deep map
   !¹        indexing into L: [[4],[5],[4],..,[5,4],[4,3]]
►            Maximum by
 Σ           sum: [5,4]

6

Haskell , 60 bytes

snd.([]%)
r%(h:t)=max(r%t)$(r++[h])%drop 1t
r%_=(sum r<$r,r)

Experimente online!

A função auxiliar %ramifica-se recursivamente na escolha de incluir o primeiro elemento e soltar o segundo ou de ignorar o primeiro elemento. Leva o máximo de todos os resultados, que são tuplas cujo primeiro elemento é a soma e cujo segundo elemento é a lista correspondente que é extraída para a saída.

Para lidar com a regra de que a lista vazia não é permitida, mesmo que tenha o menor truque, fazemos um truque simples de escrever em sum r<$rvez de sum r. Isso cria uma lista cujos elementos são todos sum re cujo comprimento é o de r. Dessa forma, quando escolhemos o máximo, priorizamos qualquer lista em vez de uma vazia r, mas as comparações dependem do primeiro elemento que é sum r.


6

R , 136 125 bytes

function(l,G=unlist(Map(combn,list(y<-seq(a=l)),y,c(function(x)'if'(all(diff(x)>1),l[x],-Inf)),F),F))G[which.max(Map(sum,G))]

Experimente online!

-6 bytes graças ao digEmAll , que aliás também me superou .

Retorna a subsequência mais curta como a list, quebrando os laços lexicograficamente primeiro pelos índices.

A força bruta gera todas as subsequências do índice e, em seguida, Filters para as que não são adjacentes, ou seja, onde all(diff(x)>1). Então subconjuntos [para lutilizar estes índices, seleccionando [[o primeiro onde a soma é o máximo (which.max ).

Tenho certeza de que esta é a primeira resposta R que eu já escrevi que usa Filter! triste, Filteré sem graça, não é de admirar que eu nunca tenha usado ...



@digEmAll thanks!
Giuseppe

5

05AB1E , 14 bytes

Guardado 1 byte graças a Kevin Cruijssen

ā<æʒĆ¥≠W}èΣO}θ

Experimente online! ou como um conjunto de testes

Explicação

ā<               # push [0 ... len(input)-1]
  æ              # compute powerset
   ʒ    }        # filter, keep lists where:
      ≠W         # no element is 1 in the
     ¥           # deltas
    Ć            # of the list with the head appended
         è       # index into the input with each
          ΣO}    # sort by sum
             θ   # take the last element

Você pode não estar feliz, mas ainda é 4 bytes menor que minha solução inicial. ;) E você pode jogar golfe mais 1 mudando ¤ªpara Ć.
Kevin Cruijssen 17/04

@KevinCruijssen: Oh sim! Por alguma razão, eu me convenci de que precisava de um elemento repetido no final. Obrigado!
Emigna 17/04

5

Braquilog (v2), 14 bytes

{~ba~c∋₁ᵐ}ᶠ+ᵒt

Experimente online!

Envio de função; entrada da esquerda, saída da direita, como de costume. Muito devagar; uma lista de cinco elementos é provavelmente o máximo para teste no TIO.

{~ba~c∋₁ᵐ}ᶠ+ᵒt
 ~b              Prepend an arbitrary element to the input
   a             Take a prefix or suffix of the resulting list
    ~c           Ordered partition into contiguous sublists
      ∋₁         Take the second element
        ᵐ          of each sublist
{        }ᶠ      Find all possible ways to do this
           +ᵒ    Sort by sum
             t   Take the greatest

Os resultados obtidos dos prefixos não estão incorretos, mas também não são interessantes; todos os resultados possíveis são gerados usando um sufixo (que é possivelmente a própria lista, mas não pode estar vazia), mas "sufixo" é mais detalhado no Brachylog do que "prefixo ou sufixo", por isso fui com a versão que é mais tersa (e menos eficiente, mas ainda correto). A idéia básica é que, para cada elemento que desejamos na lista de saída, a partição em sublistas contíguas precisa colocar esse elemento e o elemento antes na mesma sublist (porque o elemento é o segundoda sub-lista), portanto, dois elementos consecutivos não podem aparecer no resultado. Por outro lado, é bastante claro que qualquer lista sem dois elementos consecutivos pode aparecer no resultado. Assim, quando tivermos todas as listas de candidatos possíveis, podemos apenas pegar as somas de todas elas e ver qual é a maior.



3

JavaScript (ES6),  138 132 130 129  126 bytes

Emite pares de valores-chave.

a=>a.reduce((a,x,i)=>[...a,...a.map(y=>[[x,i],...y])],[[]]).map(m=a=>a.some(s=p=([v,i])=>p-(s=~~s+v,p=i)<2)|s<m||(r=a,m=s))&&r

Experimente online!

Passo 1

[value,index]

a.reduce((a, x, i) => // for each value x at position i:
  [                   //   update a[] to a new array consisting of:
    ...a,             //     all previous entries
    ...a.map(y =>     //     for each value y in a[]:
      [[x, i], ...y]  //       append [x, i], followed by all original entries
    )                 //     end of map()
  ],                  //   end of new array
  [[]]                //   start with a = [[]]
)                     // end of reduce()

Passo 2

mr

.map(m =              // initialize m to a non-numeric value
  a =>                // for each entry a[] in the powerset:
  a.some(s = p =      //   initialize s and p to non numeric values
    ([v, i]) =>       //   for each value v and each index i in a[]:
    p - (             //     compute p - i
      s = ~~s + v,    //     add v to s
      p = i           //     update p to i
    ) < 2             //     if p - i is less than 2, yield true
  ) |                 //   end of some()
  s < m ||            //   unless some() was truthy or s is less than m,
  (r = a, m = s)      //   save a[] in r[] and update m to s
) && r                // end of map(); return r[]

3

Haskell, 81 80 bytes

snd.maximum.map((,)=<<sum).tail.f
f(a:b:c)=f(b:c)++map(a:)(f c)
f a=[]:map(:[])a

Experimente online!

fcria todas as subsequências válidas pulando o próximo elemento ( f(b:c)) ou usando-o e pulando o próximo ( map(a:)(f c)) e trabalhando recursivamente no resto. Para o resultado, construa todas as subsequências ( f), descarte a subsequência vazia (que ocorre primeiro na lista tail:), faça pares (<sum>,<subsequence>)( map((,)=<<sum)), encontre o máximo (os pares são comparados em ordem lexicográfica) -> maximum) e solte a soma ( snd).

Edit: -1 byte graças a @Lynn.


1
map(:[])aé um byte menor que (pure<$>a)^^
Lynn


3

T-SQL, 122 119 118 bytes

Entrada é uma variável de tabela.

Essa consulta seleciona todos os elementos da variável da tabela, combinando-os com todos os elementos não adjacentes com valores de posição mais altos e mostra o texto gerado para a soma mais alta desses valores.

WITH C(y,j,v)as(SELECT*,x*1FROM @
UNION ALL
SELECT y+','+x,i,v+x
FROM @ JOIN C ON~-i>j)SELECT
TOP 1y FROM C ORDER BY-v

Experimente on-line sem limites



2

Pitão, 19 bytes

esDm@LQdtf!q#1.+TyU

Experimente online aqui ou verifique todos os casos de teste de uma vez aqui .

esDm@LQdtf!q#1.+TyUQ   Implicit: Q=eval(input())
                       Trailing Q inferred
                  UQ   Generate range [0-len(Q))
                 y     Take the powerset of the above
         f             Filter keep elements of the above, as T, using:
              .+T        Take differences of consecutive elements of T
           q#1           Keep those differences equal to 1
          !              Logical NOT - empty lists evaluate to true, populated ones to false
                       Result of the filter is those sets without consecutive numbers
        t              Drop the first element (empty set)
   m                   Map the remaining sets, as d, using:
     L d                 For each element of d...
    @ Q                  ... get the element in Q with that index
 sD                    Order the sets by their sum
e                      Take the last element, implicit print

2

Gaia , 24 bytes

e:w;ċz⟨ọ1>¦ẏ⟩⁇‼⁇E‡ev2%Σ⌠

Experimente online!

Ugh, E‡faz algumas coisas estranhas ... de acordo com a documentação, ele deve fazer algo como "determinado iconjunto de listas de Xcomprimento e jconjunto de índices de comprimento Y, return X[i][Y[j]]", mas retorna [X[i][Y[j]] X[i][Y[-j]]onde a indexação negativa representa o complemento, então temos que fazer ev2%para extrair apenas os que queremos.

e				| eval as a list l
 :				| dup
  w				| wrap as a list
   ;				| push l again
    ċ				| push [1..len(l)]
     z				| push all subsets of [1..len(l)] -- index powerset.
      ⟨      ⟩⁇			| filter this for:
       ọ			| deltas
        1>¦			| are greater than 1
           ẏ			| all (all deltas greater than 1)
	       ‼⁇		| filter for non-empty lists
		 E‡		| table extract elements. Given l and index set i, this pushes
				| [l[i] l[setdiff(1..l,i)]] for some reason
		   ev2%		| get the l[i] only by unlisting, reversing, and taking every other element
		       Σ⌠	| Get the one with the maximum sum

Por curiosidade, por que a saída tem duas à direita em ]]vez de uma?
Kevin Cruijssen 18/04

@KevinCruijssen Apenas mais uma peculiaridade divertida do intérprete; todas as listas são impressas assim, então [[1] [2]]são impressas, o [[1]] [2]]]]que dificulta a leitura / depuração da lista.
Giuseppe

Eu acho que é por causa da expressão re.sub(" ?$","]",result)no intérprete que deveria ser, re.sub(" +$","]",result)mas meu python é super ruim.
Giuseppe

2

R , 108 107 bytes

function(v,M=-Inf){for(j in J<-seq(a=v))for(i in combn(J,j,,F))if(all(diff(i)>1)&sum(v[i])>sum(M))M=v[i]
M}

Experimente online!

-1 graças a @Giuseppe


2

Wolfram Language (Mathematica) , 70 63 bytes

MaximalBy[Select[q=Rest@Subsets@#,!FreeQ[q,#~Riffle~_]&],Tr,1]&

Experimente online!

Pesquisa de alto nível

          Select[q=Rest@Subsets@#,                     ]        (*choose nonempty subsets of the input such that*)
                                  !FreeQ[q,          ]&         (*there exists a subset of the input which matches*)
                                           #~Riffle~_           (*this list, with an item inserted between adjacent elements*)
MaximalBy[                                              ,Tr,1]& (*and return one with the greatest total*)

,1é necessário para não retornar inadvertidamente conjuntos inválidos (caso contrário, por exemplo, uma entrada de {1,1,1}resultaria em uma saída de {{1,1},{1,1},{1,1}})


1

Haskell , 300 168 bytes

import Data.List
h[]=1>2
h(x:y)=fst$foldl(\a c->((fst a)&&(c-snd a>1),c))(1<2,x)y
z=snd.last.sortOn fst.map((,)=<<sum.snd).filter(h.fst).map unzip.subsequences.zip[0..]

Experimente online!

-132 bytes, graças a todos os comentários de @nimi :)


Original

Ungolfed (original)

import Data.List
import Data.Function

f :: [Int] -> [(Int, Int)] -- attach indices for later use
f [] = []
f xs = zip xs [0..length xs]

g :: [[(Int, Int)]] -> [([Int], [Int])] -- rearrange into list of tuples
g [] = []
g (x:xs) = (map fst x, map snd x) : g xs

h :: [Int] -> Bool -- predicate that checks if the indices are at least 2 apart from each other
h [] = False
h (x:xs) = fst $ foldl (\acc curr -> ((fst acc) && (curr - snd acc > 1), curr)) (True, x) xs
j :: [([Int], [Int])] -> [([Int], [Int])] -- remove sets that don't satisfy the condition
j xs = filter (\(elements, indices) -> h indices) xs

k :: [([Int], [Int])] -> [(Int, ([Int], [Int]))] -- calculate some of elements
k xs = map (\(elements, indices) -> (foldl1 (+) elements, (elements, indices))) xs

l :: [(Int, ([Int], [Int]))] -> ([Int], [Int]) -- grab max
l xs = snd $ last $ sortBy (compare `on` fst) xs

z -- put things together
```

1
Algumas dicas: virar o elemento e seu índice dentro dos pares retornados por f: f x=zip[0..length x]x, então ftorna-se f=zip[0..]. gé justo g=map unzip. A função com a qual filtrar jé h.fst(<- pares invertidos!). j=filter(h.fst). O foldl1+from ké sume com um par sem pontos k=map((,)=<<sum.snd). sortBy(...)pode ser substituído por sortOn fst: l=snd.last.sortOn fst. Finalmente, como você está usando todas as funções apenas uma vez, é possível incorporá-las em uma única expressão sem pontos:z=snd.last.sortOn fst.map((,)=<<sum.snd).filter(h.fst).map unzip.subsequences.zip[0..]
nimi


Ah, e não há mais necessidade de importar Data.Function.
nimi 17/04

Isso é ótimo, obrigado pelo feedback :)
bugs

A seguir h: procuramos elementos não adjacentes, ou seja, a diferença de índices adjacentes deve ser >1. zipWith(-)=<<tailcria uma lista dessas diferenças, mas falha na lista vazia, por isso precisamos de mais uma tailpara nos subsequenceslivrarmos dela. Inline novamente. Experimente online!
nimi 17/04

1

Carvão , 46 bytes

≔⟦υ⟧ηFθ«≔υζ≔Eη⁺κ⟦ι⟧υ≔⁺ζηη»≔Φ⁺υηιη≔EηΣιζI§η⌕ζ⌈ζ

Experimente online! Link é a versão detalhada do código. Explicação:

≔⟦υ⟧η

A variável ué predefinida com uma lista vazia. Isso é colocado em uma lista à qual está atribuído h. Essas variáveis ​​atuam como acumuladores. ucontém as sublistas que incluem o elemento mais recente da entrada, qenquanto hcontém as sublistas que não (e, portanto, são adequadas para anexar o próximo elemento da entrada).

Fθ«

Faça um loop sobre os elementos da entrada.

≔υζ

Salve a lista de sublistas que contêm o elemento anterior.

≔Eη⁺κ⟦ι⟧υ

Pegue todas as sublistas que não contêm o elemento anterior, acrescente o elemento atual e salve o resultado como a lista de sublistas que contêm o elemento atual. (Eu não uso Pushaqui, pois preciso clonar a lista.)

≔⁺ζηη»

Concatene as duas sublistas anteriores na nova lista de sublistas que não contêm o elemento atual.

≔Φ⁺υηιη

Concatene as sublistas uma última vez e remova a lista vazia original (que o carvão vegetal não pode somar de qualquer maneira).

≔EηΣιζ

Calcule as somas de todas as sublistas.

I§η⌕ζ⌈ζ

Encontre um índice da maior soma e produza a sub-lista correspondente.



1

Japt -h , 21 bytes

Já teve um daqueles desafios em que você esquece completamente como jogar golfe ?!

ð¤à fÊk_än ø1îmgUÃñx

Tente

ð¤à fÊk_än ø1îmgUÃñx     :Implicit input of array U
ð                         :Indices of elements that return true when
 ¤                        :  Converted to a base-2 string (to account for 0s)
  à                       :Combinations
    f                     :Filter by
     Ê                    :  Length (to remove the empty combination)
      k_                  :Remove elements that return true
        än                :  Deltas
           ø1             :  Contains 1
             Ã            :End remove
              ®           :Map
               m          :  Map
                gU        :    Index into U
                  Ã       :End map
                   ñ      :Sort by
                    x     :  Sum
                          :Implicit output of last element

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.