Penambahan susunan larik

39

pengantar

Pertimbangkan dua array integer yang tidak kosong, misalkan A = [0 3 2 2 8 4] dan B = [7 8 7 2] . Untuk melakukan penambahan pelurusan pada mereka, kami melakukan hal berikut:

  1. Ulangi setiap larik cukup kali untuk memiliki panjang total lcm (panjang (A), panjang (B)) . Di sini lcm merupakan kelipatan umum terendah.

    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. Lakukan penambahan elemen-bijaksana pada array berulang, dan potong hasilnya di setiap posisi di mana ada pemotongan di salah satu dari mereka.

    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. Array array ini adalah hasil Anda.

Tugas

Input Anda adalah dua array integer yang tidak kosong, dan output Anda akan menjadi hasil penambahan alignment, seperti yang didefinisikan di atas. Input dan output dapat dalam format yang masuk akal. Anda tidak perlu khawatir tentang integer overflow saat melakukan penambahan.

Aturan dan penilaian

Anda dapat menulis program atau fungsi lengkap. Hitungan byte terendah menang.

Uji kasus

[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
sumber
C tidak memiliki cara untuk mengetahui panjang array - dapatkah saya meminta panjang array sebagai argumen, atau menyimpannya di awal array?
kucing
1
@ kucing Anda bisa mengambil argumen panjang sebagai argumen tambahan, jika tidak ada cara lain untuk mendapatkannya.
Zgarb

Jawaban:

9

JavaScript (ES6), 101 99 byte

Mengambil input sebagai 2 array. Mengembalikan string.

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

Bagaimana itu bekerja

Kita beralih pada array pertama adengan sebuah pointer isambil memperbarui pointer lain jke dalam array kedua b. Jumlahnya a[i] + b[j]ditambahkan ke string output s. Pemisah dimasukkan setiap kali i == 0atau j == 0. Kami mengulangi proses ini sampai jkembali tepat di awal bpada akhir iterasi.

Catatan: Ketika |operator diterapkan, a.map(...)dipaksa untuk NaN(jika amengandung lebih dari satu elemen) atau nilai saat ini j(jika amengandung tepat satu elemen). Karena itu, a.map(...)|j == jdalam semua kasus dan aman digunakan di sini.

Uji kasus

Arnauld
sumber
Saya bahkan belum mencoba memahami jawabannya, +1 sebagai catatan . Saya akan menyalin dan menyimpannya untuk menempel ketika dibutuhkan
edc65
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

Versi pertama saya sama dalam tata letak yang lebih mudah dibaca:

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

Menggunakan definisi lokal untuk menghindari keharusan memberikan (%)argumen tambahan untuk adanb . Hebatnya, ini adalah solusi yang hampir sama diberikan pada waktu yang hampir bersamaan dengan @ nimi, dari siapa saya mengambil ide untuk menggunakan hanya satu baris untuk definisi lokal.

Pemakaian:

*Main> [0,3,2,2,8,4] # [7,8,7,2]
[[7,11,9,4],[15,12],[7,5],[9,10,15,6]]
Sievers Kristen
sumber
Oh, itu cara yang bagus untuk menambahkan jumlah ke elemen pertama dari daftar. Jauh lebih pendek dari yang rumit saya !.
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;};

Coba di sini!

Fungsi anonim yang mengembalikan array array yang dihasilkan.

Pada dasarnya, kita mengulang isi kedua array kita, memodifikasi iterator kita dengan panjang array untuk mensimulasikan 'menyalin' mereka. Mengambil masing-masing nilai dari array, kami menjumlahkannya dan menambahkannya ke dalam array $c. Jika kami mencapai akhir dari salah satu array input kami (pemisahan, dalam hal tantangan), kami mulai menugaskan ke dalam array baru di $c.

Alasan untuk do while loop adalah karena kondisi kami didasarkan pada $i, yang dimulai pada 0. Jika kita menggunakan loop di mana kondisi diperiksa di awal, loop tidak akan berjalan

Kami hanya mengakhiri penjumlahan begitu kami mencapai akhir dari kedua array pada saat yang sama, yang akan menyiratkan LCM.

Xanderhall
sumber
Bukankah seharusnya begitu $b[$i%$y]? Anda dapat menghemat 3 byte dengan pindah $x=count($a)ke penggunaan pertama $x; sama untuk $y=count($b)dan satu byte dengan bitwise atau dalam whilekondisi
Titus
Tapi saya pikir fungsi anonim dianggap potongan dan karenanya tidak ada jawaban yang valid.
Titus
@Titus Anonim fungsi diizinkan secara default sesuai konsensus di Meta .
Zgarb
Terima kasih atas saran @Titus, saya hanya sedikit melemparkan ini bersama-sama karena saya ingin mengalahkan jawaban PHP lainnya: 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

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

Rekursi sederhana. Kasing dasar: kedua daftar kosong. Jika hanya satu yang kosong, mulai ulang dengan versi lengkap dan mulai cluster baru di output. Jika tidak ada yang kosong, tambahkan jumlah ke elemen from.

Lihat juga jawaban @Christian Sievers , yang hampir identik dan telah diposting beberapa detik sebelumnya.

nimi
sumber
Apakah kamu yakin Apakah ada cara untuk mendapatkan waktu yang tepat?
Christian Sievers
@ChristianSievers: Saya tidak tahu apakah Anda bisa melihat waktu secara langsung. Ketika waktu pengeditan kami ditampilkan dalam hitungan menit, saya ingat bahwa pengeditan Anda dihitung beberapa detik (sekitar 20) lebih awal dari saya.
nimi
Anda benar: Saya menemukan cap waktu di kode sumber html halaman ini
Christian Sievers
Arahkan kursor ke waktu di "jawab 2 hari yang lalu" untuk melihat waktu yang tepat. (Petunjuk: ini adalah UI standar di internet, jadi (a) jika Anda ingin waktu yang tepat, coba arahkan waktu relatif, dan (b) jika Anda pernah menerapkan sesuatu yang menunjukkan waktu relatif, harap tunjukkan waktu yang tepat di arahkan !)
wchargin
2

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

fungsi ini secara langsung dapat dipanggil untuk menyebutnya letakkan di dalam tanda kurung dan panggil sebagai (@ (a, b) ...) ([1 2 3 4], [6 4 5])

rahnema1
sumber
1
Sekarang TIO-Nexus mendukung Octave. Berikut tautan untuk menguji kode
Luis Mendo
@LuisMendo Terima kasih, layanan menarik
rahnema1
2

CJam , 30 byte

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

Cobalah online!

Mengambil input sebagai pasangan daftar.

Penjelasan

Idenya adalah untuk memasukkan beberapa penanda ke dalam array input (dalam bentuk string pendek) yang menunjukkan di mana array yang disejajarkan berakhir, dan di mana kita perlu memasukkan jeda pada array. Dengan cara ini kita dapat menghindari keharusan menghitung 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
sumber
2

Jelly , 21 20 18 byte

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

Cobalah online!

Bagaimana itu bekerja

ṁ€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
sumber
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=[]

Saya tidak tahu bagaimana cara meletakkan keseluruhan untuk loop dalam satu baris.

Suntingan:

  • Terima kasih zgarb untuk menghemat 9 byte!
  • Terima kasih vaultah karena telah menghemat 3 byte!
  • Terima kasih mathmandan menghemat 5 byte!
Gurupad Mamadapur
sumber
Ini memberikan kesalahan bagi saya . The gcdfungsi di fractions, tidak math.
Zgarb
@Zgarb , modul pecahan gcd sudah tidak digunakan lagi , Anda dapat memeriksa perubahannya di sini . Saya kira rexter menggunakan versi lama 3.4.3.
Gurupad Mamadapur
Rapi, saya tidak tahu tentang perubahan ini. Anda harus menandai bahasa sebagai "Python 3.5", karena itu tidak bekerja di 3.4 atau sebelumnya. Anda juga dapat meletakkan tanda kurung di sekitar l*kdan ada print(r);r=[]di baris terakhir.
Zgarb
Apakah Anda yakin jumlah byte Anda benar? Saya pikir hanya ada 145 byte.
vaultah
1
Saya mendapatkan 142 byte. Apakah Anda menggunakan Windows? Windows biasanya menghitung baris baru masing-masing 2 byte, tetapi di sini setiap baris baru dihitung sebagai satu 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]))

Mengambil input dari stdin ketika dua tupel dipisahkan oleh koma, menampilkan daftar yang dihasilkan ke stdout. Berakhir dengan menaikkan ZeroDivisionErrorpengecualian, sejak itu tampaknya diizinkan .

Misalnya, jika inputnya adalah (0, 3, 2, 2, 8, 4), (7, 8, 7, 2), program akan mencetak

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

ke stdout dan pengecualian traceback ke stderr.

kubah
sumber
Anda dapat keluar dari program dengan melemparkan kesalahan . Maka Anda mungkin bisa mendapatkan loop menjadi satu baris.
Zgarb
2

J , 34 32 byte

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

Cobalah online!

Penjelasan

[:(<;.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
mil
sumber
1

Haskell, 166 byte

Ini mungkin bukan pendekatan yang paling elegan: Pada dasarnya fungsi ?membuat satu daftar panjang yang dibutuhkan dengan jendela, dan %memotong jumlah ini lagi. !adalah fungsi terakhir yang menggabungkan keduanya.

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]
cacat
sumber
Anda dapat mengganti inddengan katau sesuatu, dan ada beberapa tanda kurung yang tidak perlu di sekitar drop i ldan map(+(-i))ind. Pertimbangkan juga memiliki dua kasing %, dengan pencocokan pola aktif 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;}

Versi bagus:

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

Keluaran:

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
sumber
Gambarlah dengan saya menggunakan tweak ini: $i=$j=$k=0;tidak perlu jika Anda menggunakan +$idll untuk indeks array dalam penugasan menambahkan (-8 byte). $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, dua kali). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;tidak membutuhkan ruang (-1).
Titus
@Titus tidak dapat menghapus $i=$j=0;bagian karena nilai pertama dari array tidak akan benar. Saya telah memodifikasi logika sedikit jadi tidak yakin bagaimana menerapkan operator ternary dalam kasus ini. Terima kasih atas ++$isarannya.
Dexa
Coba unset($i);$A[+$i]. The +akan dilemparkan nullke bilangan bulat 0.
Titus
if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;masing-masing masih menyimpan 5 byte. Simpan satu lagi dengan $f<2bukan $f!=2. dan dua lainnya dengan while($f=$f<3){...}sebagai gantinya while($f<2){$f=0;...}(menginisialisasi dan me-reset $fke 1 kecuali itu meningkat dua kali)
Titus
@Titus Terima kasih banyak, sekarang lebih pendek.
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

Cobalah online!

( Saran golf diterima. Saya merasa mungkin ada 10 hingga 15 byte yang bisa diperas dari ini. )

Mengambil input sebagai dua array eksplisit (dengan @(...)sintaks) sebagai argumen baris perintah. Mengembalikan hashtable dari array yang dihasilkan, karena array multidimensi di PowerShell bisa menjadi aneh, dan ini lebih konsisten. Set beberapa variabel awal, kemudian memasuki do/ untillingkaran lagi, dengan makhluk bersyarat sampai $iadalah lcm dari jumlah array yang .

Setiap iterasi loop, kami menambahkan korespondensi $adan $bnilai - nilai bersama-sama, memperlakukannya sebagai array ,(...)sebelum menambahkannya ke dalam hashtable $odi tempat yang sesuai $j. Enkapsulasi array diperlukan untuk mencegah penambahan aritmatika - ini memaksa +=overload untuk menggabungkan array sebagai gantinya. Kemudian, tergantung pada $xdan $y(jumlah) untuk menentukan apakah kita berada di tepi array - jika demikian, kita menambah$j .

Akhirnya, kami keluar $odari jalur pipa dan hasilnya tersirat.
(NB: Karena cara PowerShell menyebutkan hashtables dengan defaultWrite-Output , ini cenderung menjadi output "terbelakang"; seperti pada, array hasil "0" ada di "bawah" dari output. Hash itu sendiri baik-baik saja, dan akan menjadi digunakan dengan baik jika Anda misalnya, mengenkapsulasi kode ini dalam variabel kembali ... itu hanya terlihat aneh ketika dicetak.)

Menyimpan 2 byte dengan memindahkan $ x dan $ y ke dalam indeks array daripada memisahkan (menyimpan dua titik koma).

AdmBorkBork
sumber
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
orlp
sumber
Mungkinkah nots menjadi <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

Mengambil dua daftar sebagai input dan mencetak semua daftar.

Ini jawaban pertama saya dan saya belum tahu cara bermain golf. Ide dasar yang saya gunakan adalah memiliki dua penghitung untuk setiap daftar yang menunjukkan perpecahan dan daftar saat ini di mana nilai tambah ditambahkan ke; segera setelah pemecahan terjadi, kami mencetak daftar saat ini dan membuat yang kosong baru.

  • Disimpan 34 byte : Terima kasih kepada Dennis dan TimmyD
  • Disimpan 3 byte : menggunakan c dan d untuk len (a) dan len (b), tetapi ternyata tidak berguna
  • Disimpan 4 byte : Terima kasih kepada orlp , hapus paranthesis yang tidak diinginkan
  • Disimpan 11 byte : menyusun ulang beberapa blok dan mengelompokkannya
officialaimm
sumber
1
Hai, dan selamat datang di Programming Puzzles & Code Golf! Tidak bersaing berarti sesuatu yang lain di sini; Anda harus menghapusnya. Anda dapat menyimpan beberapa byte dengan menghilangkan spasi. Misalnya, garis 2 hingga 5 dapat menjadi x=[];c=len(a);d=len(b);e=f=0. Juga, truebisa menjadi 1, dan x.append(a[e]+b[f])bisa menjadi x+=a[e]+b[f],.
Dennis
1
Selamat datang di PPCG! Selain tweak khusus Dennis, lihat Tips untuk Bermain Golf di Python untuk mendapatkan beberapa petunjuk dan trik yang lebih umum.
AdmBorkBork
1
ifdan whilepernyataan tidak perlu tanda kurung.
orlp
1

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

Tidak Disatukan:

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

Pengujian:

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

Keluaran:

'((5))
'((16) (17) (12) (11))
'((7 11 9 4) (15 12) (7 5) (9 10 15 6))
juga
sumber
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))))))))

Nah ini jauh lebih masuk akal. Menghasilkan jumlah elemen-bijaksana, menambahkan metadata posisi, mengambil sementara kita belum mengulanginya dan menempatkan nilai jumlah ke setiap partisi.

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

Asli: Saya berharap untuk memperbaiki ini, tetapi ini adalah yang paling baik yang saya miliki untuk saat ini.

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

Tidak disatukan dan bertele-tele:

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

Mulai dengan "menggabungkan" siklus koleksi yang tak terbatas adanb , menambahkan metadata pada indeks setiap elemen dalam koleksi, berlangsung hingga kedua urutan mulai dari indeks 0 lagi.

Koleksi ini c ini kemudian digabungkan dengan data partisi (jumlah kumulatif satu dan nol), dipartisi dan elemen terakhir (menjadi jumlah item) dipilih.

Saya pikir untuk perbaikan signifikan diperlukan pendekatan yang sama sekali berbeda.

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

fungsi anonim mengambil input sebagai array.

kerusakan

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

C ++ 14, 206 byte

Sebagai lambda generik yang tidak disebutkan namanya, membutuhkan wadah masukan P, Qdan wadah keluaran Rseperti 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);}

Tidak digabungkan dan digunakan:

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

Mathematica 112 Bytes

Ini mungkin bisa diperbaiki. Idenya adalah untuk membuat array 2D dengan elemen kedua yang digunakan untuk melacak lessor dari penghitung i mod panjang masing-masing array input.

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

Pemakaian

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

Sedikit tidak berbulu:

(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]
  • Jika keduanya array ddan emengandung angka, jumlah angka pertama ditambahkan ke sdan elemen yang tersisa diproses secara rekursif
  • Jika salah satu array berisi angka, array jumlah sditambahkan ke hasilnya rdan array lainnya diatur ulang ke array awal
  • Jika kedua array kosong maka cukup kembalikan hasilnya dengan jumlah terakhir ditambahkan.

Sayangnya solusi ini tidak memiliki efisiensi yang kejam dari @ Arnauld, tapi setidaknya saya pikir ini solusi yang indah.

Neil
sumber