Ajout d'alignement de tableau

39

introduction

Considérons deux tableaux entiers non vides, disons A = [0 3 2 2 8 4] et B = [7 8 7 2] . Pour effectuer un ajout d'alignement sur eux, nous procédons comme suit:

  1. Répétez chaque tableau suffisamment de fois pour obtenir une longueur totale de 1 cm (longueur (A), longueur (B)) . Ici, lcm représente le plus petit commun multiple.

    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. Effectuez l'addition élément par élément sur les tableaux répétés et coupez le résultat à chaque position où il y a une coupure dans l'un ou l'autre.

    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. Ce tableau de tableaux est votre résultat.

La tâche

Vos entrées sont deux tableaux d'entiers non vides, et votre sortie doit être le résultat de leur ajout d'alignement, tel que défini ci-dessus. Les entrées et les sorties peuvent être dans n'importe quel format raisonnable. Vous n'avez pas à vous soucier du dépassement d'entier lors de l'ajout.

Règles et notation

Vous pouvez écrire un programme complet ou une fonction. Le plus petit nombre d'octets gagne.

Cas de 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]]
Zgarb
la source
C n'a pas de moyen de connaître la longueur d'un tableau - puis-je demander la longueur du tableau en tant qu'argument ou le stocker au début du tableau?
chat
1
@cat Vous pouvez utiliser les longueurs comme arguments supplémentaires, s'il n'y a pas d'autre moyen de les obtenir.
Zgarb

Réponses:

9

JavaScript (ES6), 101 99 octets

Prend l'entrée sous forme de 2 tableaux. Retourne une chaîne.

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

Comment ça marche

Nous itérons sur le premier tableau aavec un pointeur ilors de la mise à jour d'un autre pointeur jdans le second tableau b. Les sommes a[i] + b[j]sont ajoutées à la chaîne de sortie s. Un séparateur est inséré à chaque fois i == 0ou j == 0. Nous répétons ce processus jusqu'à ce qu'il jsoit exactement au début ou bà la fin d'une itération.

Remarque: Lorsque l' |opérateur est appliqué, il a.map(...)est contraint NaN(si acontient plus d'un élément) ou à la valeur actuelle de j(s'il acontient exactement un élément). Par conséquent, a.map(...)|j == jdans tous les cas et est sans danger pour utiliser ici.

Cas de test

Arnauld
la source
Je n'ai même pas essayé de comprendre la réponse, +1 pour la note . Je vais le copier et le garder pour le coller au besoin
edc65
6

Haskell, 84 79 octets

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

Ma première version était la même dans une mise en page plus lisible:

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

Utiliser une définition locale pour ne pas avoir à donner (%)d’arguments supplémentaires pour aet b. Étonnamment, c'est presque la même solution donnée presque au même moment que celle de @ nimi, de qui j'ai eu l'idée d'utiliser une seule ligne pour la définition locale.

Usage:

*Main> [0,3,2,2,8,4] # [7,8,7,2]
[[7,11,9,4],[15,12],[7,5],[9,10,15,6]]
Christian Sievers
la source
Oh, c’est une bonne façon d’ajouter la somme au premier élément de la liste. Bien plus court que mon encombrant !.
nimi
4

PHP, 126 120 octets

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

Essayez-le ici!

Fonction anonyme qui retourne le tableau résultant de tableaux.

Essentiellement, nous parcourons le contenu de nos deux tableaux, en modifiant notre itérateur en fonction de la longueur du tableau pour les simuler en les "copiant". En prenant chacune des valeurs des tableaux, nous les additionnons et les ajoutons à un tableau dans $c. Si nous arrivons à la fin de l’un de nos tableaux d’entrée (une division, en termes de défi), nous commençons à assigner un nouveau tableau dans $c.

La raison de la do whileboucle est parce que notre condition est basée sur $i, qui commence à 0. Si nous utilisons une boucle où la condition est vérifiée au début, la boucle ne serait pas exécutée

Nous ne finissons la sommation que lorsque nous atteignons la fin des deux tableaux en même temps, ce qui impliquerait le LCM.

Xanderhall
la source
Ça ne devrait $b[$i%$y]pas être ça ? Vous pouvez économiser 3 octets en passant $x=count($a)à la première utilisation de $x; idem pour $y=count($b)et un octet avec bitwise ou dans l' whileétat
Titus
Mais je pense que les fonctions anonymes sont considérées comme des extraits et ne constituent donc pas une réponse valable.
Titus
@Titus Les fonctions anonymes sont autorisées par défaut conformément au consensus sur Meta .
Zgarb
Merci pour les suggestions @Titus, je viens juste de jeter cela ensemble parce que je voulais battre les autres réponses PHP: P
Xanderhall
4

Haskell, 87 84 octets

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

Exemple d'utilisation: [0,3,2,2,8,4] # [7,8,7,2]-> [[7,11,9,4],[15,12],[7,5],[9,10,15,6]].

Récursion simple. Cas de base: les deux listes sont vides. Si un seul d'entre eux est vide, redémarrez avec une version complète et démarrez un nouveau cluster dans la sortie. Si aucun n'est vide, ajoutez la somme à l'élément from.

Regardez aussi la réponse de @Christian Sievers , qui est presque identique et a été postée quelques secondes plus tôt.

nimi
la source
Êtes-vous sûr? Y at-il un moyen d'obtenir les heures exactes?
Christian Sievers
@ChristianSievers: Je ne sais pas si vous pouvez voir les heures directement. Lorsque les temps de nos modifications ont été indiqués en minutes, je me souviens que votre compte a été compté quelques secondes (environ 20) plus tôt que le mien.
nimi
Vous avez raison: j'ai trouvé les horodatages dans le code source html de cette page
Christian Sievers
Survolez le temps "réponse il y a 2 jours" pour voir l'heure exacte. (Astuce: il s'agit d'une interface utilisateur standard sur Internet, donc (a) si vous voulez une heure exacte, essayez de survoler l'heure relative, et (b) si vous implémentez quelque chose qui affiche l'heure relative, veuillez indiquer l'heure exacte en survol. !)
wchargin
2

Octave, 113 octets

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

cette fonction est directement appelable pour l'appeler, la placer entre parenthèses et appeler comme (@ (a, b) ...) ([1 2 3 4], [6 4 5])

rahnema1
la source
1
Maintenant, TIO-Nexus supporte Octave. Voici un lien pour tester le code
Luis Mendo
@LuisMendo Merci, service intéressant
rahnema1
2

CJam , 30 octets

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

Essayez-le en ligne!

Prend les entrées comme une paire de listes.

Explication

L'idée est d'insérer dans les tableaux d'entrée des marqueurs (sous la forme de chaînes courtes) indiquant l'endroit où le tableau aligné se termine et où nous devons insérer les ruptures dans les tableaux. De cette façon, nous pouvons éviter de devoir calculer le 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.
Martin Ender
la source
2

Jelly , 21 20 18 octets

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

Essayez-le en ligne!

Comment ça marche

ṁ€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).
Dennis
la source
2

Python 3.5 - ( 146 137 134 130 + 12) = 142 octets

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

Je n'arrive pas à comprendre comment mettre la boucle complète en une ligne.

Modifications:

Gurupad Mamadapur
la source
Cela donne une erreur pour moi . La gcdfonction est dans fractions, pas math.
Zgarb
@Zgarb le module gcd en fractions est obsolète , vous pouvez vérifier le changement ici . Je suppose que rexter utilise l'ancienne version 3.4.3.
Gurupad Mamadapur
Bien, je n'étais pas au courant de ce changement. Vous devez toutefois marquer le langage comme "Python 3.5", car il ne fonctionne pas dans 3.4 ou une version antérieure. En outre, vous pouvez supprimer les parenthèses l*ket les avoir print(r);r=[]sur la dernière ligne.
Zgarb
Etes-vous sûr que votre nombre d'octets est correct? Je pense qu'il n'y a que 145 octets.
vaultah
1
Je reçois 142 octets. Utilisez-vous Windows? Windows compte généralement les nouvelles lignes comme 2 octets chacune, mais ici chaque nouvelle ligne est comptée comme un seul octet.
mathmandan
2

Python 2, 119 octets

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

Prend l'entrée de stdin sous la forme de deux tuples séparés par une virgule, affiche les listes résultantes dans stdout. Termine en levant l' ZeroDivisionErrorexception, puisque cela semble être autorisé .

Par exemple, si l'entrée est (0, 3, 2, 2, 8, 4), (7, 8, 7, 2), le programme imprimera

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

sur la sortie standard et l’exception traceback vers stderr.

vaultah
la source
Vous pouvez quitter le programme en générant une erreur . Ensuite, vous pourrez peut-être insérer la boucle dans une seule ligne.
Zgarb
2

J , 34 32 octets

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

Essayez-le en ligne!

Explication

[:(<;.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
milles
la source
1

Haskell, 166 octets

Ce n’est probablement pas l’approche la plus élégante: en gros, la fonction ?crée une liste de la longueur requise avec ces sommes et %réduit ce montant. !est la dernière fonction qui fusionne les deux.

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]
flawr
la source
Vous pouvez remplacer indpar kou autre chose, et il y a des parenthèses inutiles autour de drop i let map(+(-i))ind. Pensez également à avoir deux cas pour %, avec correspondance de motif activée l.
Zgarb
1

[PHP], 183 152 135 octets

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

Belle version:

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

Sortie:

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
Dexa
la source
Dessinez même avec moi en utilisant ces réglages: $i=$j=$k=0;inutile si vous utilisez +$ietc. pour les index de tableau dans l'affectation ajoutée (-8 octets). $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, deux fois). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;n'a pas besoin d'espace (-1).
Titus
@ Titus ne peut pas supprimer une $i=$j=0;partie car les premières valeurs des tableaux ne seront pas correctes. J'ai un peu modifié la logique pour ne pas savoir comment implémenter les opérateurs ternaires dans ce cas. Merci pour les ++$iconseils.
Dexa
Essayez unset($i);$A[+$i]. Le +cast va en nullentier 0.
Titus
if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;enregistre encore 5 octets chacun. Sauver un plus avec $f<2au lieu de $f!=2. et deux autres avec while($f=$f<3){...}au lieu de while($f<2){$f=0;...}(initialise et réinitialise $fà 1 à moins d’être incrémenté deux fois)
Titus
@Titus Merci beaucoup, c'est plus court maintenant.
Dexa
1

PowerShell , 147 145 octets

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

Essayez-le en ligne!

(Les suggestions de golf sont les bienvenues. J’ai le sentiment qu’il est probablement possible de supprimer 10 à 15 octets supplémentaires. )

Prend les entrées sous forme de deux tableaux explicites (avec la @(...)syntaxe) comme arguments de ligne de commande. Renvoie une table de hachage des tableaux résultants, car les tableaux multidimensionnels de PowerShell peuvent devenir bizarres et cela est plus cohérent. Définit des variables initiales, puis entre à nouveau dans une boucle do/ until, avec la condition conditionnelle jusqu’à ce que $ile nombre de cm du tableau compte .

A chaque itération de la boucle, nous additionnons les valeurs correspondantes $aet correspondantes, nous les $btraitons comme un tableau ,(...)avant de l’ajouter à la table $ode hachage à l’emplacement approprié $j. L'encapsulation de matrice est nécessaire pour empêcher l'addition arithmétique - ceci oblige la +=surcharge à la concaténation de matrice à la place. Ensuite, une condition sur $xet $y(les comptes) pour déterminer si nous sommes au bord du tableau - si c'est le cas, nous incrémentons $j.

Enfin, nous partons $osur le pipeline et la sortie est implicite.
(NB: En raison de la façon dont PowerShell énumère les hashtables avec les valeurs par défaut Write-Output, ceci a tendance à être "en amont"; comme dans, le "0ème" tableau résultant est sur le "bas" de la sortie. Le hachage est correct et utilisé très bien si, par exemple, vous encapsulez ce code dans une variable de retour ... cela a l'air bizarre quand il est imprimé.)

Vous avez enregistré 2 octets en déplaçant $ x et $ y dans l'indexation du tableau plutôt que de les séparer (deux points-virgules enregistrés).

AdmBorkBork
la source
1

Python 2, 113 octets

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
orlp
la source
Le nots pourrait être <1s à la place?
Zgarb
1

Python 3.5, 210 176 173 169 158 octets

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

Prend deux listes en entrée et imprime toutes les listes.

C'est ma première réponse et je ne sais pas encore jouer au golf. L’idée de base que j’ai utilisée est d’avoir deux compteurs pour chaque liste qui indiquent une scission et une liste en cours où les valeurs ajoutées sont ajoutées; Dès qu'une scission se produit, nous imprimons la liste actuelle et en créons une nouvelle.

  • 34 octets sauvés : Merci à Dennis et TimmyD
  • Sauvegardé 3 octets : utilisait c et d pour len (a) et len ​​(b), mais s’avère qu’ils ne sont pas utiles
  • 4 octets enregistrés : grâce à orlp , suppression de la paranthèse indésirable
  • 11 octets sauvegardés : réarrangez quelques blocs et réduisez-les
fonctionnaire
la source
1
Bonjour et bienvenue à la programmation de Puzzles & Code Golf! Non-concurrence signifie autre chose ici; vous devriez l'enlever. Vous pouvez économiser pas mal d’octets en éliminant les espaces. Par exemple, les lignes 2 à 5 peuvent devenir x=[];c=len(a);d=len(b);e=f=0. Aussi, truepeut devenir 1et x.append(a[e]+b[f])peut devenir x+=a[e]+b[f],.
Dennis
1
Bienvenue chez PPCG! En plus des ajustements spécifiques de Dennis, consultez Tips for Golfing in Python pour obtenir des astuces et des astuces plus générales.
AdmBorkBork
1
ifet les whiledéclarations n'ont pas besoin de parenthèses.
Orlp
1

Raquette 373 octets

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

Essai:

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

Sortie:

'((5))
'((16) (17) (12) (11))
'((7 11 9 4) (15 12) (7 5) (9 10 15 6))
rnso
la source
1

Clojure, 280 206 octets

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

Cela a beaucoup plus de sens. Générer la somme par élément, ajouter des métadonnées de position, prendre pendant que nous n'avons pas encore répété et attribuer la valeur de somme à chaque partition.

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

Original: J'espère améliorer cela, mais c'est le cas le plus sérieux que j'ai pour le moment.

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

Commence par "fusionner" un cycle infini de collections aet b, ajoute des métadonnées sur l'index de chaque élément dans la collection, jusqu'à ce que les deux séquences recommencent à partir de l'index 0.

Cette collection cest ensuite fusionnée avec les données de partition (une somme cumulative de 1 et de zéros), partitionnée et le dernier élément (la somme d'éléments) est sélectionné.

Je pense que pour des améliorations significatives, une approche totalement différente est nécessaire.

NikoNyrh
la source
1

PHP, 150 121 119 octets

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

fonction anonyme prend l'entrée sous forme de tableaux.

panne

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;
Titus
la source
0

C ++ 14, 206 octets

Comme lambda générique sans nom, nécessitant des conteneurs d'entrée P, Qet le conteneur de sortie Rpour être comme 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 et utilisation:

#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;
}
Karl Napf
la source
0

Mathematica 112 octets

Cela pourrait probablement être amélioré. L'idée est de créer un tableau 2D avec le deuxième élément utilisé pour suivre le bailleur du compteur i mod la longueur de chaque tableau d'entrée.

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

Usage

%@{{0,3,2,2,8,4},{7,8,7,2}}
Kelly Lowder
la source
0

JavaScript (ES6), 131 octets

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

Légèrement non-golfé:

(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]
  • Si les deux tableaux det econtiennent des chiffres, la somme du premier numéro est ajouté às et les éléments restants sont traités de manière récursive
  • Si l'un des tableaux contient des nombres, le tableau des sommes sest ajouté au résultat.r et l'autre tableau est réinitialisé sur son tableau initial.
  • Si les deux tableaux sont vides, renvoyez simplement le résultat avec les dernières sommes ajoutées.

Malheureusement, cette solution n'a pas l'efficacité impitoyable de @ Arnauld, mais au moins, je pense que c'est une belle solution.

Neil
la source