Aggiunta dell'allineamento di array


39

introduzione

Considera due array di numeri interi non vuoti, ad esempio A = [0 3 2 2 8 4] e B = [7 8 7 2] . Per eseguire l' aggiunta di allineamento su di essi, eseguiamo le seguenti operazioni:

  1. Ripetere ogni array abbastanza volte per avere lunghezza totale mcm (lunghezza (A), lunghezza (B)) . Qui mcm sta per il minimo comune multiplo.

    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. Esegui un'aggiunta in termini di elementi sugli array ripetuti e taglia il risultato in ogni posizione in cui è presente un taglio in uno di essi.

    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. Questa matrice di array è il tuo risultato.

L'obiettivo

I tuoi input sono due matrici di numeri interi non vuoti e il tuo output deve essere il risultato della loro aggiunta di allineamento, come definito sopra. Gli input e output possono essere in qualsiasi formato ragionevole. Non devi preoccuparti dell'overflow dei numeri interi quando esegui l'aggiunta.

Regole e punteggio

È possibile scrivere un programma completo o una funzione. Vince il conteggio dei byte più basso.

Casi test

[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 non ha modo di conoscere la lunghezza di un array - posso richiedere la lunghezza dell'array come argomento o averlo memorizzato all'inizio dell'array?
cat

1
@cat Puoi prendere le lunghezze come argomenti extra, se non c'è altro modo di ottenerle.
Zgarb,

Risposte:


9

JavaScript (ES6), 101 99 byte

Accetta input come 2 array. Restituisce una stringa.

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

Come funziona

Esaminiamo il primo array acon un puntatore idurante l'aggiornamento di un altro puntatore jnel secondo array b. Le somme a[i] + b[j]vengono aggiunte alla stringa di output s. Un separatore viene inserito ogni volta i == 0o j == 0. Ripetiamo questo processo fino a quando non jè tornato esattamente all'inizio della bfine di un'iterazione.

Nota: quando |viene applicato l' operatore, a.map(...)viene forzato su NaN(se acontiene più di un elemento) o sul valore corrente di j(se acontiene esattamente un elemento). Pertanto, a.map(...)|j == jin tutti i casi ed è sicuro da usare qui.

Casi test


Non ho nemmeno provato a capire la risposta, +1 per la nota .
Copierò

6

Haskell, 84 79 byte

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

La mia prima versione era la stessa in un layout più leggibile:

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

Utilizzo di una definizione locale per evitare di dover fornire (%)argomenti aggiuntivi per ae b. Sorprendentemente, questa è quasi la stessa soluzione data quasi contemporaneamente a quella di @nimi, da cui ho preso l'idea di usare solo una riga per la definizione locale.

Uso:

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

Oh, è un bel modo di anteporre la somma al primo elemento della lista. Molto più corto del mio ingombrante !.
nimi,

4

PHP, 126 120 byte

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

Provalo qui!

Funzione anonima che restituisce l'array risultante di array.

Fondamentalmente, eseguiamo il loop dei contenuti di entrambi i nostri array, modificando il nostro iteratore per la lunghezza dell'array per simulare 'copiandoli'. Prendendo ciascuno dei valori dagli array, li sommiamo e li aggiungiamo a un array in $c. Se raggiungiamo la fine di uno dei nostri array di input (una divisione, in termini di sfida), iniziamo ad assegnare in un nuovo array in $c.

Il motivo del do whileloop è perché la nostra condizione si basa su $i, che inizia alle 0. Se utilizziamo un loop in cui la condizione è selezionata all'inizio, il loop non funzionerebbe

Terminiamo la somma solo quando raggiungiamo la fine di entrambi gli array contemporaneamente, il che implicherebbe la LCM.


Non dovrebbe essere $b[$i%$y]? È possibile salvare 3 byte passando $x=count($a)al primo utilizzo di $x; stesso per $y=count($b)e un byte con bit per bit o nella whilecondizione
Tito

Ma penso che le funzioni anonime siano considerate frammenti e quindi non siano risposte valide.
Tito

@Titus Le funzioni anonime sono consentite di default secondo il consenso su Meta .
Zgarb,

Grazie per i suggerimenti @Titus, ho appena lanciato questo perché volevo battere le altre risposte PHP: P
Xanderhall

4

Haskell, 87 84 byte

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

Esempio di utilizzo: [0,3,2,2,8,4] # [7,8,7,2]-> [[7,11,9,4],[15,12],[7,5],[9,10,15,6]].

Ricorsione semplice. Caso base: entrambi gli elenchi sono vuoti. Se solo uno di essi è vuoto, riavviare con una versione completa e avviare un nuovo cluster nell'output. Se nessuno è vuoto, anteporre la somma all'elemento from.

Dai un'occhiata anche alla risposta di @Christian Sievers , che è quasi identica ed è stata pubblicata pochi secondi prima.


Sei sicuro? C'è un modo per ottenere gli orari esatti?
Christian Sievers,

@ChristianSievers: non so se puoi vedere i tempi direttamente. Quando i tempi delle nostre modifiche sono stati mostrati in pochi minuti, ricordo che il tuo è stato contato pochi secondi (circa 20) prima del mio.
nimi

Hai ragione: ho trovato i timestamp nel codice sorgente html di questa pagina
Christian Sievers,

Passa con il mouse su "risposta 2 giorni fa" per vedere l'ora esatta. (Suggerimento: questa è un'interfaccia utente standard su Internet, quindi (a) se si desidera un orario esatto, provare a passare il tempo relativo e (b) se si implementa qualcosa che mostra il tempo relativo, si prega di mostrare l'ora esatta al passaggio del mouse !)
wchargin,

2

Ottava, 113 byte

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

questa funzione è richiamabile direttamente per chiamarla tra parentesi e chiamare come (@ (a, b) ...) ([1 2 3 4], [6 4 5])


1
Ora TIO-Nexus supporta Octave. Ecco un link per testare il codice
Luis Mendo il

@LuisMendo Grazie, servizio interessante
rahnema1

2

CJam , 30 byte

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

Provalo online!

Accetta input come coppia di elenchi.

Spiegazione

L'idea è quella di inserire alcuni marcatori negli array di input (sotto forma di stringhe corte) che indicano dove finisce l'array allineato e dove dobbiamo inserire le interruzioni negli array. In questo modo possiamo evitare di dover calcolare l'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

Gelatina , 21 20 18 byte

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

Provalo online!

Come funziona

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

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

Non riesco a capire come mettere l'intero ciclo in una riga.

modifiche:

  • Grazie zgarb per aver salvato 9 byte!
  • Grazie vaultah per aver salvato 3 byte!
  • Grazie mathmandan risparmiando 5 byte!

Questo mi dà un errore . La gcdfunzione è attiva fractions, no math.
Zgarb,

@Zgarb il modulo gcd in frazioni è obsoleto , puoi controllare la modifica qui . Immagino che rexter stia usando la vecchia versione 3.4.3.
Gurupad Mamadapur,

Bene, non sapevo di questo cambiamento. Dovresti contrassegnare la lingua come "Python 3.5", poiché non funziona in 3.4 o precedenti. Inoltre, puoi rilasciare le parentesi l*ke avere print(r);r=[]l'ultima riga.
Zgarb,

Sei sicuro che il conteggio dei byte sia corretto? Penso che ci siano solo 145 byte.
vaultah,

1
Sto ricevendo 142 byte. Stai usando Windows? Windows di solito conta i newline come 2 byte ciascuno, ma qui ogni newline viene conteggiato come un singolo byte.
Mathmandan,

2

Python 2, 119 byte

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

Prende input da stdin come due tuple separate da virgola, restituisce gli elenchi risultanti a stdout. Termina sollevando l' ZeroDivisionErroreccezione, dal momento che sembra essere consentito .

Ad esempio, se l'ingresso è (0, 3, 2, 2, 8, 4), (7, 8, 7, 2), il programma stamperà

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

su stdout e l'eccezione traceback su stderr.


È possibile uscire dal programma generando un errore . Quindi potresti essere in grado di ottenere il ciclo in una sola riga.
Zgarb,

2

J , 34 32 byte

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

Provalo online!

Spiegazione

[:(<;.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 byte

Questo probabilmente non è l'approccio più elegante: in pratica la funzione ?crea un elenco della lunghezza necessaria con thesums e %sta tagliando di nuovo questa somma. !è l'ultima funzione che unisce quei due.

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]

È possibile sostituire indcon ko qualcosa del genere e ci sono alcune parentesi non necessarie in giro drop i le map(+(-i))ind. Considera anche di avere due casi per %, con la corrispondenza del modello attivata l.
Zgarb,

1

[PHP], 183 152 135 byte

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

Bella versione:

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

Produzione:

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

Disegna anche con me usando queste modifiche: $i=$j=$k=0;non è necessario se usi +$iecc. Per gli indici di array nell'assegnazione in aggiunta (-8 byte).$i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, due volte). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;non ha bisogno di spazio (-1).
Tito

@Titus non può rimuovere la $i=$j=0;parte poiché i primi valori delle matrici non saranno corretti. Ho modificato un po 'la logica, quindi non sono sicuro di come implementare gli operatori ternari in questo caso. Grazie per i ++$iconsigli
Dexa,

Prova unset($i);$A[+$i]. Il +cast verrà convertito nullin intero 0.
Tito

if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;salva ancora 5 byte ciascuno. Salvane uno in più con $f<2invece di $f!=2. e altri due con while($f=$f<3){...}invece diwhile($f<2){$f=0;...} (inizializza e reimposta $fsu 1 a meno che non venga incrementato due volte)
Tito

@Titus Grazie mille, ora è più corto.
Dexa,

1

PowerShell , 147 145 byte

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

Provalo online!

( Suggerimenti di golf benvenuti. Penso che probabilmente ci siano altri 10-15 byte che possono essere estratti da questo. )

Accetta input come due array espliciti (con la @(...)sintassi) come argomenti della riga di comando. Restituisce una tabella hash degli array risultanti, poiché gli array multidimensionali in PowerShell possono diventare strani e questo è più coerente. Imposta alcune variabili iniziali, quindi inserisce nuovamente un do/ untilloop, con il condizionale fino a quando non $iè il mcm dell'array conteggi .

Ad ogni iterazione del loop, sommiamo insieme i valori corrispondenti $ae li $btrattiamo come un array ,(...)prima di aggiungerlo nell'hashtable $onel punto appropriato $j. L'incapsulamento dell'array è necessario per impedire l'aggiunta aritmetica - questo invece costringe il +=sovraccarico alla concatenazione dell'array. Quindi, un condizionale su $xe $y(i conteggi) per determinare se siamo a bordo di un array - in tal caso, incrementiamo $j.

Infine, lasciamo $oin cantiere e l'output è implicito.
(NB: a causa del modo in cui PowerShell enumera gli hashtable con il valore predefinito Write-Output, questo tende ad essere output "arretrato"; come in, l'array risultante "0th" è sul "fondo" dell'output. L'hash stesso va bene e sarebbe usato bene se per esempio, incapsulato questo codice in una variabile di ritorno ... sembra strano quando viene stampato.)

Salvato 2 byte spostando $ xe $ y nell'indicizzazione dell'array anziché separarli (due punti e virgola salvati).


1

Python 2, 113 byte

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

Potrebbero invece notessere <1s?
Zgarb,

1

Python 3.5, 210 176 173 169 158 byte

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

Accetta due elenchi come input e stampa tutti gli elenchi.

È la mia prima risposta e non so ancora giocare a golf. L'idea di base che ho usato è di avere due contatori per ogni elenco che indicano una divisione e un elenco corrente in cui vengono aggiunti i valori aggiunti; non appena viene rilevata una divisione, stampiamo l'elenco corrente e ne creiamo uno vuoto.

  • 34 byte salvati : grazie a Dennis e TimmyD
  • 3 byte salvati : stava usando cod per len (a) e len (b), ma risulta che non erano utili
  • 4 byte salvati : grazie a orlp , rimosso la indesiderata
  • Salvati 11 byte : riorganizzati alcuni blocchi e li crunch giù

1
Salve e benvenuti a Programming Puzzles & Code Golf! Non competere significa qualcos'altro qui; dovresti rimuoverlo. Puoi risparmiare parecchi byte eliminando gli spazi bianchi. Ad esempio, le righe da 2 a 5 possono diventare x=[];c=len(a);d=len(b);e=f=0. Inoltre, truepuò diventare 1e x.append(a[e]+b[f])può diventare x+=a[e]+b[f],.
Dennis,

1
Benvenuti in PPCG! Oltre alle modifiche specifiche di Dennis, dai un'occhiata a Tips for Golfing in Python per ottenere alcuni suggerimenti e trucchi più generali.
AdmBorkBork,

1
ife le whiledichiarazioni non necessitano di parentesi.
orlp

1

Racchetta 373 byte

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

Ungolfed:

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

test:

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

Produzione:

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

1

Clojure, 280 206 byte

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

Bene, questo ha molto più senso. Generare la somma dal punto di vista degli elementi, aggiungere metadati posizionali, prendere mentre non l'abbiamo ancora ripetuto e mettere il valore della somma in ogni partizione.

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

Originale: spero di migliorare questo, ma questo è il più gentile che ho per ora.

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

Ungolfed e verbose:

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

Inizia "fondendo" un ciclo infinito di collezioni aeb , aggiunge metadati sull'indice di ciascun elemento all'interno della raccolta, impiega fino a quando entrambe le sequenze ricominciano dall'indice 0.

Questa raccolta c viene quindi unita ai dati di partizione (una somma cumulativa di uno e zero), partizionata e viene selezionato l'ultimo elemento (ovvero la somma degli elementi).

Penso che per miglioramenti significativi sia necessario un approccio totalmente diverso.


1

PHP, 150 121 119 byte

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

la funzione anonima accetta input come array.

abbattersi

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 byte

Come senza nome generico lambda, richiedono contenitori di input P, Qed il contenitore di uscita Rper essere come 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);}

Ungolfed e utilizzo:

#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 byte

Questo potrebbe probabilmente essere migliorato. L'idea è di creare un array 2D con il secondo elemento utilizzato per tracciare il locatore del contatore e mod la lunghezza di ciascun array di input.

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

uso

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

0

JavaScript (ES6), 131 byte

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

Leggermente non golfato:

(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]
  • Se entrambi gli array dee contengono numeri, viene aggiunta la somma del primo numeros e gli elementi rimanenti vengono elaborati in modo ricorsivo
  • Se uno degli array contiene numeri, l'array di somme sviene aggiunto al risultator e l'altro array viene reimpostato sull'array iniziale
  • Se entrambi gli array sono vuoti, è sufficiente restituire il risultato con le ultime somme aggiunte.

Purtroppo questa soluzione non ha l'efficienza spietata di @ Arnauld's, ma almeno penso che sia una soluzione bellissima.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.