Array-Ausrichtung hinzugefügt

39

Einführung

Betrachten Sie zwei nicht leere Ganzzahl-Arrays: A = [0 3 2 2 8 4] und B = [7 8 7 2] . Um sie auszurichten , gehen wir wie folgt vor:

  1. Wiederholen Sie jedes Array so oft, bis die Gesamtlänge lcm (Länge (A), Länge (B)) erreicht ist . Hier steht lcm für das niedrigste gemeinsame Vielfache.

    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. Führen Sie eine elementweise Addition für die wiederholten Arrays durch und schneiden Sie das Ergebnis an jeder Position ab, an der eine der beiden Stellen eingeschnitten ist.

    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. Dieses Array von Arrays ist Ihr Ergebnis.

Die Aufgabe

Ihre Eingaben sind zwei nicht leere Felder mit ganzen Zahlen, und Ihre Ausgabe ist das Ergebnis der oben definierten Ausrichtungsaddition. Die Ein- und Ausgaben können in jedem vernünftigen Format erfolgen. Sie müssen sich nicht um einen Ganzzahlüberlauf sorgen, wenn Sie die Addition durchführen.

Regeln und Wertung

Sie können ein vollständiges Programm oder eine Funktion schreiben. Die niedrigste Byteanzahl gewinnt.

Testfälle

[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
quelle
C kann die Länge eines Arrays nicht ermitteln. Kann ich die Länge des Arrays als Argument anfordern oder am Anfang des Arrays speichern?
Katze
1
@cat Sie können die Längen als zusätzliche Argumente verwenden, wenn es keine andere Möglichkeit gibt, sie zu ermitteln.
Zgarb

Antworten:

9

JavaScript (ES6), 101 bis 99 Byte

Übernimmt die Eingabe als 2 Arrays. Gibt eine Zeichenfolge zurück.

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

Wie es funktioniert

Wir iterieren auf dem ersten Array amit einem Zeiger, iwährend wir einen anderen Zeiger jauf das zweite Array aktualisieren b. Die Summen a[i] + b[j]werden an die Ausgabezeichenfolge angehängt s. Ein Separator wird jedes Mal eingesetzt i == 0oder j == 0. Wir wiederholen diesen Vorgang, bis jer genau am Anfang und bam Ende einer Iteration steht.

Hinweis: Wenn der |Operator angewendet wird, a.map(...)wird er entweder auf NaN(wenn er amehr als ein Element enthält) oder auf den aktuellen Wert von j(wenn er agenau ein Element enthält) erzwungen. Daher ist a.map(...)|j == jin allen Fällen und hier sicher zu bedienen.

Testfälle

Arnauld
quelle
Ich habe nicht einmal versucht, die Antwort zu verstehen, +1 für die Notiz . Ich werde es kopieren und bei Bedarf zum Einfügen aufbewahren
edc65
6

Haskell, 84 79 Bytes

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

Meine erste Version war dieselbe in besser lesbarem Layout:

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

Verwenden einer lokalen Definition, um (%)zusätzliche Argumente für aund zu vermeiden b. Erstaunlicherweise ist dies fast dieselbe Lösung, die fast zur selben Zeit wie bei @ nimi angegeben wurde, von der ich die Idee hatte, nur eine Zeile für die lokale Definition zu verwenden.

Verwendungszweck:

*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
quelle
Oh, das ist eine gute Möglichkeit, die Summe vor das erste Element der Liste zu stellen. Weitaus kürzer als mein umständlicher !.
nimi
4

PHP, 126 120 Bytes

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

Probieren Sie es hier aus!

Anonyme Funktion, die das resultierende Array von Arrays zurückgibt.

Im Wesentlichen durchlaufen wir den Inhalt unserer beiden Arrays und modifizieren unseren Iterator um die Länge des Arrays, um das "Kopieren" zu simulieren. Wir nehmen jeden der Werte aus den Arrays, addieren sie und fügen sie einem Array in hinzu $c. Wenn wir das Ende eines unserer Eingabearrays erreichen (eine Aufteilung in Bezug auf die Herausforderung), beginnen wir, in ein neues Array zuzuweisen $c.

Der Grund für die do whileSchleife ist, dass unsere Bedingung auf basiert $i, die bei beginnt 0. Wenn wir eine Schleife verwenden, in der die Bedingung zu Beginn geprüft wird, wird die Schleife nicht ausgeführt

Wir beenden die Summierung erst, wenn wir gleichzeitig das Ende beider Arrays erreicht haben, was den LCM implizieren würde.

Xanderhall
quelle
Sollte das nicht sein $b[$i%$y]? Sie können 3 Bytes einsparen, indem Sie $x=count($a)zur ersten Verwendung von $xwechseln. das gleiche für $y=count($b)und ein Byte mit bitweise oder in der whileBedingung
Titus
Aber ich denke, anonyme Funktionen gelten als Schnipsel und sind daher keine gültigen Antworten.
Titus
@Titus Anonymous-Funktionen sind standardmäßig in Übereinstimmung mit Meta zulässig .
Zgarb
Vielen Dank für die Vorschläge @Titus, ich habe das nur irgendwie zusammengeschmissen, weil ich die anderen PHP-Antworten schlagen wollte: P
Xanderhall
4

Haskell, 87 84 Bytes

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

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

Einfache Rekursion. Basisfall: Beide Listen sind leer. Wenn nur einer leer ist, starten Sie den Computer mit einer Vollversion neu und starten Sie einen neuen Cluster in der Ausgabe. Wenn keines leer ist, stellen Sie die Summe dem from-Element voran.

Schauen Sie sich auch die Antwort von Christian Sievers an , die fast identisch ist und einige Sekunden zuvor gepostet wurde.

nimi
quelle
Bist du sicher? Gibt es eine Möglichkeit, die genauen Zeiten zu ermitteln?
Christian Sievers
@ChristianSievers: Ich weiß nicht, ob du die Zeiten direkt sehen kannst. Als die Zeiten unserer Bearbeitungen in Minuten angezeigt wurden, erinnere ich mich, dass Ihre einige Sekunden (ungefähr 20) früher als meine gezählt wurden.
Nimi
Sie haben Recht: Ich habe Zeitstempel im HTML-Quellcode dieser Seite gefunden
Christian Sievers
Bewegen Sie den Mauszeiger über die Zeit in "vor 2 Tagen beantwortet", um die genaue Uhrzeit anzuzeigen. (Hinweis: Dies ist eine Standardbenutzeroberfläche im Internet. Wenn Sie also eine genaue Uhrzeit wünschen, versuchen Sie, den Mauszeiger über die relative Uhrzeit zu bewegen, und wenn Sie jemals etwas implementieren, das die relative Uhrzeit anzeigt, zeigen Sie bitte die genaue Uhrzeit beim Hover an !)
wchargin
2

Oktave, 113 Bytes

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

Diese Funktion kann direkt aufgerufen werden, um sie in Klammern zu setzen und als (@ (a, b) ...) aufzurufen. ([1 2 3 4], [6 4 5])

rahnema1
quelle
1
Jetzt unterstützt TIO-Nexus Octave. Hier ist ein Link, um den Code zu testen
Luis Mendo
@ LuisMendo Vielen Dank, interessanter Service
rahnema1
2

CJam , 30 Bytes

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

Probieren Sie es online!

Nimmt Eingaben als Listenpaar entgegen.

Erläuterung

Die Idee ist, einige Marker in die Eingabearrays einzufügen (in Form von kurzen Strings), die angeben, wo das ausgerichtete Array endet und wo die Unterbrechungen in den Arrays eingefügt werden müssen. Auf diese Weise können wir vermeiden, das LCM berechnen zu müssen.

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
quelle
2

Jelly , 21 20 18 Bytes

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

Probieren Sie es online!

Wie es funktioniert

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

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

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

Ich kann nicht herausfinden, wie man die ganze for-Schleife in eine Zeile setzt.

Bearbeitungen:

  • Danke zgarb für das Speichern von 9 Bytes!
  • Danke vaultah für das Speichern von 3 Bytes!
  • Danke Mathmandan , der 5 Bytes spart!
Gurupad Mamadapur
quelle
Das gibt mir einen Fehler . Die gcdFunktion ist in fractions, nicht math.
Zgarb
@Zgarb Das Modul gcd in fractions ist veraltet . Sie können die Änderung hier überprüfen . Ich denke, Rexter verwendet die alte Version 3.4.3.
Gurupad Mamadapur
Gut, ich wusste nichts von dieser Veränderung. Sie sollten die Sprache jedoch als "Python 3.5" markieren, da sie in 3.4 oder früher nicht funktioniert. Sie können auch die Klammern um l*kund print(r);r=[]in der letzten Zeile haben.
Zgarb
Sind Sie sicher, dass Ihre Byteanzahl korrekt ist? Ich denke, es gibt nur 145 Bytes.
Gewölbe
1
Ich bekomme 142 Bytes. Verwenden Sie Windows? Windows zählt Zeilenumbrüche in der Regel mit jeweils 2 Byte, wobei hier jede Zeile als einzelnes Byte gezählt wird.
Mathmandan
2

Python 2, 119 Bytes

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

Übernimmt die Eingabe von stdin als zwei durch Komma getrennte Tupel und gibt die resultierenden Listen an stdout aus. Beendet durch Auslösen der ZeroDivisionErrorAusnahme, da dies zulässig zu sein scheint .

Wenn die Eingabe beispielsweise lautet (0, 3, 2, 2, 8, 4), (7, 8, 7, 2), wird das Programm gedruckt

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

zu stdout und die ausnahme traceback zu stderr.

Vaultah
quelle
Sie können das Programm beenden, indem Sie einen Fehler auslösen . Dann können Sie die Schleife möglicherweise in eine einzelne Zeile umwandeln.
Zgarb
2

J , 34 32 Bytes

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

Probieren Sie es online!

Erläuterung

[:(<;.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
Meilen
quelle
1

Haskell, 166 Bytes

Dies ist wahrscheinlich nicht der eleganteste Ansatz: Grundsätzlich erstellt die Funktion ?eine Liste der benötigten Länge mit diesen Summen und %schneidet diese Summe erneut auf. !ist die letzte Funktion, die diese beiden verbindet.

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]
fehlerhaft
quelle
Sie können inddurch koder etwas ersetzen , und es gibt einige unnötige Klammern um drop i lund map(+(-i))ind. Betrachten Sie auch zwei Fälle für %, mit Mustervergleich auf l.
Zgarb
1

[PHP], 183 152 135 Bytes

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

Schöne 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;
}

Ausgabe:

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
quelle
Zeichne auch bei mir mit diesen Tweaks: $i=$j=$k=0;ist unnötig, wenn du +$ifür die Array-Indizes in der anhängenden Zuweisung (-8 Bytes) etc. verwendest. $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, zweimal). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;braucht kein Leerzeichen (-1).
Titus
@Titus kann keinen $i=$j=0;Teil entfernen, da die ersten Werte von Arrays nicht korrekt sind. Ich habe die Logik ein wenig modifiziert, damit ich nicht weiß, wie ich ternäre Operatoren in diesem Fall implementieren soll. Danke für ++$iRatschläge.
Dexa
Versuchen Sie es unset($i);$A[+$i]. Der +wird nullin eine Ganzzahl umgewandelt 0.
Titus
if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;spart noch jeweils 5 Bytes. Speichern Sie eine weitere mit $f<2anstelle von $f!=2. und zwei weitere mit while($f=$f<3){...}statt while($f<2){$f=0;...}(initialisiert und setzt $fauf 1 zurück, es sei denn, es wird zweimal erhöht)
Titus
@ Titus Vielen Dank, es ist jetzt kürzer.
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

Probieren Sie es online!

( Golf Vorschläge willkommen. Ich denke, es gibt wahrscheinlich weitere 10 bis 15 Bytes, die daraus herausgepresst werden können. )

Nimmt Eingaben als zwei explizite Arrays (mit der @(...)Syntax) als Befehlszeilenargumente. Gibt eine Hashtabelle der resultierenden Arrays zurück, da mehrdimensionale Arrays in PowerShell merkwürdig werden können und dies konsistenter ist. Setzt einige anfängliche Variablen und gibt dann eine do/ until-Schleife erneut ein, wobei die Bedingung so lange gilt, bis $ider lcm-Wert des Arrays erreicht ist .

Bei jeder Schleifeniteration werden die entsprechenden Werte $aund addiert und $bals Array behandelt, ,(...)bevor sie $oan der entsprechenden Stelle in die Hash-Tabelle eingefügt werden $j. Die Array-Kapselung ist erforderlich, um eine arithmetische Addition zu verhindern - dies erzwingt +=stattdessen eine Überlastung der Array-Verkettung. Dann eine Bedingung an $xund $y(die Anzahl), um zu bestimmen, ob wir uns an einer Arraykante befinden - wenn ja, erhöhen wir diese $j.

Schließlich bleiben wir $oin der Pipeline und die Ausgabe ist implizit.
(Hinweis: Aufgrund der Art und Weise, wie PowerShell Hashtabellen mit der Standardeinstellung auflistet Write-Output, wird diese tendenziell "rückwärts" ausgegeben. Wie in Beispiel 1 befindet sich das sich ergebende Array "0" am "unteren Rand" der Ausgabe Wird verwendet, wenn Sie diesen Code zB in eine Rückgabevariable gekapselt haben. Es sieht nur seltsam aus, wenn er gedruckt wird.)

2 Bytes wurden gespart, indem $ x und $ y in die Array-Indizierung verschoben wurden, anstatt sie zu trennen (zwei Semikolons wurden gespeichert).

AdmBorkBork
quelle
1

Python 2, 113 Bytes

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
quelle
Könnte das s statt nots sein <1?
Zgarb
1

Python 3.5, 210 176 173 169 158 Bytes

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

Nimmt zwei Listen als Eingabe und druckt alle Listen.

Es ist meine erste Antwort und ich weiß noch nicht, wie man Golf spielt. Die Grundidee, die ich verwendet habe, besteht darin, zwei Zähler für jede Liste zu haben, die einen Split und eine aktuelle Liste angeben, an die die hinzugefügten Werte angehängt werden. Sobald ein Split auftritt, wird die aktuelle Liste gedruckt und eine neue leere erstellt.

  • 34 Bytes gespart : Danke an Dennis und TimmyD
  • 3 Bytes gespart : benutzte c und d für len (a) und len (b), stellte sich aber heraus, dass sie nicht nützlich waren
  • 4 Bytes gespart : Dank orlp wurden unerwünschte Klammern entfernt
  • 11 Bytes gespart : Einige Blöcke wurden neu angeordnet und zerkleinert
officialaimm
quelle
1
Hallo und willkommen bei Programming Puzzles & Code Golf! Wettbewerbsverbot bedeutet hier etwas anderes; Sie sollten das entfernen. Sie können einige Bytes einsparen, indem Sie Leerzeichen entfernen. Beispielsweise können die Zeilen 2 bis 5 werden x=[];c=len(a);d=len(b);e=f=0. Außerdem truekönnen sich 1, und x.append(a[e]+b[f])kann werden x+=a[e]+b[f],.
Dennis
1
Willkommen bei PPCG! Lesen Sie neben Dennis 'spezifischen Verbesserungen auch die Tipps zum Golfen in Python , um allgemeine Tipps und Tricks zu erhalten.
AdmBorkBork
1
ifund whileAnweisungen benötigen keine Klammern.
Orlp
1

Schläger 373 Bytes

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

Testen:

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

Ausgabe:

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

Clojure, 280 206 Bytes

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

Nun, das macht viel mehr Sinn. Generieren der elementweisen Summe, Hinzufügen von Positionsmetadaten, Hinzufügen des Summenwerts zu jeder 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: Ich hoffe, das zu verbessern, aber das ist das Sortierste, das ich derzeit habe.

(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 und wortreich:

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

Beginnt mit dem "Zusammenführen" eines unendlichen Zyklus von Sammlungen aund bfügt Metadaten zum Index jedes Elements in der Sammlung hinzu, bis beide Sequenzen wieder bei Index 0 beginnen.

Diese Sammlung cwird dann mit Partitionsdaten (eine kumulative Summe von Einsen und Nullen) zusammengeführt, partitioniert und das letzte Element (die Summe von Elementen) wird ausgewählt.

Ich denke, für signifikante Verbesserungen ist ein völlig anderer Ansatz erforderlich.

NikoNyrh
quelle
1

PHP, 150 121 119 Bytes

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

Anonyme Funktion nimmt Eingaben als Arrays entgegen.

Nervenzusammenbruch

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
quelle
0

C ++ 14, 206 Bytes

Als unnamed generic lambda, erfordern Eingang Behälter P, Qund Ausgangsbehälter Rzu sein wie 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 und Nutzung:

#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
quelle
0

Mathematica 112 Bytes

Dies könnte wahrscheinlich verbessert werden. Die Idee ist, ein 2D-Array mit dem zweiten Element zu erstellen, das verwendet wird, um den Lessor des Zählers zu verfolgen und die Länge jedes Eingangs-Arrays zu ändern.

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

Verwendungszweck

%@{{0,3,2,2,8,4},{7,8,7,2}}
Kelly Lowder
quelle
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([])

Leicht ungolfed:

(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]
  • Wenn sowohl Arrays dals eauch Zahlen enthalten, wird die Summe der ersten Zahl angehängts und die verbleibenden Elemente werden rekursiv verarbeitet
  • Wenn eines der Arrays Zahlen enthält, wird das Array mit den Summen san das Ergebnis angehängtr und das andere Array auf das ursprüngliche Array zurückgesetzt
  • Wenn beide Felder leer sind, geben Sie einfach das Ergebnis mit den letzten angehängten Summen zurück.

Leider hat diese Lösung nicht die skrupellose Effizienz von @ Arnauld's, aber ich denke zumindest, dass es eine schöne Lösung ist.

Neil
quelle