Додавання вирівнювання масиву


39

Вступ

Розглянемо два непусті цілі масиви, скажімо, A = [0 3 2 2 8 4] і B = [7 8 7 2] . Щоб виконати додавання вирівнювання на них, ми робимо наступне:

  1. Повторіть кожен масив достатньо разів, щоб мати загальну довжину lcm (length (A), length (B)) . Тут lcm означає найменший загальний кратний.

    A -> [0 3 2 2  8 4][0 3  2 2 8 4]
    B -> [7 8 7 2][7 8  7 2][7 8 7 2]
    
  2. Виконайте елементне додавання на повторних масивах та виріжте результат у кожній позиції, де є зріз у будь-якому з них.

    A -> [0  3 2 2   8  4][0 3  2  2  8 4]
    B -> [7  8 7 2][ 7  8  7 2][7  8  7 2]
      -> [7 11 9 4][15 12][7 5][9 10 15 6]
    
  3. Цей масив масивів - ваш результат.

Завдання

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

Правила та оцінка

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

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

[1] [4] -> [[5]]
[1,2,-3,-4] [15] -> [[16],[17],[12],[11]]
[0,-4] [2,1,0,-3] -> [[2,-3],[0,-7]]
[0,3,2,2,8,4] [7,8,7,2] -> [[7,11,9,4],[15,12],[7,5],[9,10,15,6]]
[18,17,16] [-1,-2,-3,-4] -> [[17,15,13],[14],[16,14],[15,13],[15],[16,14,12]]
[18,17,16,15] [-1,-2,-3,-4] -> [[17,15,13,11]]
[1,1,1,1,1] [6,5,6,5,6,5,6,2,1] -> [[7,6,7,6,7],[6,7,3,2],[7],[6,7,6,7,6],[7,3,2],[7,6],[7,6,7,6,7],[3,2],[7,6,7],[6,7,6,7,3],[2],[7,6,7,6],[7,6,7,3,2]]
[1,1,1,1,1,1] [6,5,6,5,6,5,6,2,1] -> [[7,6,7,6,7,6],[7,3,2],[7,6,7],[6,7,6,7,3,2]]
[1,1,1,1,1,1,1] [6,5,6,5,6,5,6,2,1] -> [[7,6,7,6,7,6,7],[3,2],[7,6,7,6,7],[6,7,3,2],[7,6,7],[6,7,6,7,3,2],[7],[6,7,6,7,6,7,3],[2],[7,6,7,6,7,6],[7,3,2],[7,6,7,6],[7,6,7,3,2],[7,6],[7,6,7,6,7,3,2]]

У C немає можливості дізнатися довжину масиву - чи можу я запитати довжину масиву як аргумент, чи зберігати його на початку масиву?
кіт

1
@cat Ви можете вважати довжини додатковими аргументами, якщо іншого способу їх отримання не існує.
Згарб

Відповіді:


9

JavaScript (ES6), 101 99 байт

Приймає вхід як 2 масиви. Повертає рядок.

f=(a,b,j=0,s='')=>a.map((v,i)=>(s+=i*j?' ':s&&'][',s+=b[j]+v,j=++j%b.length))|j?f(a,b,j,s):`[${s}]`

Як це працює

Ми повторюємо перший масив aвказівником i, оновлюючи інший вказівник jна другий масив b. Суми a[i] + b[j]додаються до вихідного рядка s. Роздільник вставляється щоразу i == 0або j == 0. Ми повторюємо цей процес, поки jне повернеться точно на початку, bнаприкінці ітерації.

Примітка. Коли |оператор застосовано, a.map(...)він примусовий до або NaN(якщо aмістить більше одного елемента), або поточного значення j(якщо aмістить точно один елемент). Тому a.map(...)|j == jу всіх випадках і тут безпечно використовувати.

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


Я навіть не намагався зрозуміти відповідь, +1 для замітки . Я
скопіюю і збережу

6

Haskell, 84 79 байт

a#b=a%b where(c:d)%(e:f)|(x:y)<-d%f=(c+e:x):y;[]%[]=[[]];c%[]=[]:c%b;_%d=[]:a%d

Моя перша версія була такою ж у більш читаному макеті:

a#b=a%b where
 (c:d)%(e:f)|(x:y)<-d%f=(c+e:x):y
 []%[]=[[]]
 c%[]=[]:c%b
 _%d=[]:a%d

Використання локального визначення, щоб уникнути необхідності наводити (%)додаткові аргументи для aта b. Дивовижно, що це майже те саме рішення, яке дається майже в той же час, що і @ nimi's, від якого я взяв ідею використовувати лише один рядок для локального визначення.

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

*Main> [0,3,2,2,8,4] # [7,8,7,2]
[[7,11,9,4],[15,12],[7,5],[9,10,15,6]]

О, це приємний спосіб додати суму до першого елемента списку. Набагато коротше мого громіздкого !.
німі

4

PHP, 126 120 байт

function($a,$b){do{$c[$j][]=$a[$i%$x=count($a)]+$b[$i%$y=count($b)];++$i%$x&&$i%$y?:$j++;}while($i%$x|$i%$y);return$c;};

Спробуйте тут!

Анонімна функція, яка повертає отриманий масив масивів.

По суті, ми перебираємо вміст обох наших масивів, модеруючи наш ітератор по довжині масиву, щоб імітувати «їх копіювання». Беручи кожне зі значень з масивів, ми підсумовуємо їх і додаємо до масиву в $c. Якщо ми дійдемо до кінця одного з наших вхідних масивів (розщеплення, з точки зору виклику), ми почнемо призначати новий масив в $c.

Причина do whileциклу полягає в тому, що заснований наш стан $i, який починається з 0. Якщо ми використовуємо цикл, де умова перевіряється на початку, цикл не запускається

Ми закінчуємо підсумовування лише після того, як досягнемо кінця обох масивів одночасно, що означало б LCM.


Хіба це не повинно бути $b[$i%$y]? Ви можете зберегти 3 байти, перейшовши $x=count($a)до першого використання $x; те ж саме $y=count($b)і один байт з порозрядним або в whileумові
Тит

Але я думаю, що анонімні функції вважаються фрагментами, а отже, не відповідають дійсності.
Тит

@Titus Анонімні функції дозволені за замовчуванням відповідно до консенсусу щодо Meta .
Згарб

Дякую за пропозиції @Titus, я просто накинув це разом, тому що хотів бити інші відповіді PHP: P
Xanderhall

4

Haskell, 87 84 байт

a#b=a%b where[]%[]=[[]];(e:f)%(g:h)=f%h!(e+g);e%[]=[]:e%b;_%g=[]:a%g
(m:n)!l=(l:m):n

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

Проста рекурсія. Базовий регістр: обидва списки порожні. Якщо лише один із них порожній, перезапустіть повну версію та запустіть новий кластер у висновку. Якщо жодна з них порожня, додайте суму до елемента from.

Подивіться також відповідь @Christian Sievers , яка майже однакова і була опублікована на кілька секунд раніше.


Ти впевнений? Чи є спосіб отримати точний час?
Крістіан Сіверс

@ChristianSievers: Я не знаю, чи ви можете бачити час безпосередньо. Коли час нашого редагування був показаний за лічені хвилини, я пам'ятаю, що ваш відлік був на кілька секунд (приблизно на 20) раніше, ніж мій.
німі

Ви маєте рацію: я знайшов часові позначки у вихідному коді html цієї сторінки
Christian Sievers

Наведіть курсор миші на "Відповідь 2 дні тому", щоб побачити точний час. (Підказка: це стандартний інтерфейс користувача в Інтернеті, тому (а) якщо ви хочете точного часу, спробуйте навести курсор відносного часу, і (б) якщо ви коли-небудь реалізуєте щось, що показує відносний час, будь ласка, покажіть точний час на наведення курсора !)
wchargin

2

Октава, 113 байт

@(a,b)mat2cell(sum([repmat(a,1,(L=lcm(A=numel(a),B=numel(b)))/A);repmat(b,1,L/B)]),1,diff(unique([0:A:L,0:B:L])))

цю функцію можна безпосередньо назвати, щоб викликати її, розмістити її в дужках і викликати як (@ (a, b) ...) ([1 2 3 4], [6 4 5])


1
Тепер TIO-Nexus підтримує Octave. Ось посилання для тестування коду
Луїс Мендо

@LuisMendo Спасибі, цікава послуга
rahnema1

2

CJam , 30 байт

{Sf*Laf+_s,f*:.+La/0=S2*a-Sa/}

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

Вводиться як пара списків.

Пояснення

Ідея полягає в тому, щоб вставити деякі маркери у вхідні масиви (у вигляді коротких рядків), які вказують, де закінчується вирівняний масив, і де нам потрібно вставити перерви у масиви. Таким чином ми можемо уникати обчислення LCM.

Sf*    e# Riffle each list with spaces. These are just place holders, so that having
       e# an array-end marker between two elements doesn't misalign subsequent elements.
Laf+   e# Append an empty string to each list. This is the array-end marker.
_s,    e# Convert the pair of lists to a string and get its length. This is always
       e# greater than the number of elements in either input.
f*     e# Repeat either array that many times. This is definitely more than necessary
       e# to reach the LCM (since multiplying by the length of the other list always
       e# gives a common multiple).
:.+    e# Pairwise addition of the list elements. There are four cases:
       e# - Both elements are numbers, add them. This is the actual addition
       e#   we need for the problem.
       e# - Both elements are spaces. This is just a regular position between
       e#   list elements.
       e# - One is a space, one is empty: the result is a single space, and
       e#   this marks a position where one of the arrays ended, which means
       e#   we need to split here.
       e# - Both elements are empty. This happens at the LCM of both list lengths
       e#   and indicates where we need to stop the output.
La/0=  e# Split the input around empty strings and discard everything except
       e# the first chunk.
S2*a-  e# Remove the double-space strings, we no longer need them.
Sa/    e# Split the list around single spaces.

2

Желе , 21 20 18 байт

ṁ€L€æl/$S
J€ỊÇœṗÇḊ

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

Як це працює

ṁ€L€æl/$S  Helper link. Argument [X, Y] (arrays of integers).

       $   Combine the two links to the left into a monadic chain.
  L€       Length each; yield the lengths of X and Y.
    æl/    Reduce by least common multiple.
ṁ€         Mold each; cyclically repeat the elements of X and Y to extend them
           to length lcm(length(X), length(Y)).
        S  Compute the sum of the extended X and Y arrays.

J€ỊÇœṗÇḊ   Main link. Argument [A, B] (arrays of integers).

J€         Indices each; replace A and B by the arrays of there 1-based indices.
  Ị        Insignificant; map 1 to itself, all other indices to 0.
   Ç       Apply the helper link to the result.
           This yield a Boolean array with a 1 (or 2) at all indices where a new
           repetition of A or B (or both) begins.
      Ç    Apply the helper link to [A, B].
    œṗ     Partition; break the result to the right at truthy elements (1 or 2) in
           the result to the right.
       Ḋ   Dequeue; remove the first element of the partition (empty array).

2

Пітон 3,5 - ( 146 137 134 130 + 12) = 142 байт

import math
def s(a,b):
 l,k,*r=map(len,[a,b])
 for i in range(l*k//math.gcd(l,k)):
  r+=a[i%l]+b[i%k],
  if i%k==k-1or i%l==l-1:print(r);r=[]

Я не можу зрозуміти, як розмістити цілу петлю в один рядок.

Зміни:

  • Дякуємо zgarb за збереження 9 байт!
  • Дякуємо vaultah за збереження 3 байтів!
  • Дякую математиці, економивши 5 байт!

Це дає помилку для мене . gcdФункція в fractionsНЕ math.
Згарб

@Zgarb модуль gcd у фракціях застарілий , ви можете перевірити зміни тут . Я думаю, що рекстер використовує стару версію 3.4.3.
Гурупад Мамадапур

Акуратний, я не знав про цю зміну. Ви повинні позначити мову як "Python 3.5", оскільки вона не працює в 3.4 або раніше. Також ви можете опустити круглі дужки навколо l*kі мати print(r);r=[]в останньому рядку.
Згарб

Ви впевнені, що кількість байтів правильна? Я думаю, що всього 145 байт.
vaultah

1
Я отримую 142 байти. Ви використовуєте Windows? Windows зазвичай рахує нові рядки по 2 байти кожен, але тут кожен новий рядок рахується як один байт.
mathmandan

2

Python 2, 119 байт

a=input()
i,v,l=0,list(a),len
while 1:q=l(v[0])>l(v[1]);print map(sum,zip(*v)[i:]);i=l(v[q]);v[q]+=a[q];1/(i-l(v[q^1]))

Приймає вхід від stdin як два кортежі, розділені комою, виводить отримані списки в stdout. Припиняється скасування ZeroDivisionErrorвинятку, оскільки, здається, це дозволено .

Наприклад, якщо вхід є (0, 3, 2, 2, 8, 4), (7, 8, 7, 2), програма надрукує

[7, 11, 9, 4]
[15, 12]
[7, 5]
[9, 10, 15, 6]

до stdout та простеження винятку до stderr.


Ви можете вийти з програми, видавши помилку . Тоді ви, можливо, зможете звести цикл в один рядок.
Згарб

2

J , 34 32 байти

[:(<;.1~*)/[:+/*.&#$&>,:&(;2>#\)

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

Пояснення

[:(<;.1~*)/[:+/*.&#$&>,:&(;2>#\)  Input: array A (LHS), array B (RHS)
                             #\   Length of each prefix of A and B
                           2>     Less than 2
                          ;       Link each with A and B
                      ,:&         Pair them
                  #               Length of A and B
               *.&                LCM of the lengths
                    &>            For each box
                   $              Reshape it to the LCM of the lengths
           [:+/                   Reduce by addition
[:        /                       Reduce by
        *                           Sign of RHS
   <;.1~                            Box each partition of LHS

1

Haskell, 166 байт

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

l=length
a?b=take(lcm(l a)$l b)$zipWith(+)(cycle a)$cycle b
l%(i:ind)|l==[]=[]|1>0=take i l:(drop i l)%(map(+(-i))ind)
a!b=(a?b)%[k|k<-[1..],k`mod`l a<1||k`mod`l b<1]

Ви можете замінити indна kщось чи щось, а навколо drop i lі навколо є деякі непотрібні дужки map(+(-i))ind. Розглянемо також наявність двох випадків для %, з урахуванням шаблону l.
Згарб

1

[PHP], 183 152 135 байт

function O($A,$B){while($f<2){$O[$k][]=$A[+$i]+$B[+$j];$f=0;isset($A[++$i])?:$i=!++$k|!++$f;isset($B[++$j])?:$j=!++$k|!++$f;}return$O;}

Хороша версія:

function O($A,$B)
{
    while($f<2) {
        $O[$k][]=$A[+$i]+$B[+$j];
        $f=0;
        isset($A[++$i])?:$i=!++$k|!++$f;
        isset($B[++$j])?:$j=!++$k|!++$f;
    }

    return$O;
}

Вихід:

array (size=4)
  0 => 
    array (size=4)
      0 => int 7
      1 => int 11
      2 => int 9
      3 => int 4
  1 => 
    array (size=2)
      0 => int 15
      1 => int 12
  2 => 
    array (size=2)
      0 => int 7
      1 => int 5
  3 => 
    array (size=4)
      0 => int 9
      1 => int 10
      2 => int 15
      3 => int 6

Малюйте навіть зі мною, використовуючи ці налаштування: $i=$j=$k=0;непотрібно, якщо ви використовуєте +$ietc. для індексів масиву в додатку, що додається (-8 байт). $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, двічі). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;не потребує місця (-1).
Тит

@Titus не може видалити $i=$j=0;частину, оскільки перші значення з масивів не будуть правильними. Я трохи змінив логіку, тому не знаю, як реалізувати потрійні оператори в цьому випадку. Дякую за ++$iпоради.
Декса

Спробуйте unset($i);$A[+$i]. +Вкинуто nullв ціле число 0.
Тит

if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;досі зберігає 5 байт. Збережіть ще один за допомогою, $f<2а не $f!=2. і ще два з, while($f=$f<3){...}а не while($f<2){$f=0;...}(ініціалізує та скидає $fдо 1, якщо він не збільшується вдвічі)
Тит

@Titus Дякую, зараз це коротше.
Декса

1

PowerShell , 147 145 байт

param($a,$b)$o=@{};do{$o[+$j]+=,($a[+$i%($x=$a.count)]+$b[$i++%($y=$b.count)]);if(!($i%$x-and$i%$y)){$j++}}until(($x,$y|?{!($i%$_)}).count-eq2)$o

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

( Пропозиції з гольфу вітаються. Я вважаю, що, мабуть, ще 10–15 байт, які можна вичавити з цього. )

Вводить дані як два явні масиви (із @(...)синтаксисом) як аргументи командного рядка. Повертає хештинг отриманих масивів, оскільки багатовимірні масиви в PowerShell можуть стати дивними, і це більш послідовно. Встановлює деякі початкові змінні, після чого знову вводить do/ untilцикл, при цьому умовне буття $iдорівнює lcm масиву .

Кожну ітерацію циклу, ми додаємо відповідні $aта $bзначення разом, трактуємо її як масив ,(...)перед тим, як додати її до хештету $oу відповідному місці $j. Інкапсуляція масиву необхідна для запобігання арифметичного додавання - це змушує +=перевантажувати замість конкатенації масиву. Потім, умовний на $xі$y (підрахунків) , щоб визначити , якщо ми на краю масиву - якщо це так, ми збільшуємо $j.

Нарешті, ми залишаємо $oна конвеєрі і вихід неявний.
(Примітка: Через те, як PowerShell перераховує хештелі за замовчуваннямWrite-Output , це, як правило, виводиться "назад"; як і в "0-му" результуючому масиві знаходиться на "нижній частині" виводу. Сам хеш - це добре, і це буде використовується просто чудово, якщо, наприклад, інкапсулював цей код у змінну, що повертається ... він просто виглядає дивним, коли він друкується.)

Збережено 2 байти, перемістивши $ x і $ y в індексацію масиву, а не окремо (збережено два крапки з комою).


1

Python 2, 113 байт

a,b=input()
i=m=n=0;r=[]
while(not i)+m+n:r+=[[]]*(not m*n);r[-1]+=[a[m]+b[n]];i+=1;m=i%len(a);n=i%len(b)
print r

Чи notможе <1замість цього бути s?
Згарб

1

Пітон 3,5, 210 176 173 169 158 байт

def f(a,b):
 x=[];e=f=0              
 while 1:
  if e==len(a):         
   print(x);x=[];e=0;
   if f==len(b):break
  if f==len(b):print(x);x=[];f=0
 x+=a[e]+b[f],;e+=1;f+=1

Бере два списки як вхідні та друкує всі списки.

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

  • Збережено 34 байти : завдяки Деннісу та TimmyD
  • Збережено 3 байти : використовував c і d для len (a) та len (b), але виявляється, вони були не корисні
  • Збережені 4 байти : завдяки orlp видалено небажаний парантез
  • Збережено 11 байт : перестановивши кілька блоків і розчавивши їх

1
Привіт, ласкаво просимо до Головоломки та гольфу програмування! Неконкурентний означає щось інше тут; ви повинні вилучити це. Ви можете зберегти досить багато байтів, усунувши пробіли. Наприклад, рядки 2 - 5 можуть стати x=[];c=len(a);d=len(b);e=f=0. Також trueможе стати 1, і x.append(a[e]+b[f])може стати x+=a[e]+b[f],.
Денніс

1
Ласкаво просимо до PPCG! Окрім специфічних виправлень Денніса, перегляньте поради щодо гольфу в Python, щоб отримати ще деякі загальні підказки та підказки.
AdmBorkBork

1
ifі whileтвердження не потребують дужок.
orlp

1

Ракетка 373 байт

(let*((lg length)(fl flatten)(ml make-list)(t rest)(r reverse)(m modulo)(o cons)(ln(lg l))(jn(lg j))(c(lcm ln jn))(l2(fl(ml(/ c ln)l)))
(j2(fl(ml(/ c jn)j)))(ll(for/list((a l2)(b j2))(+ a b))))(let p((ll ll)(ol '())(tl '())(n 0))(cond[(empty? ll)(t(r(o(r tl)ol)))]
[(or(= 0(m n ln))(= 0(m n jn)))(p(t ll)(o(r tl)ol)(take ll 1)(+ 1 n))][(p(t ll)ol(o(first ll)tl)(+ 1 n))])))

Безголовки:

(define(f l j)
  (let* ((ln (length l))
         (jn (length j))
         (c (lcm ln jn))
         (l2 (flatten (make-list (/ c ln) l)))
         (j2 (flatten (make-list (/ c jn) j)))
         (ll (for/list ((a l2)(b j2))
               (+ a b))))

    ; TO CUT LIST INTO PARTS: 
    (let loop ((ll ll)
               (ol '())
               (templ '())
               (n 0))
      (cond
        [(empty? ll) 
         (rest (reverse (cons (reverse templ) ol)))]
        [(or (= 0 (modulo n ln))
             (= 0 (modulo n jn)))
         (loop (rest ll)
               (cons (reverse templ) ol)
               (list (first ll))
               (add1 n))]
        [(loop (rest ll)
               ol
               (cons (first ll) templ)
               (add1 n))]))))

Тестування:

(f '[1]  '[4])
(f '[1 2 -3 -4] '[15])
(f '[0 3 2 2 8 4]  '[7 8 7 2])

Вихід:

'((5))
'((16) (17) (12) (11))
'((7 11 9 4) (15 12) (7 5) (9 10 15 6))

1

Clojure, 280 206 байт

(fn[a b](let[A(count a)B(count b)Q quot](map #(map last %)(partition-by first(take-while #((% 0)2)(map-indexed(fn[i s][[(Q i A)(Q i B)(or(= i 0)(>(mod i A)0)(>(mod i B)0))]s])(map +(cycle a)(cycle b))))))))

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

(def f (fn[a b]
         (let[A(count a)B(count b)Q quot]
           (->> (map +(cycle a)(cycle b))
                (map-indexed (fn [i s][[(Q i A)(Q i B)(or(= i 0)(>(mod i A)0)(>(mod i B)0))]s]))
                (take-while #((% 0)2))
                (partition-by first)
                (map #(map last %))))))

Оригінал: Я сподіваюся на вдосконалення цього, але це найвищого у мене зараз.

(fn[a b](let [C cycle o count c(take-while #(or(=(% 0)0)(>(% 1)0)(>(% 2)0))(map-indexed(fn[i[A B]][i(mod i(o a))(mod i(o b))(+ A B)])(map(fn[& v]v)(C a)(C b))))](map #(map last %)(partition-by first(map(fn[p c][p(last c)])(reductions + (map #(if(or(=(% 1)0)(=(% 2)0))1 0)c))c)))))

Недоліковані та багатослівні:

(def f (fn[a b]
         (let [c(->> (map (fn[& v]v) (cycle a) (cycle b))
                     (map-indexed (fn[i[A B]][i (mod i(count a)) (mod i(count b)) (+ A B)]))
                     (take-while #(or(=(% 0)0)(>(% 1)0)(>(% 2)0))))]
           (->> (map (fn[p c][p(last c)]) (reductions +(map #(if(or(=(% 1)0)(=(% 2)0))1 0)c)) c)
                (partition-by first)
                (map #(map last %))))))

Починається з "об'єднання" нескінченного циклу колекцій aі bдодає метадані до індексу кожного елемента в колекції, доки обидві послідовності не почнуться з індексу 0 знову.

Ця колекція c об'єднується з даними розділів (сукупна сума одиниць і нулів), розділяється і вибирається останній елемент (будучи сумою елементів).

Я думаю, що для значних удосконалень потрібен абсолютно інший підхід.


1

PHP, 150 121 119 байт

function($a,$b){while($i<2|$x|$y)$r[$k+=!($x=$i%count($a))|!$y=$i++%count($b)][]=$a[$x]+$b[$y];array_pop($r);return$r;}

анонімна функція приймає введення як масиви.

зламатися

while($i<2|$x|$y)   // loop while either $a or $b has NO cut
    $r[
                // if either $a or $b has a cut, increment $k; post-increment $i
        $k+=!($x=$i%count($a))|!$y=$i++%count($b)
                // append current $a + current $b to $r[$k]
    ][]=$a[$x]+$b[$y];
array_pop($r);  // $r has one element too much; remove it
return$r;

0

C ++ 14, 206 байт

Як безіменний загальний лямбда, що вимагає введення контейнери P, Qі вихідний контейнер , Rщоб бути схожими vector<vector<int>>.

[](auto P,auto Q,auto&R){R.clear();auto a=P.begin(),b=Q.begin(),x=P.end(),y=Q.end();auto A=a,B=b;do{R.emplace_back();while(a!=x&&b!=y)R.back().push_back(*a+++*b++);a=a==x?A:a;b=b==y?B:b;}while(a!=A||b!=B);}

Безголівки та використання:

#include<vector>
#include<iostream>

using namespace std;

auto f=
[](auto P,auto Q,auto&R){
 R.clear();               //just clear the output to be sure
 //a and b are the iterators, x and y is the end
 auto a=P.begin(),b=Q.begin(),x=P.end(),y=Q.end();
 //just some abbreviations for .begin()
 auto A=a,B=b;
 do{
  R.emplace_back();      //add new vector
  while(a!=x&&b!=y)      //while not at the end of one vector
   R.back().push_back(*a+++*b++);  //add the pointed elements and advance
  a=a==x?A:a;            //reset if at the end   
  b=b==y?B:b;
 }while(a!=A||b!=B);     //if both were resetted, then finish
}
;


int main(){
 vector<int> A = {0, 3, 2, 2, 8, 4};
 vector<int> B = {7, 8, 7, 2};
 vector<vector<int>> R;
 f(A,B,R);
 for (auto c:R){
  for (int x:c)
   cout << x << ", ";
  cout << endl;
 }
 cout << endl;
}

0

Математика 112 байт

Це, можливо, вдасться покращити. Ідея полягає у створенні 2D масиву з другим елементом, який використовується для відстеження лізингодавця лічильника i mod довжини кожного вхідного масиву.

Split[Table[{#[[1,(m=Mod[i,d=Length/@#,1])[[1]]]]+#[[2,m[[2]]]],Min@m},{i,LCM@@d}],#2[[2]]>#1[[2]]&][[;;,;;,1]]&

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

%@{{0,3,2,2,8,4},{7,8,7,2}}

0

JavaScript (ES6), 131 байт

(a,b,g=(r,[n,...d]=a,[m,...e]=b,s=[])=>1/n?1/m?g(r,d,e,[...s,n+m]):g([...r,s],[n,...d]):1/m?g([...r,s],a,[m,...e]):[...r,s])=>g([])

Трохи незворушений:

(a,b,r=[],[n,...d]=a,[m,...e]=b,s=[])
=>1/n?1/m?f(a,b,r,d,e,[...s,n+m])
         :f(a,b,[...r,s],[n,...d],b,[])
     :1/m?f(a,b,[...r,s],a,[m,...e],[])
         :[...r,s]
  • Якщо обидва масиви dі eмістять числа, до них додається сума першого числаs , а інші елементи обробляються рекурсивно
  • Якщо один з масивів містить числа, масив сум sдодається до результату, rа інший масив скидається до його початкового масиву
  • Якщо обидва масиви порожні, просто поверніть результат з останніми доданими сумами.

На жаль, це рішення не має безжальної ефективності @ Arnauld's, але, принаймні, я думаю, що це прекрасне рішення.

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