Максимально підсумовані підпункти з суміжними елементами


23

Вступ:

Натхненний цими двома питаннями SO (без сумніву, того ж класу): друкуйте елементи в підматриті максимальної суми без суміжних елементів java та Максимальної суми суміжних елементів масиву для друку .

Виклик:

Враховуючи список цілих чисел, виведіть підряд, що складається з суміжних елементів, які мають найбільшу суму. Ось кілька прикладів:

  • [1,2,3,-1,-3,2,5]призведе до [1,3,5](з сумою 9) при 0-індексах [0,2,6].
  • [4,5,4,3]призведе до або [4,4](із сумою 8) при 0-індексах, [0,2]або [5,3](також із сумою 8) при 0-індексах [1,3].
  • [5,5,10,100,10,5]призведе до [5,100,5](із сумою 110) або на 0-індексах, [0,3,5]або [1,3,5].

Що найважливіше в цих прикладах, наведених вище, показники, що містять елементи, розташовані як мінімум на відстані один від одного. Якщо ми розглянемо приклад [5,5,10,100,10,5]більш глибоко: у нас є наступна потенційна послідовність, що містить не сусідні елементи; з їх індексами нижче; з їх сумами нижче, ніж:

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

Оскільки максимальні суми є 110, ми виводимо [5,100,5]як результат.

Правила виклику:

  • Вам дозволяється виводити пари ключ-значення індексу + значення. Тож замість [5,100,5]вас можна вивести [[0,5],[3,100],[5,5]]або [[1,5],[3,100],[5,5]]як результат (або [[1,5],[4,100],[6,5]]/ [[2,5],[4,100],[6,5]]коли використовується індексація на основі 1, а не 0).
    • Якщо ви використовуєте пари ключ-значення, вони також можуть бути в зворотному або випадковому порядку, оскільки зрозуміло, які значення мають на увазі парний індекс.
    • Виведення лише індексів без значень заборонено. Він повинен або виводити значення, або значення / індекси як пари ключів-значень (або два розділені списки для 'ключів' і 'значень' одного розміру, якщо пари ключових значень неможливі у вашій вибраній мові).
  • Вам дозволяється виводити всі можливі послідовності з максимальною сумою замість лише однієї.
  • Як видно з прикладів, вхідний список також може містити негативні та дублювані значення. Можна припустити, що вхідні цілі числа знаходяться в межах [999,999] .
  • Список вихідних даних не може бути порожнім і завжди повинен містити щонайменше один елемент (якщо список міститиме лише негативні значення, тоді список, що містить одне найменше негативне значення, буде виведено як результат - див. Останні два тестові випадки).
  • Якщо є один можливий вихід, але для декількох різних індексів, дозволено виводити їх обох, навіть якщо вони можуть виглядати дублікатами. (тобто наведений вище приклад може виводитись [[5,100,5],[5,100,5]]для обох можливих комбінацій індексів).

Тестові приклади:

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

Якщо є декілька однакових наборів (але з різних індексів), чи добре їх перелічити? наприклад, [5,100,5]двічі для вашого третього прикладу.
Нік Кеннеді

1
powersetце набір підмножин чи не так? але схоже, що ви повертаєте набір підзаконних даних? [4,5,4,3] призведе до будь-якого [4,4], де [4,4] явно не є набором.
Термін дії придатності минув

1
@Arnauld Так, якщо значення є парами ключ-значення з їх індексом, зрозуміло, які індексовані значення мають на увазі вхідні дані, тому вони можуть бути в будь-якому порядку. Також буде редагувати це в описі виклику.
Кевін Круїссен

2
Просто для впевненості: виведення індексів не є варіантом, чи не так?
Кудлатий

1
Класичний термін - «підпорядкування» . У цій же проблемі є і люди, які думають про суміжні підпорядкування. Я б сказав "підмножина", якби ми насправді працювали з наборами тут, але це безумовно послідовності - питання порядку та дублікатів дозволені.
user2357112 підтримує Моніку

Відповіді:


6

Лушпиння , 11 байт

►Σ†!¹mü≈tṖŀ

Спробуйте в Інтернеті!

Пояснення

►Σ†!¹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 байт

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

Спробуйте в Інтернеті!

Хелперна функція %рекурсивно розгалужується на вибір, чи включати перший елемент і відкинути другий, або пропустити перший елемент. Він бере максимум усіх результатів, це кортежі, першим елементом яких є сума, а другий елемент - відповідний список, який витягується для виводу.

Щоб впоратися з правилом, що порожній список заборонений, навіть якщо він би мав найменший трюк, ми робимо милий трюк написання, sum r<$rа не sum r. Це складає список, усі елементи якого є sum rі чия довжина r. Таким чином, коли ми вибираємо максимум, ми визначаємо пріоритетність будь-якого списку перед порожнім r, але в іншому випадку порівняння залежать від першого елемента, який є sum r.


6

R , 136 125 байт

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

Спробуйте в Інтернеті!

-6 байт завдяки digEmAll , який до речі також перевершив мене .

Повертає найкоротшу послідовність як list , розриваючи зв'язки на лексикографічно спочатку за показниками.

Брут-сила генерує всі індекси підрядів, потім Filters для тих, які не є суміжними, тобто де all(diff(x)>1). Тоді підмножини [в lвикористанні цих індексів, вибираючи [[першу , де сума є макс ( which.max).

Я впевнений, що це перша відповідь, яку я коли-небудь писав, що використовує Filter! сумно, Filterє незнімним, недарма я ніколи його не використовував ...



@digEmВсі спасибі!
Джузеппе

5

05AB1E , 14 байт

Збережено 1 байт завдяки Kevin Cruijssen

ā<æʒĆ¥≠W}èΣ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

Можливо, ви не задоволені, але це все-таки на 4 байти коротше мого початкового рішення. ;) А ви можете гольф-більш зміни ¤ªдо Ć.
Кевін Круїссен

@KevinCruijssen: О так! Я чомусь переконав себе, що мені потрібен елемент повторення наприкінці. Спасибі!
Емінья

5

Брахілог (v2), 14 байт

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

Спробуйте в Інтернеті!

Подання функції; вхід зліва, вихід праворуч, як зазвичай. Дуже повільно; п'ятиелементний список, мабуть, максимум для тестування на 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

Результати, які ми отримуємо з префіксів, є невірними, але також не цікавими; всі можливі результати генеруються за допомогою взяття суфікса (який, можливо, є самим списком, але не може бути порожнім), але "суфікс" у Brachylog є більш багатослівним, ніж "префікс або суфікс", тому я пішов із версією, яка є більш короткою (і менше ефективний, але все-таки правильний). Основна ідея полягає в тому, що для кожного елемента, який ми хочемо у списку вихідних даних, розділ на суміжні підлісти повинен розміщувати цей елемент і елемент раніше в одному підписі (тому що елемент є другимелемент підспису), тому два результати поспіль не можуть відображатися в результаті. З іншого боку, цілком зрозуміло, що в результаті може з’явитися будь-який список без двох послідовних елементів. Отже, як тільки ми маємо всі можливі списки кандидатів, ми можемо просто взяти суми всіх і побачити, який із них найбільший.



3

JavaScript (ES6),  138 132 130 129  126 байт

Виводить пари ключ-значення.

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

Спробуйте в Інтернеті!

Крок 1

[vалуе,iнгех]

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

Крок 2

мr

.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

Хаскелл, 81 рік 80 байт

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

Спробуйте в Інтернеті!

fбудує всі дійсні послідовності, або пропускаючи наступний елемент ( f(b:c)), або використовуючи його, і пропускаючи наступний ( map(a:)(f c)), і рекурсивно працювати над рештою. Для результату побудуйте всі підпослідовності ( f), випустіть порожню підпорядкованість (що відбувається першим у списку tail:), зробіть пари (<sum>,<subsequence>)(map((,)=<<sum) ), знайдіть максимум (пари порівнюються в лексикографічному порядку) -> maximum) і опустіть суму (snd ).

Редагувати: -1 байт завдяки @Lynn


1
map(:[])a- байт коротший ніж (pure<$>a)^^
Лінн


3

T-SQL, 122 119 118 байт

Введення - це змінна таблиця.

Цей запит вибирає всі елементи зі змінної таблиці, поєднуючи їх із усіма суміжними елементами з більш високими значеннями позиції та показує текст, сформований для найбільшої суми цих значень.

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

Спробуйте його в режимі он-лайн, що не має волі



2

Pyth, 19 байт

esDm@LQdtf!q#1.+TyU

Спробуйте в Інтернеті тут або одразу підтвердіть усі тестові випадки тут .

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

Гая , 24 байти

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

Спробуйте в Інтернеті!

Тьху, E‡роблять деякі дивні речі ... в відповідно до документації, він повинен зробити що - щось на зразок «заданою довжиною iбезлічі списків Xі довжиною jнабору індексів Y, повернення X[i][Y[j]]», але замість цього повертається , [X[i][Y[j]] X[i][Y[-j]]де негативне індексування представляє додаток, так що ми повинні зробити , ev2%щоб витягувати лише ті, що ми хочемо.

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

Чому з цікавості, чому на виході є два трейлінгу ]]замість одного?
Кевін Круїссен

@KevinCruijssen Ще одна весела примха перекладача; всі списки роздруковуються так, тому [[1] [2]]надруковується, [[1]] [2]]]]що робить його дуже важким для читання / налагодження виводу списку.
Джузеппе

Я думаю, це через вираження re.sub(" ?$","]",result)в інтерпретаторі, яке натомість має бути, re.sub(" +$","]",result)але мій пітон дуже поганий.
Джузеппе


2

Мова Вольфрама (Mathematica) , 70 63 байт

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

Спробуйте в Інтернеті!

Пошук на високому рівні

          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Потрібно, щоб не випадково повернути недійсні набори (інакше, наприклад, введення в {1,1,1}результаті призведе до виведення {{1,1},{1,1},{1,1}})


1

Haskell , 300 168 байт

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..]

Спробуйте в Інтернеті!

-132 байти дякую за всі відгуки від @nimi :)


Оригінал

Безлічі (оригінал)

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
Деякі поради: переверніть елемент та його індекс у парах, повернених f:, f x=zip[0..length x]xтак fстає f=zip[0..]. gпросто g=map unzip. Функція для фільтрації в jє h.fst(<- перевернуті пари!). j=filter(h.fst). foldl1+Від kце sumі з pointfree пари рішень k=map((,)=<<sum.snd). sortBy(...)може бути замінений на sortOn fst: l=snd.last.sortOn fst. Нарешті, оскільки ви використовуєте всі функції лише один раз, ви можете вкласти їх у єдиний виразний вираз:z=snd.last.sortOn fst.map((,)=<<sum.snd).filter(h.fst).map unzip.subsequences.zip[0..]
nimi


о, і більше не потрібно імпортувати Data.Function.
німі

Це чудово, дякую за відгуки :)
помилки

Далі h : ми шукаємо не сусідні елементи, тобто різниця суміжних індексів повинна бути >1. zipWith(-)=<<tailбудує такий список відмінностей, але не виконується для порожнього списку, так що нам потрібно додатково tailна , subsequencesщоб позбутися від нього. Інлайн знову. Спробуйте в Інтернеті!
німі

1

Вугілля деревне , 46 байт

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

≔⟦υ⟧η

Змінна uзаздалегідь визначена з порожнім списком. Це міститься у списку, якому призначено h. Ці змінні виконують роль акумуляторів. uмістить підсписки, які містять останній елемент введення, в qтой час як hмістять підлісти, які цього не роблять (і тому придатні для додавання наступного елемента введення).

Fθ«

Проведіть петлю над елементами вводу.

≔υζ

Збережіть список підсписів, що містять попередній елемент.

≔Eη⁺κ⟦ι⟧υ

Візьміть усі підлісти, які не містять попереднього елемента, додайте поточний елемент і збережіть результат у списку підсписок, що містять поточний елемент. (Я не використовую Pushтут, як мені потрібно клонувати список.)

≔⁺ζηη»

Об’єднайте обидва попередні підсистеми в новий список підсписок, які не містять поточного елемента.

≔Φ⁺υηιη

Останнє з'єднання списків і видаліть оригінальний порожній список (який Деревне вугілля все одно не може підсумовувати).

≔EηΣιζ

Обчисліть суми всіх списків.

I§η⌕ζ⌈ζ

Знайдіть індекс найбільшої суми та виведіть відповідний підпис.



1

Japt -h , 21 байт

У вас колись є одне з тих викликів, коли ви зовсім забуваєте грати в гольф ?!

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

Спробуй це

ð¤à 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.