Dizi hizalaması ekleme


39

Giriş

İki boş olmayan tamsayı dizisini göz önünde bulundurun, A = [0 3 2 2 8 4] ve B = [7 8 7 2] deyin . Gerçekleştirmek için hizalama ek üzerlerinde, aşağıdakileri yapın:

  1. Her bir diziyi, toplam uzunluğu lcm (uzunluk (A), uzunluk (B)) olacak kadar tekrarlayın . Burada lcm en düşük ortak katın kısaltmasıdır.

    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. Tekrarlanan dizilere eleman şeklinde ekleme yapın ve sonucu, her ikisinde de kesik olan her pozisyonda kesin.

    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. Bu dizi dizisi sizin sonucunuzdur.

Görev

Girdileriniz iki boş olmayan tam sayı dizisidir ve çıktınız yukarıda tanımlandığı gibi hizalama eklerinin bir sonucu olacaktır. Girişler ve çıkışlar herhangi bir makul formatta olabilir. Ekleme yaparken tamsayı taşması konusunda endişelenmenize gerek yok.

Kurallar ve puanlama

Tam bir program veya bir fonksiyon yazabilirsiniz. En düşük bayt sayısı kazanır.

Test durumları

[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, bir dizinin uzunluğunu bilmenin bir yoluna sahip değil - dizinin uzunluğunu bir argüman olarak isteyebilir miyim, yoksa dizinin başında depolanmış mı?
kedi

1
@ cat Başka bir yol yoksa, uzunlukları ekstra argüman olarak alabilirsiniz.
Zgarb

Yanıtlar:


9

JavaScript (ES6), 101 99 bayt

Girdiyi 2 dizi olarak alır. Bir dize döndürür.

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

Nasıl çalışır

İkinci diziye başka abir göstericiyi igüncellerken ilk dizgede bir gösterici ile jyineliyoruz b. Toplamlar a[i] + b[j]çıktı dizisine eklenir s. Her seferinde bir ayırıcı i == 0ya da yerleştirilir j == 0. Bu işlemi , bir yinelemenin sonunda jtam olarak geri dönene kadar tekrar ediyoruz b.

Not: Tüm |operatör uygulanır, a.map(...)ya da zorlanır olan NaN(varsa aveya akım değeri, birden fazla eleman içerir) j(eğer atam olarak bir eleman içerir). Bu nedenle, a.map(...)|j == jher durumda ve burada kullanmak güvenlidir.

Test durumları


Cevabı anlamaya bile çalışmadım, not için +1 . Gerektiğinde yapıştırmayı kopyalayacağım ve saklayacağım
edc65

6

Haskell, 84 79 bayt

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

İlk sürümüm daha okunaklı düzende aynıydı:

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

Yerel bir tanımını kullanarak vermek zorunda kalmamak için (%)ekstra argümanlar ave b. Şaşırtıcı bir şekilde, bu, yerel tanım için sadece bir satır kullanma fikrini aldığım @ nimi ile aynı anda verilen neredeyse aynı çözüm.

Kullanımı:

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

Bu, toplamı listenin ilk öğesine hazırlamak için güzel bir yol. Hantal benim çok daha kısa !.
nimi

4

PHP, 126 120 bayt

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

Burada dene!

Ortaya çıkan dizi dizisini döndüren adsız işlev.

Temel olarak, her iki dizimizin de içerisinden geçiyoruz, yineleyicimizi dizileri boyunca 'kopyalamayı' simüle edecek şekilde düzenliyoruz. Değerlerin her birini dizilerden alarak, onları bir araya getirip bir diziye ekleriz $c. Girdi dizilerimizden birinin sonuna ulaşırsak (zorluk açısından bir bölünme), içinde yeni bir diziye atanmaya başlarız $c.

Nedeni do whiledurumumuz dayalı olduğu için döngü olduğunu $ibaşlar, hangi 0. Koşulun başlangıçta kontrol edildiği bir döngü kullanırsak, döngü çalışmaz

Toplamı, yalnızca her iki dizinin sonuna aynı anda ulaştıktan sonra bitiririz; bu, LCM anlamına gelir.


Olmamalı mıydı $b[$i%$y]? $x=count($a)İlk kullanımına geçerek 3 bayt tasarruf edebilirsiniz $x; aynı $y=count($b)ve bir bit baytta veya whiledurumda bir bayt
Titus

Ancak anonim işlevlerin pasajlar olarak kabul edildiğini ve dolayısıyla geçerli bir cevap olmadığını düşünüyorum.
Titus,

@Titus Anonymous işlevlerine , Meta üzerinde fikir birliğine göre varsayılan olarak izin verilir .
Zgarb

Öneri @Titus için teşekkürler, ben sadece çok diğer PHP cevapları dövmek istedi neden bu birlikte attı: P
Xanderhall

4

Haskell, 87 84 bayt

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

Kullanım örneği: [0,3,2,2,8,4] # [7,8,7,2]-> [[7,11,9,4],[15,12],[7,5],[9,10,15,6]].

Basit özyineleme. Temel durum: iki liste de boş. Bunlardan yalnızca biri boşsa, tam sürümüyle yeniden başlatın ve çıktıda yeni bir küme başlatın. Hiçbiri boş değilse, toplamı from öğesine göre hazırlayın.

Ayrıca @Shristian Sievers'ın neredeyse aynı olan ve birkaç saniye önce yayınlanan cevabına da bir göz atın .


Emin misiniz? Kesin süreleri elde etmenin bir yolu var mı?
Christian Sievers

@ ChristianSievers: Zamanları doğrudan görebiliyor musunuz bilmiyorum. Düzenlemelerimizin zamanları dakikalar içinde gösterildiğinde, sizinkilerin benimkinden birkaç saniye önce (yaklaşık 20) ​​sayıldığını hatırlıyorum.
nimi

Haklısın: Bu sayfanın html kaynak kodunda zaman damgaları buldum
Christian Sievers

Tam zamanı görmek için "2 gün önce yanıtlandı" bölümündeki zamanın üzerine gelin. (İpucu: Bu, İnternet'teki standart bir UI'dir, bu nedenle (a) tam bir zaman istiyorsanız, göreli zamana gitmeyi deneyin ve (b) herhangi bir zaman göreceli zaman gösteren bir şey uygularsanız, lütfen vurgunun tam zamanını gösterin !)
wchargin

2

Oktav, 113 bayt

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

bu işlev parantez içine almak ve doğrudan (@ (a, b) ...) olarak çağırmak için çağrılabilir ([1 2 3 4], [6 4 5])


1
Şimdi TIO-Nexus Octave'ı destekliyor. İşte kodu test etmek için
Luis Mendo

@LuisMendo Teşekkürler, ilginç hizmet
rahnema1 16:16 16:16

2

CJam , 30 bayt

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

Çevrimiçi deneyin!

Bir liste çifti olarak girdi alır.

açıklama

Buradaki fikir, dizilerin bittiği yeri ve dizileri sonları nereye yerleştirmemiz gerektiğini gösteren girdi dizilerine (kısa dizeler biçiminde) bazı işaretleyicileri yerleştirmektir. Bu şekilde LCM'yi hesaplamaktan kaçınabiliriz.

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

Jöle , 21 20 18 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

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

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

Döngü için bütünün bir satırda nasıl yerleştirileceğini çözemiyorum.

Düzenlemeler:


Bu benim için bir hata veriyor . gcdFonksiyon olduğunu fractionsdeğil math.
Zgarb

@Zgarb kesir modülündeki gcd kullanımdan kaldırılmıştır , değişikliği buradan kontrol edebilirsiniz . Sanırım rexter eski sürümü kullanıyor 3.4.3.
Gurupad Mamadapur

Güzel, bu değişikliği bilmiyorum. Dili 3.4 ya da daha eski sürümlerde çalışmadığından, "Python 3.5" olarak işaretlemelisiniz. Ayrıca, parantez içine bırakın l*kve sahip print(r);r=[]son satırında.
Zgarb

Bayt sayınızın doğru olduğundan emin misiniz? Sanırım sadece 145 bayt var.
Vaultah

1
142 byte alıyorum. Windows kullanıyor musunuz? Windows genellikle yeni satırları 2 bayt olarak sayar, ancak burada her yeni satır tek bayt olarak sayılır.
mathmandan

2

Python 2, 119 bayt

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

Stdin'den virgülle ayrılmış iki tuple girdi alır, elde edilen listeleri stdout'a çıkarır. Buna izin verildiği için ZeroDivisionErroristisnayı yükselterek sona eriyor .

Örneğin, giriş ise (0, 3, 2, 2, 8, 4), (7, 8, 7, 2)program yazdıracaktır.

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

stdout ve istisna izlemesi stderr'e.


Bir hata atarak programdan çıkabilirsiniz . O zaman, döngüyü tek bir satıra sığdırabilirsiniz.
Zgarb

2

J , 3432 bayt

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

Çevrimiçi deneyin!

açıklama

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

Bu muhtemelen en zarif yaklaşım değildir: Temel olarak, fonksiyon ?, gerekli uzunluğun bir listesini thesums ile oluşturur ve %bu toplamı tekrar keser. !bu ikisini birleştiren son işlevdir.

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]

Sen değiştirebilir indtarafından kya da bir şey ve orada bazı gereksiz parantez etrafında drop i lve map(+(-i))ind. %Desen eşleşmesi için iki durumda da düşünün l.
Zgarb

1

[PHP], 183 152 135 bayt

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

Güzel versiyon:

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

Çıktı:

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

Bu tweaks kullanarak benimle bile çizin: ekleyen atama (-8 bayt) dizi dizinleri için vb $i=$j=$k=0;kullanırsanız gereksizdir +$i. $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, iki kez). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;boşluk gerektirmez (-1).
Titus,

@Titus, $i=$j=0;dizilerdeki ilk değerler doğru olmadığından bölümü kaldıramadı . Mantığı biraz değiştirdim, bu nedenle üçlü operatörlerin nasıl uygulanacağından emin değilim. Tavsiyeler için teşekkürler ++$i.
Dexa

Dene unset($i);$A[+$i]. +Döküm olacak nulltamsayıya 0.
Titus,

if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;hala her biri 5 bayt kaydeder. $f<2Bunun yerine bir tane daha kaydedin $f!=2. ve while($f=$f<3){...}bunun yerine iki tane daha (iki kez artırılmadıkça 1'e while($f<2){$f=0;...}sıfırlar ve sıfırlar $f)
Titus

@Titus Çok teşekkürler, şimdi daha kısa.
Dexa,

1

PowerShell , 147 145 bayt

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

Çevrimiçi deneyin!

( Golf önerileri memnuniyetle karşılanmaktadır. Bundan sıkılabilecek bir başka 10-15 bayt olduğunu düşünüyorum. )

Girdiyi iki açık dizi olarak ( @(...)sözdizimiyle) komut satırı argümanları olarak alır. Elde edilen dizilerin bir özetini döndürür, çünkü PowerShell'deki çok boyutlu diziler garipleşebilir ve bu daha tutarlıdır. Bazı başlangıç ​​değişkenlerini ayarlar, ardından tekrar a do/ untilloop'a girer , koşullu olmak , dizi sayımının lcm olanına kadar $iolur .

Her döngü yineleme, karşılık gelen $ave $bdeğerleri birlikte ekleriz , uygun noktada ,(...)karma tabloya eklemeden önce onu bir dizi olarak ele alırız . Dizi kapsülleme, aritmetik eklemeyi önlemek için gereklidir - bu , dizi birleştirmeyi aşırı yüklemeye zorlar . Sonra, bir dizi kenarında olup olmadığımızı belirlemek için bir koşullu ve (sayımlar) - öyleyse, artırırız .$o$j+=$x$y$j

Sonunda, $oboru hattında ayrılıyoruz ve çıktı kapalı.
(Not: PowerShell'in varsayılan olarak hashtable'ları nasıl numaralandırdığına bağlı olarak Write-Output, bu "geriye doğru" çıkma eğilimindedir; olduğu gibi, "0th" sonuç dizisi çıktının "altında" durur. Örneğin, bu kodu bir dönüş değişkeninde sakladıysanız, sadece para cezası kullanılır ... yazdırıldığında tuhaf görünüyor.)

$ X ve $ y dizilerini ayrı değil dizinin indeksine taşıyarak 2 bayt kurtarıldı (iki noktalı virgül kaydedildi).


1

Python 2, 113 bayt

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

Could notler olmak <1yerine s?
Zgarb

1

Python 3.5, 210 176 173 169 158 Bayt

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

Giriş olarak iki liste alır ve tüm listeleri yazdırır.

Bu benim ilk cevabım ve henüz golf oynamayı bilmiyorum. Kullandığım temel fikir, her liste için bir bölünmeyi ve eklenen değerlerin eklendiği bir geçerli listeyi gösteren iki sayacı kullanmak; Bir bölünmeye rastlanır karşılaşmaz mevcut listeyi yazdırır ve yeni bir tane boş bırakırız.

  • 34 bayt kurtarıldı : Dennis ve TimmyD sayesinde
  • Kaydedilen 3 bayt : len (a) ve len (b) için c ve d kullanıyordu, ancak işe yaramadıklarını ortaya koydu
  • 4 bayt kurtarıldı : orlp sayesinde , istenmeyen parantezi kaldırıldı
  • 11 bayt kurtarıldı : bazı blokları yeniden düzenledi ve kırdı

1
Merhaba, Programlama Puzzles & Code Golf'a hoş geldiniz! Rekabet etmemek burada başka bir şey ifade ediyor; Bunu kaldırmalısın. Beyaz boşlukları kaldırarak epeyce bayt tasarruf edebilirsiniz. Örneğin, 2 ila 5 arasındaki çizgiler olabilir x=[];c=len(a);d=len(b);e=f=0. Ayrıca, trueolabilir 1ve x.append(a[e]+b[f])olabilir x+=a[e]+b[f],.
Dennis,

1
PPCG'ye Hoşgeldiniz! Dennis'in özel tweaks'lerine ek olarak, daha genel ipuçları ve püf noktaları almak için Python'da Golf için İpuçları'a bakın .
AdmBorkBork

1
ifve whileifadelerde parantez gerekmez.
orlp

1

Raket 373 bayt

(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 yapmak:

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

Çıktı:

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

1

Clojure, 280 206 bayt

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

Peki bu çok daha mantıklı. Öğe-toplamı üretmek, konumsal meta veri eklemek, henüz tekrarlamadığımız zamanları almak ve toplam değeri her bölüme koymak.

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

Orijinal: Bunu geliştirmeyi umuyorum ama bu şu an için en iyi olanı.

(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 ve ayrıntılı:

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

Koleksiyonları sonsuz döngüsünü "birleştirme" tarafından başlatır ave bher iki dizileri tekrar indeksi 0 dan başlayana dek, koleksiyon içinde her öğenin endeksi meta ekler alır.

Bu koleksiyon cdaha sonra bölüm verileriyle (toplamlar ve sıfırların toplamı) birleştirilir, bölümlendirilir ve son öğe (öğelerin toplamı) seçilir.

Önemli gelişmeler için tamamen farklı bir yaklaşım gerektiğini düşünüyorum.


1

PHP, 150 121 119 bayt

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

anonim işlev diziyi girdi olarak alır.

Yıkmak

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 bayt

İsimsiz genel lambda gerektiren giriş kaplar olarak P, Qve çıkış, kabın Rgibi olmak 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 ve kullanım:

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

Bu muhtemelen geliştirilebilir. Buradaki fikir, her girdi dizisinin uzunluğundaki sayıcıyı izlemek için kullanılan ikinci elemanlı bir 2D dizi oluşturmaktır.

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

kullanım

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

0

JavaScript (ES6), 131 bayt

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

Biraz 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]
  • Diziler hem ise dve esayı içeren birinci sayının toplamı eklenir sve geri kalan elemanlar yinelemeli işlenir
  • Dizilerden biri sayı içeriyorsa, toplamlar dizisi ssonuçlara eklenir rve diğeri ilk dizisine sıfırlanır.
  • Her iki dizi de boşsa, sadece sonucu eklenen son toplamla döndürün.

Ne yazık ki bu çözüm @ Arnauld'un acımasız verimliliğine sahip değil, ama en azından bunun güzel bir çözüm olduğunu düşünüyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.