Dodawanie wyrównania tablicy


39

Wprowadzenie

Rozważ dwie niepuste tablice liczb całkowitych, powiedzmy A = [0 3 2 2 8 4] i B = [7 8 7 2] . Aby wykonać na nich dodanie wyrównania , wykonujemy następujące czynności:

  1. Powtórz każdą tablicę tyle razy, aby mieć całkowitą długość lcm (długość (A), długość (B)) . Tutaj lcm oznacza najniższą wspólną wielokrotność.

    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. Wykonaj elementowe dodawanie na powtarzanych tablicach i wytnij wynik w każdej pozycji, w której znajduje się cięcie w każdym z nich.

    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. Ta tablica tablic jest twoim rezultatem.

Zadanie

Twoje dane wejściowe to dwie niepuste tablice liczb całkowitych, a dane wyjściowe będą wynikiem dodania ich wyrównania, jak zdefiniowano powyżej. Wejścia i wyjścia mogą mieć dowolny rozsądny format. Podczas dodawania nie musisz się martwić o przepełnienie liczb całkowitych.

Zasady i punktacja

Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów.

Przypadki testowe

[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 nie ma sposobu na poznanie długości tablicy - czy mogę zażądać długości tablicy jako argumentu, czy też zapisać ją na początku tablicy?
kot

1
@cat Możesz wziąć długości jako dodatkowe argumenty, jeśli nie ma innego sposobu ich uzyskania.
Zgarb,

Odpowiedzi:


9

JavaScript (ES6), 101 99 bajtów

Pobiera dane wejściowe jako 2 tablice. Zwraca ciąg.

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}]`

Jak to działa

Iterujemy pierwszą tablicę aza pomocą wskaźnika ipodczas aktualizacji innego wskaźnika jdo drugiej tablicy b. Sumy a[i] + b[j]są dołączane do ciągu wyjściowego s. Separator jest wstawiany za każdym razem i == 0lub j == 0. Powtarzamy ten proces, aż jpowróci dokładnie na początku biteracji.

Uwaga: Gdy |operator jest zastosowany, a.map(...)jest wymuszany na NaN(jeśli azawiera więcej niż jeden element) lub na bieżącą wartość j(jeśli azawiera dokładnie jeden element). Dlatego a.map(...)|j == jwe wszystkich przypadkach i jest bezpieczny w użyciu tutaj.

Przypadki testowe


Nawet nie próbowałem zrozumieć odpowiedzi +1 dla notatki .
Skopiuję

6

Haskell, 84 79 bajtów

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

Moja pierwsza wersja była taka sama w bardziej czytelnym układzie:

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

Korzystanie z lokalnej definicji, aby uniknąć konieczności podawania (%)dodatkowych argumentów za ai b. O dziwo, jest to prawie to samo rozwiązanie, które podano niemal w tym samym czasie, co @ nimi, od którego wpadłem na pomysł użycia tylko jednej linii do definicji lokalnej.

Stosowanie:

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

Och, to fajny sposób na dodanie sumy do pierwszego elementu listy. Znacznie krótszy niż mój nieporęczny !.
nimi

4

PHP, 126 120 bajtów

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;};

Wypróbuj tutaj!

Anonimowa funkcja, która zwraca wynikową tablicę tablic.

Zasadniczo przeglądamy zawartość obu naszych tablic, modyfikując nasz iterator o długość tablicy, aby symulować „kopiowanie”. Biorąc każdą z wartości z tablic, sumujemy je i dodajemy do tablicy w $c. Jeśli dojdziemy do końca jednej z naszych tablic wejściowych (podział, jeśli chodzi o wyzwanie), zaczniemy przypisywać do nowej tablicy w $c.

Powodem do whilepętli jest to, że nasz warunek jest oparty na $i, który zaczyna się od 0. Jeśli użyjemy pętli, w której warunek jest sprawdzany na początku, pętla nie uruchomi się

Podsumowanie kończymy dopiero, gdy dojdziemy do końca obu tablic jednocześnie, co oznaczałoby LCM.


Nie powinno tak być $b[$i%$y]? Możesz zapisać 3 bajty, przechodząc $x=count($a)do pierwszego użycia $x; taki sam dla $y=count($b)i jeden bajt z bitem lub whilewarunkiem
Tytus

Ale myślę, że anonimowe funkcje są uważane za fragmenty i dlatego nie są prawidłowymi odpowiedziami.
Tytus

@Titus Funkcje anonimowe są domyślnie dozwolone zgodnie z porozumieniem w sprawie Meta .
Zgarb

Dzięki za sugestie @Titus, po prostu rzuciłem to razem, bo chciałem pokonać inne odpowiedzi PHP: P
Xanderhall

4

Haskell, 87 84 bajtów

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

Przykład użycia: [0,3,2,2,8,4] # [7,8,7,2]-> [[7,11,9,4],[15,12],[7,5],[9,10,15,6]].

Prosta rekurencja. Przypadek podstawowy: obie listy są puste. Jeśli tylko jeden z nich jest pusty, uruchom ponownie pełną wersję i uruchom nowy klaster w danych wyjściowych. Jeśli żaden nie jest pusty, dodaj sumę do elementu from.

Zobacz także odpowiedź @Christian Sievers , która jest prawie identyczna i została opublikowana kilka sekund wcześniej.


Jesteś pewny? Czy istnieje sposób na uzyskanie dokładnych czasów?
Christian Sievers

@ChristianSievers: Nie wiem, czy możesz bezpośrednio zobaczyć czasy. Kiedy czasy naszych edycji były wyświetlane w minutach, pamiętam, że twój był liczony o kilka sekund (około 20) wcześniej niż mój.
nimi

Masz rację: Znalazłem znaczniki czasu w kodzie źródłowym HTML tej strony
Christian Sievers

Najedź kursorem na czas w polu „odpowiedz 2 dni temu”, aby zobaczyć dokładny czas. (Wskazówka: jest to standardowy interfejs użytkownika w Internecie, więc (a) jeśli chcesz uzyskać dokładny czas, spróbuj najechać wskaźnikiem czasu względnego i (b) jeśli kiedykolwiek zaimplementujesz coś, co pokazuje czas względny, pokaż dokładny czas najechania kursorem !)
wchargin

2

Oktawa, 113 bajtów

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

tę funkcję można wywołać bezpośrednio, nazywając ją, umieszczając w nawiasie i wywołując jako (@ (a, b) ...) ([1 2 3 4], [6 4 5])


1
Teraz TIO-Nexus obsługuje Octave. Oto link do przetestowania kodu
Luis Mendo

@LuisMendo Dzięki, ciekawa usługa
rahnema1

2

CJam , 30 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe jako parę list.

Wyjaśnienie

Chodzi o to, aby wstawić kilka znaczników do tablic wejściowych (w postaci krótkich łańcuchów), które wskazują, gdzie kończy się wyrównana tablica i gdzie musimy wstawić przerwy w tablicach. W ten sposób możemy uniknąć konieczności obliczania 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

Galaretka , 21 20 18 bajtów

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

Wypróbuj online!

Jak to działa

ṁ€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

Python 3.5 - ( 146 137 134 130 + 12) = 142 bajtów

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

Nie mogę wymyślić, jak umieścić całość dla pętli w jednej linii.

Edycje:

  • Dzięki zgarb za oszczędność 9 bajtów!
  • Dzięki vaultah za uratowanie 3 bajtów!
  • Dzięki matematyku oszczędzasz 5 bajtów!

Daje mi to błąd . gcdFunkcja jest w fractionsnie math.
Zgarb

@Zgarb moduł gcd we frakcjach jest przestarzały , możesz sprawdzić zmianę tutaj . Myślę, że rexter używa starej wersji 3.4.3.
Gurupad Mamadapur,

Zgrabne, nie wiedziałem o tej zmianie. Powinieneś jednak oznaczyć język jako „Python 3.5”, ponieważ nie działa on w wersji 3.4 lub wcześniejszej. Ponadto, można upuścić nawiasów wokół l*ki mają print(r);r=[]w ostatnim wierszu.
Zgarb

Czy jesteś pewien, że liczba bajtów jest poprawna? Myślę, że jest tylko 145 bajtów.
vaultah

1
Dostaję 142 bajty. Czy korzystasz z systemu Windows? Windows zwykle liczy nowe wiersze jako 2 bajty, ale tutaj każda nowa linia jest liczona jako pojedynczy bajt.
matmandan

2

Python 2, 119 bajtów

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

Pobiera dane wejściowe ze standardowego wejścia jako dwie krotki oddzielone przecinkiem, a wyniki są wypisywane na standardowe wyjście. Kończy się, zgłaszając ZeroDivisionErrorwyjątek, ponieważ wydaje się to dozwolone .

Na przykład, jeśli dane wejściowe są (0, 3, 2, 2, 8, 4), (7, 8, 7, 2), program wydrukuje

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

na stdout i śledzenie wyjątku na stderr.


Możesz wyjść z programu, zgłaszając błąd . Wtedy możesz uzyskać pętlę w jednej linii.
Zgarb

2

J , 34 32 bajty

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

Wypróbuj online!

Wyjaśnienie

[:(<;.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 bajtów

Prawdopodobnie nie jest to najbardziej eleganckie podejście: Zasadniczo funkcja ?tworzy jedną listę potrzebnej długości z sumami i %ponownie przycina tę sumę. !jest ostatnią funkcją, która łączy te dwa elementy.

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]

Możesz zastąpić indprzez klub coś, a wokół drop i li są niepotrzebne nawiasy map(+(-i))ind. Rozważ także posiadanie dwóch skrzynek %z włączonym dopasowaniem wzorca l.
Zgarb

1

[PHP], 183 152 135 bajtów

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;}

Ładna wersja:

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;
}

Wynik:

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

Rysuj nawet ze mną za pomocą tych poprawek: nie $i=$j=$k=0;jest konieczne, jeśli używasz +$iitp. Dla indeksów tablic w dołączanym przypisaniu (-8 bajtów). $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, dwa razy). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;nie wymaga spacji (-1).
Tytus

@Titus nie może usunąć $i=$j=0;części, ponieważ pierwsze wartości z tablic nie będą poprawne. Zmodyfikowałem trochę logikę, więc nie jestem pewien, jak zaimplementować trójskładnikowe operatory w tym przypadku. Dziękuję za ++$iporady.
Dexa,

Spróbować unset($i);$A[+$i]. +Rzuci nulldo liczby całkowitej 0.
Tytus

if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;nadal zapisuje 5 bajtów każdy. Zapisz jedna ze $f<2zamiast $f!=2. i kolejne dwa z while($f=$f<3){...}zamiast while($f<2){$f=0;...}(inicjuje się i resetuje $fdo 1, chyba że dwukrotnie zwiększy się)
Tytus

@Titus Dziękuję bardzo, teraz jest krótszy.
Dexa,

1

PowerShell , 147 145 bajtów

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

Wypróbuj online!

( Sugestie dotyczące gry w golfa są mile widziane. Wydaje mi się, że można jeszcze wycisnąć 10–15 bajtów ).

Pobiera dane wejściowe jako dwie jawne tablice (ze @(...)składnią) jako argumenty wiersza poleceń. Zwraca tablicę skrótów wynikowych tablic, ponieważ tablice wielowymiarowe w programie PowerShell mogą stać się dziwne, a to jest bardziej spójne. Ustawia niektóre początkowe zmienne, a następnie ponownie wchodzi w pętlę do/ until, przy czym warunek jest $itaki, że lcm tablicy się liczy .

Każdej iteracji pętli dodajemy razem odpowiednie wartości $ai $bwartości, traktujemy ją jako tablicę ,(...)przed dodaniem jej do tablicy mieszającej $ow odpowiednim miejscu $j. Hermetyzacja macierzy jest niezbędna, aby zapobiec dodawaniu arytmetycznemu - to +=zamiast tego zmusza do przeciążenia do konkatenacji macierzy. Następnie warunkowe $xi $y(liczy), aby ustalić, czy jesteśmy na krawędzi tablicy - jeśli tak, zwiększamy $j.

Wreszcie, pozostawiamy $ow przygotowaniu i wynik jest niejawny.
(Uwaga: Ze względu na to, jak program PowerShell wylicza tabele skrótów z ustawieniami domyślnymi Write-Output, dane wyjściowe mają tendencję do wyświetlania „wstecz”; jak w tym przypadku tablica wynikowa „0” znajduje się na „dole” wyniku. Sam skrót jest w porządku i byłby użyto w porządku, jeśli np. enkapsulowano ten kod w zmiennej zwracanej ... po prostu wygląda dziwnie, gdy jest drukowany.)

Zaoszczędzono 2 bajty, przenosząc $ x i $ y do indeksowania tablicy zamiast oddzielne (zapisano dwa średniki).


1

Python 2, 113 bajtów

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

Czy zamiast tego mogą notbyć <1?
Zgarb,

1

Python 3.5, 210 176 173 169 158 bajtów

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

Pobiera dwie listy jako dane wejściowe i drukuje wszystkie listy.

To moja pierwsza odpowiedź i jeszcze nie wiem, jak grać w golfa. Podstawową ideą, którą zastosowałem, jest posiadanie dwóch liczników dla każdej listy, które wskazują podział i bieżącą listę, do której dodawane są wartości dodane; zaraz po napotkaniu podziału drukujemy bieżącą listę i tworzymy nową pustą.

  • Zapisane 34 bajty : Dzięki Dennis i TimmyD
  • Zapisano 3 bajty : użyłem cid dla len (a) i len (b), ale okazało się, że nie były przydatne
  • Zapisane 4 bajty : Dzięki orlp usunięto niechciane nawiasy
  • Zapisano 11 bajtów : uporządkowałem kilka bloków i skruszyłem je

1
Cześć, witamy w Programowaniu Puzzle i Code Golf! Nie konkurowanie oznacza tutaj coś innego; powinieneś to usunąć. Możesz zaoszczędzić sporo bajtów, eliminując spacje. Na przykład mogą być wiersze od 2 do 5 x=[];c=len(a);d=len(b);e=f=0. Ponadto truemoże stać się 1i x.append(a[e]+b[f])może stać się x+=a[e]+b[f],.
Dennis

1
Witamy w PPCG! Oprócz drobnych poprawek Dennisa, zobacz Wskazówki dotyczące gry w golfa w Pythonie, aby uzyskać więcej ogólnych wskazówek i wskazówek.
AdmBorkBork,

1
ifa whileoświadczenia nie wymagają nawiasów.
orlp

1

Rakieta 373 bajtów

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

Nie golfowany:

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

Testowanie:

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

Wynik:

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

1

Clojure, 280 206 bajtów

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

To ma o wiele większy sens. Generowanie sumy elementarnej, dodawanie metadanych pozycyjnych, pobieranie, podczas gdy jeszcze się nie powtórzyliśmy, i dodawanie wartości sumy do każdej partycji.

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

Oryginał: Mam nadzieję, że to poprawię, ale na razie jest to najmilszy.

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

Nie golfista i gadatliwy:

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

Zaczyna się od „scalenia” nieskończonego cyklu kolekcji ai bdodaje metadane do indeksu każdego elementu w kolekcji, dopóki obie sekwencje nie zaczną ponownie od indeksu 0.

Ta kolekcja cjest następnie łączona z danymi partycji (skumulowana suma zer i jedynek), partycjonowana i wybierany jest ostatni element (będący sumą pozycji).

Myślę, że w przypadku znacznych ulepszeń wymagane jest zupełnie inne podejście.


1

PHP, 150 121 119 bajtów

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;}

funkcja anonimowa pobiera dane wejściowe jako tablice.

awaria

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 bajtów

Jako bezimiennego rodzajowego lambda, co wymaga wprowadzania pojemników P, Qa pojemnikiem wyjściowym Rtak być 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);}

Niegolfowane i użytkowanie:

#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

Mathematica 112 bajtów

Prawdopodobnie można to poprawić. Chodzi o to, aby utworzyć tablicę 2D z drugim elementem używanym do śledzenia wynajmującego licznika i modyfikować długość każdej tablicy wejściowej.

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

Stosowanie

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

0

JavaScript (ES6), 131 bajtów

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

Nieznacznie nie golfista:

(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]
  • Jeśli obie tablice di ezawierają liczby, dodawana jest suma pierwszej liczby, sa pozostałe elementy są przetwarzane rekurencyjnie
  • Jeśli jedna z tablic zawiera liczby, tablica sum sjest dołączana do wyniku, ra druga tablica jest resetowana do tablicy początkowej
  • Jeśli obie tablice są puste, po prostu zwróć wynik z ostatnimi dołączonymi sumami.

Niestety to rozwiązanie nie ma bezwzględnej wydajności @ Arnauld's, ale przynajmniej uważam, że jest to piękne rozwiązanie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.