Нульова сума покриттів


38

Вступ

Розглянемо не порожній список L цілих чисел. З нульовою сумою зріз з L являє собою безперервну підпослідовність L , сума яких дорівнює 0. Наприклад, [1, -3, 2] є нульовою сумою зріз [-2, 4, 1, -3, 2, 2 , -1, -1] , але [2, 2] це не (тому що це не дорівнює 0), і ні [4, -3, -1] (тому що це не є суміжним).

Колекція фрагментів з нульовою сумою L є кришкою з нульовою сумою L, якщо кожен елемент належить принаймні одному з фрагментів. Наприклад:

L = [-2, 4, 1, -3, 2, 2, -1, -1]
A = [-2, 4, 1, -3]
B =        [1, -3, 2]
C =                  [2, -1, -1]

Три з нульовою сумою нарізає , В і С утворюють з нульовою сумою кришку L . Кілька копій одного фрагмента можуть відображатися в обкладинці з нульовою сумою, наприклад, така:

L = [2, -1, -1, -1, 2, -1, -1]
A = [2, -1, -1]
B =        [-1, -1, 2]
C =                [2, -1, -1]

Звичайно, не всі списки мають нульову суму; деякі приклади: [2, -1] (кожен фрагмент має ненульову суму) та [2, 2, -1, -1, 0, 1] (крайній лівий 2 не є частиною нульового зрізу).

Завдання

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

Ви можете написати повну програму або функцію, і найнижча кількість байтів виграє.

Тестові справи

[-1] -> False
[2,-1] -> False
[2,2,-1,-1,0,1] -> False
[2,-2,1,2,-2,-2,4] -> False
[3,-5,-2,0,-3,-2,-1,-2,0,-2] -> False
[-2,6,3,-3,-3,-3,1,2,2,-2,-5,1] -> False
[5,-8,2,-1,-7,-4,4,1,-8,2,-1,-3,-3,-3,5,1] -> False
[-8,-8,4,1,3,10,9,-11,4,4,10,-2,-3,4,-10,-3,-5,0,6,9,7,-5,-3,-3] -> False
[10,8,6,-4,-2,-10,1,1,-5,-11,-3,4,11,6,-3,-4,-3,-9,-11,-12,-4,7,-10,-4] -> False
[0] -> True
[4,-2,-2] -> True
[2,2,-3,1,-2,3,1] -> True
[5,-3,-1,-2,1,5,-4] -> True
[2,-1,-1,-1,2,-1,-1] -> True
[-2,4,1,-3,2,2,-1,-1] -> True
[-4,-1,-1,6,3,6,-5,1,-5,-4,5,3] -> True
[-11,8,-2,-6,2,-12,5,3,-7,4,-7,7,12,-1,-1,6,-7,-4,-5,-12,9,5,6,-3] -> True
[4,-9,12,12,-11,-11,9,-4,8,5,-10,-6,2,-9,10,-11,-9,-2,8,4,-11,7,12,-5] -> True

Якщо "кожен елемент належить до одного з фрагментів", чи трактуєте ви одне і те ж значення за різними показниками як виразні?
ngenisis

@ngenisis Так, вони виразні, і кожен має відбуватися у фрагменті, що містить відповідний індекс.
Згарб

2
Чи не повинен третій [2,2,-1,-1,0,1] -> Falseфальшивий приклад бути правдоподібним, оскільки обидва фрагменти [2,-1,-1]і [-1,0,1]додають до нуля, а всі їх елементи знаходяться в первинному списку?
dfernan

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

Зрозумів. Це ускладнює. : o)
dfernan

Відповіді:


11

Желе , 13 12 байт

JẆịS¥ÐḟċþJḄẠ

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

Як це працює

JẆịS¥ÐḟċþJḄẠ  Main link. Argument: A (array)

J             Yield all indices of A.
 Ẇ            Window; yield all slices of indices.
     Ðḟ       Filter; keep slices for which the link to the left returns 0.
    ¥           Combine the two atoms to the left into a dyadic chain.
  ị               Retrieve the elements of A at the slice's indices.
   S              Take the sum.
         J    Yield the indices of A.
       ċþ     Count table; count how many times each index appears in each table.
          Ḅ   Unbinary; convery the array of counts of each index from base 2 to 
              integer. This yields 0 iff an index does not appear in any slice.
           Ạ  All; return 1 iff all integers are non-zero.

9

Математика, 66 65 байт

Зберегли 1 байт і, сподіваємось, навчилися нового трюку на майбутнє, завдяки ngenisis!

Дві однакові довгі альтернативи, обидві - це неназвані функції, що беруть список цілих чисел як вхідні та повертаючі Trueабо False:

And@@Table[0==Product[Tr@#[[i;;j]],{i,k},{j,k,l}],{k,l=Tr[1^#]}]&

0==Norm@Table[Product[Tr@#[[i;;j]],{i,k},{j,k,l}],{k,l=Tr[1^#]}]&

В обох випадках Tr@#[[i;;j]]обчислюється сума зрізу введення з позиції iв позицію j(1-індексується). Product[...,{i,k},{j,k,l}]множимо разом усі ці зрізні суми, як iдіапазони над індексами, які є максимум, kі jдіапазони над показниками, що принаймні k. (Зверніть увагу, що l=Tr[1^#]визначається lяк сума 1всіх повноважень у вхідному списку, яка є просто довжиною списку.) Іншими словами, цей добуток дорівнює 0, якщо і лише тоді, коли цей kелемент належить до нульової суми .

У першій версії кожен із цих продуктів порівнюється 0і And@@повертається Trueточно тоді, коли кожен окремий продукт дорівнює 0. У другій версії список продуктів діє функцією Norm(довжина l-вимірного вектора), яка дорівнює, 0якщо і лише тоді, коли кожен запис дорівнює 0.


1
Tr[1^#]рятує 1байт від Length@#.
ngenisis

Чи 0^працювали б замість цього 0==? Не впевнений, як Mathematica справляється з цим. (ви повернетесь 1/ 0замість true/ false)
Cyoce

1
Класна ідея, але Mathematica повертається Indeterminateза 0^0. Крім того, 1/ 0насправді не є правдою / фальшивістю в Mathematica - це занадто сильно набрано, щоб зробити гольфістів щасливими :)
Грег Мартін

7

Математика, 65 64 байт

Завдяки ngenisis за збереження 1 байта.

Union@@Cases[Subsequences[x=Range@Tr[1^#]],a_/;Tr@#[[a]]==0]==x&

Я скоріше знайду рішення, що відповідає чистому шаблону, але воно виявляється складним (і такі речі {___,a__,___}завжди супер тривалі).


4

Haskell, 94 байти

import Data.Lists
g x=(1<$x)==(1<$nub(id=<<[i|(i,0)<-fmap sum.unzip<$>powerslice(zip[1..]x)]))

Приклад використання: g [-11,8,-2,-6,2,-12,5,3,-7,4,-7,7,12,-1,-1,6,-7,-4,-5,-12,9,5,6,-3] -> True.

Як це працює (давайте використовувати [-1,1,5,-5]для введення):

        zip[1..]x  -- zip each element with its index
                   -- -> [(1,-1),(2,1),(3,5),(4,-5)]
      powerslice   -- make a list of all continuous subsequences
                   -- -> [[],[(1,-1)],[(1,-1),(2,1)],[(1,-1),(2,1),(3,5)],[(1,-1),(2,1),(3,5),(4,-5)],[(2,1)],[(2,1),(3,5)],[(2,1),(3,5),(4,-5)],[(3,5)],[(3,5),(4,-5)],[(4,-5)]]
    <$>            -- for each subsequence
   unzip           --   turn the list of pairs into a pair of lists
                   --   -> [([],[]),([1],[-1]),([1,2],[-1,1]),([1,2,3],[-1,1,5]),([1,2,3,4],[-1,1,5,-5]),([2],[1]),([2,3],[1,5]),([2,3,4],[1,5,-5]),([3],[5]),([3,4],[5,-5]),([4],[-5])]
  fmap sum         --   and sum the second element
                   --   -> [([],0),([1],-1),([1,2],0),([1,2,3],5),([1,2,3,4],0),([2],1),([2,3],6),([2,3,4],1),([3],5),([3,4],0),([4],-5)]
 [i|(i,0)<-    ]   -- take all list of indices where the corresponding sum == 0
                   -- -> [[],[1,2],[1,2,3,4],[3,4]]
 id=<<             -- flatten the list
                   -- -> [1,2,1,2,3,4,3,4]
nub                -- remove duplicates
                   -- -> [1,2,3,4]

(1<$x)==(1<$    )  -- check if the above list has the same length as the input list. 

powersliceтака велика назва функції.
Згарб


3

J, 36 35 байт

#\*/@e.[:;]({:*0=[:+/{.)@|:\.\@,.#\

Для кожного subum я додаю індекси елементів і зберігаю індекси iff subsum є, 0а потім перевіряю, чи є кожен індекс.

Трюк: 1-базисні індекси списку можна генерувати, #\тобто довжину кожного префікса.

Використання:

   (#\*/@e.[:;]({:*0=[:+/{.)@|:\.\@,.#\) 2 _1 _1 2
1
   (#\*/@e.[:;]({:*0=[:+/{.)@|:\.\@,.#\) 2 _1
0

Спробуйте його онлайн тут.


Я думаю, що ви можете зберегти 2 байти, скориставшись трюком базового 1 для підсумовування та за допомогою складеної плоскості#\*/@e.&,]({:*0=1#.{.)@|:\.\@,.#\
миль

2

JavaScript (ES6), 109 байт

f=([q,...a],b=[],c=[])=>1/q?f(a,[...b,0].map((x,i)=>x+q||(c=c.map((n,j)=>n|i<=j)),c.push(0)),c):c.every(x=>x)

Фрагмент тесту


1

Python, 123 120 байт

-3 байти завдяки @Zgarb

Записує список такого ж розміру, що і вхід з зрізами з нульовою сумою та перезаписує відповідно до індексів, повертаючи його рівність до початкового в кінці.

def f(l):
 s=len(l);n=[0]*s
 for i in range(s):
  for j in range(i,s+1):
   if sum(l[i:j])==0:n[i:j]=l[i:j]
 return n==l

1
Я думаю, ви можете використовувати 0як заповнювач замість None. Неправдивих позитивних результатів не буде, тому що кожен 0із вхідних даних завжди є частиною або зрізом з нульовою сумою.
Згарб

Ти правий. Я подумав над цим, але в підсумку дійшов висновку, що це може спричинити помилкові позитиви.
dfernan

0

Скала, 49 байт

% =>(1 to%.size)flatMap(%sliding)exists(_.sum==0)

Спробуйте це у ideone

Використання:

val f:(Seq[Int]=>Boolean)= % =>(1 to%.size)flatMap(%sliding)exists(_.sum==0)
f(Seq(4, -2, -2)) //returns true

Безголовки:

array=>(1 to array.size)
  .flatMap(n => array.sliding(n))
  .exists(slice => slice.sum == 0)

Пояснення:

% =>            //define a anonymouns function with a parameter called %
  (1 to %.size) //create a range from 1 to the size of %
  flatMap(      //flatMap each number n of the range
    %sliding    //to an iterator with all slices of % with length n
  )exists(      //check whether there's an iterator with a sum of 0
    _.sum==0
  )

Я не зовсім впевнений, як це працює, але я думаю, що це повинно зазнати невдачі в деяких тестових випадках.
Згарб

@Zgarb Я додав посилання на ideone, щоб ви могли переконатися, що це правильно. Це, в основному, груба сила, пробуючи всі можливі скибочки.
corvus_192

Ви можете використовувати %як ім'я параметра? Класно!
Cyoce

@Cyoce Ви можете використовувати майже будь-які символи Unicode, крім .,;:()[]{}\"'. Дуже корисний для гри в гольф, оскільки вони відокремлюються від букв на синтаксичному розборі, тому ви можете зберегти пробіл.
corvus_192

Я перевірив тестові випадки, і, здається, це дає trueдругий хибний випадок.
Згарб

0

Пітон, 86 байт

def f(l):
 r=range(len(l))
 if[i for i in r for j in r if sum(l[j:j+i+1])==0]:return 1

Truthy = 1 Falsy = Ні


Це неправильно повертається 1для третього тестового випадку.
Згарб

1
Він фактично повертається 1для всіх тестових випадків, крім перших двох хибних.
dfernan

0

Clojure, 109 байт

#(=(count %)(count(set(flatten(for[r[(range(count %))]l r p(partition l 1 r):when(=(apply +(map % p))0)]p))))

Генерує всі розділи, які дорівнюють нулю, перевіряє, чи має він "довжину вхідного вектора".


0

PHP, 104 байти

Сила грубої сили та ще понад 99 байт. :-(

for($p=$r=$c=$argc;$s=--$p;)for($i=$c;$s&&$k=--$i;)for($s=0;$k<$c&&($r-=!$s+=$argv[$k++])&&$s;);echo!$r;

бере вхід з аргументів командного рядка 1для truthy, порожній для хибного. Бігайте з -r.

зламатися

for($p=$r=$argc;$s=$p--;)   # loop $p from $argc-1 to 0 with dummy value >0 for $s
    for($i=$p;$s&&$k=$i--;)     # loop $i (slice start) from $p to 1, break if sum is 0
        for($s=0;                   # init sum to 0
            $k<$argc                # loop $k (slice end) from $i to $argc-1
            &&($r-=!$s+=$argv[$k++])    # update sum, decrement $r if sum is 0
            &&$s;);                     # break loop if sum is 0
echo!$r;                    # $r = number of elements that are not part of a zero-sum slice

$argv[0]містить ім'я файлу; якщо запустити з -r, це буде -і оцінювати 0для числових ops.


0

JavaScript (ES6), 102 байти

a=>(g=f=>a.map((_,i)=>f(i)))(i=>g(j=>j<i||(t+=a[j])||g(k=>b[k]&=k<i|k>j),t=0),b=g(_=>1))&&!/1/.test(b)

Обчислює часткові суми для всіх елементів i..jвключно, і скидають відповідні елементи bз 1до , 0коли він знаходить нульову суму, нарешті , не перевіряючи , що немає 1и залишилися.

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