Ngoài ra căn chỉnh mảng


39

Giới thiệu

Xét hai mảng số nguyên không trống, giả sử A = [0 3 2 2 8 4]B = [7 8 7 2] . Để thực hiện bổ sung căn chỉnh trên chúng, chúng tôi làm như sau:

  1. Lặp lại mỗi mảng đủ số lần để có tổng chiều dài lcm (chiều dài (A), chiều dài (B)) . Ở đây lcm là viết tắt của bội số chung thấp nhất.

    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. Thực hiện bổ sung phần tử trên các mảng lặp lại và cắt kết quả ở mọi vị trí có một phần bị cắt.

    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. Mảng này là kết quả của bạn.

Nhiệm vụ

Đầu vào của bạn là hai mảng số nguyên không trống và đầu ra của bạn sẽ là kết quả của phép cộng liên kết của chúng, như được định nghĩa ở trên. Các đầu vào và đầu ra có thể ở bất kỳ định dạng hợp lý. Bạn không phải lo lắng về việc tràn số nguyên khi thực hiện bổ sung.

Quy tắc và tính điểm

Bạn có thể viết một chương trình đầy đủ hoặc một chức năng. Số byte thấp nhất sẽ thắng.

Các trường hợp thử nghiệm

[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 không có cách nào để biết độ dài của mảng - tôi có thể yêu cầu độ dài của mảng làm đối số không hoặc có được lưu trữ ở đầu mảng không?
mèo

1
@cat Bạn có thể lấy độ dài làm đối số bổ sung, nếu không có cách nào khác để có được chúng.
Zgarb

Câu trả lời:


9

JavaScript (ES6), 101 99 byte

Lấy đầu vào là 2 mảng. Trả về một chuỗi.

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

Làm thế nào nó hoạt động

Chúng tôi lặp lại trên mảng đầu tiên avới một con trỏ itrong khi cập nhật một con trỏ khác jvào mảng thứ hai b. Các khoản tiền a[i] + b[j]được nối vào chuỗi đầu ra s. Một dấu phân cách được chèn mỗi lần i == 0hoặc j == 0. Chúng tôi lặp lại quá trình này cho đến khi jtrở lại chính xác vào lúc bắt đầu bkhi kết thúc một lần lặp.

Lưu ý: Khi |toán tử được áp dụng, a.map(...)bị ép buộc NaN(nếu achứa nhiều hơn một phần tử) hoặc giá trị hiện tại của j(nếu achứa chính xác một phần tử). Do đó, a.map(...)|j == jtrong mọi trường hợp và an toàn để sử dụng ở đây.

Các trường hợp thử nghiệm


Tôi thậm chí không cố gắng để hiểu câu trả lời, +1 cho ghi chú . Tôi sẽ sao chép và giữ nó để dán khi cần
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

Phiên bản đầu tiên của tôi giống với bố cục dễ đọc hơn:

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

Sử dụng một định nghĩa cục bộ để tránh phải đưa ra (%)các đối số bổ sung cho ab. Thật đáng ngạc nhiên, đây gần như là một giải pháp được đưa ra gần như cùng lúc với @ nimi, từ đó tôi lấy ý tưởng chỉ sử dụng một dòng cho định nghĩa cục bộ.

Sử dụng:

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

Ồ, đó là một cách hay để trả trước tổng số cho phần tử đầu tiên của danh sách. Ngắn hơn nhiều so với cồng kềnh của tôi !.
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;};

Hãy thử nó ở đây!

Hàm ẩn danh trả về mảng kết quả của mảng.

Về cơ bản, chúng tôi lặp qua nội dung của cả hai mảng, điều chỉnh trình lặp của chúng tôi theo độ dài của mảng để mô phỏng 'sao chép' chúng. Lấy từng giá trị từ các mảng, chúng tôi tổng hợp chúng và thêm chúng vào một mảng $c. Nếu chúng tôi đạt đến cuối của một trong các mảng đầu vào của chúng tôi (một phần tách, về mặt thách thức), chúng tôi bắt đầu gán vào một mảng mới trong $c.

Lý do của do whilevòng lặp là vì điều kiện của chúng tôi dựa trên $i, bắt đầu từ 0. Nếu chúng ta sử dụng một vòng lặp trong đó điều kiện được kiểm tra lúc đầu, vòng lặp sẽ không chạy

Chúng tôi chỉ kết thúc tổng kết một khi chúng tôi đạt đến cuối của cả hai mảng cùng một lúc, điều này có nghĩa là LCM.


Có nên $b[$i%$y]hay không? Bạn có thể lưu 3 byte bằng cách chuyển $x=count($a)sang sử dụng đầu tiên $x; tương tự cho $y=count($b)và một byte với bitwise hoặc trong whileđiều kiện
Titus

Nhưng tôi nghĩ các hàm ẩn danh được coi là đoạn trích và do đó không có câu trả lời hợp lệ.
Tít

Các chức năng ẩn danh @Titus được cho phép theo mặc định theo sự đồng thuận trên Meta .
Zgarb

Cảm ơn những lời đề nghị @Titus, tôi vừa mới ném nó lại với nhau vì tôi muốn đánh bại các câu trả lời khác của PHP: P
Xanderhall

4

Haskell, 87 84 byte

a#b=a%b where[]%[]=[[]];(e:f)%(g:h)=f%h!(e+g);e%[]=[]:e%b;_%g=[]:a%g
(m:n)!l=(l:m):n

Ví dụ sử dụng: [0,3,2,2,8,4] # [7,8,7,2]-> [[7,11,9,4],[15,12],[7,5],[9,10,15,6]].

Đệ quy đơn giản. Trường hợp cơ sở: cả hai danh sách đều trống. Nếu chỉ có một trong số chúng trống, hãy khởi động lại với phiên bản đầy đủ và bắt đầu một cụm mới trong đầu ra. Nếu không có giá trị nào, hãy thêm tổng vào phần tử from.

Cũng hãy xem câu trả lời của @Christian Sievers , gần như giống hệt nhau và đã được đăng vài giây trước đó.


Bạn có chắc không? Có cách nào để có được thời gian chính xác?
Christian Sievers

@ChristianSievers: Tôi không biết nếu bạn có thể xem thời gian trực tiếp. Khi thời gian chỉnh sửa của chúng tôi được hiển thị trong vài phút, tôi nhớ rằng thời gian chỉnh sửa của bạn được tính sớm hơn vài giây (khoảng 20) so với thời gian của tôi.
nimi

Bạn nói đúng: Tôi đã tìm thấy dấu thời gian trong mã nguồn html của trang này
Christian Sievers

Di chuột qua thời gian trong "đã trả lời 2 ngày trước" để xem thời gian chính xác. (Gợi ý: đây là giao diện người dùng chuẩn trên internet, vì vậy (a) nếu bạn muốn có thời gian chính xác, hãy thử di chuột thời gian tương đối và (b) nếu bạn từng thực hiện điều gì đó hiển thị thời gian tương đối, vui lòng hiển thị thời gian chính xác khi di chuột !)
wchargein

2

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

hàm này có thể gọi trực tiếp để gọi nó đặt trong ngoặc đơn và gọi là (@ (a, b) ...) ([1 2 3 4], [6 4 5])


1
Bây giờ TIO-Nexus hỗ trợ Octave. Đây là một liên kết để kiểm tra mã
Luis Mendo

@LuisMendo Cảm ơn, dịch vụ thú vị
rahnema1

2

CJam , 30 byte

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

Hãy thử trực tuyến!

Đưa đầu vào như một cặp danh sách.

Giải trình

Ý tưởng là chèn một số điểm đánh dấu vào các mảng đầu vào (dưới dạng các chuỗi ngắn) cho biết vị trí của mảng được căn chỉnh kết thúc và nơi chúng ta cần chèn các ngắt trong các mảng. Bằng cách này, chúng ta có thể tránh phải tính LCM.

Sf*    e# Riffle each list with spaces. These are just place holders, so that having
       e# an array-end marker between two elements doesn't misalign subsequent elements.
Laf+   e# Append an empty string to each list. This is the array-end marker.
_s,    e# Convert the pair of lists to a string and get its length. This is always
       e# greater than the number of elements in either input.
f*     e# Repeat either array that many times. This is definitely more than necessary
       e# to reach the LCM (since multiplying by the length of the other list always
       e# gives a common multiple).
:.+    e# Pairwise addition of the list elements. There are four cases:
       e# - Both elements are numbers, add them. This is the actual addition
       e#   we need for the problem.
       e# - Both elements are spaces. This is just a regular position between
       e#   list elements.
       e# - One is a space, one is empty: the result is a single space, and
       e#   this marks a position where one of the arrays ended, which means
       e#   we need to split here.
       e# - Both elements are empty. This happens at the LCM of both list lengths
       e#   and indicates where we need to stop the output.
La/0=  e# Split the input around empty strings and discard everything except
       e# the first chunk.
S2*a-  e# Remove the double-space strings, we no longer need them.
Sa/    e# Split the list around single spaces.

2

Thạch , 21 20 18 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

ṁ€L€æl/$S  Helper link. Argument [X, Y] (arrays of integers).

       $   Combine the two links to the left into a monadic chain.
  L€       Length each; yield the lengths of X and Y.
    æl/    Reduce by least common multiple.
ṁ€         Mold each; cyclically repeat the elements of X and Y to extend them
           to length lcm(length(X), length(Y)).
        S  Compute the sum of the extended X and Y arrays.

J€ỊÇœṗÇḊ   Main link. Argument [A, B] (arrays of integers).

J€         Indices each; replace A and B by the arrays of there 1-based indices.
  Ị        Insignificant; map 1 to itself, all other indices to 0.
   Ç       Apply the helper link to the result.
           This yield a Boolean array with a 1 (or 2) at all indices where a new
           repetition of A or B (or both) begins.
      Ç    Apply the helper link to [A, B].
    œṗ     Partition; break the result to the right at truthy elements (1 or 2) in
           the result to the right.
       Ḋ   Dequeue; remove the first element of the partition (empty array).

2

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

import math
def s(a,b):
 l,k,*r=map(len,[a,b])
 for i in range(l*k//math.gcd(l,k)):
  r+=a[i%l]+b[i%k],
  if i%k==k-1or i%l==l-1:print(r);r=[]

Tôi không thể tìm ra làm thế nào để đặt toàn bộ vòng lặp cho một dòng.

Chỉnh sửa:


Điều này cho một lỗi cho tôi . Các gcdchức năng là trong fractions, không math.
Zgarb

@Zgarb mô-đun gcd trong phân số không được dùng nữa , bạn có thể kiểm tra sự thay đổi ở đây . Tôi đoán rexter đang sử dụng phiên bản cũ 3.4.3.
Gurupad Mamadapur

Không, tôi không biết về sự thay đổi này. Mặc dù vậy, bạn nên đánh dấu ngôn ngữ là "Python 3.5" vì ngôn ngữ này không hoạt động trong phiên bản 3.4 trở về trước. Ngoài ra, bạn có thể thả dấu ngoặc đơn xung quanh l*kvà có print(r);r=[]dòng cuối cùng.
Zgarb

Bạn có chắc chắn số byte của bạn là chính xác? Tôi nghĩ rằng chỉ có 145 byte.
vaultah

1
Tôi đang nhận được 142 byte. Bạn đang sử dụng Windows? Windows thường tính các dòng mới là 2 byte mỗi loại, nhưng ở đây mỗi dòng mới được tính là một byte đơn.
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]))

Đưa đầu vào từ stdin thành hai bộ dữ liệu được phân tách bằng dấu phẩy, đưa ra danh sách dẫn đến thiết bị xuất chuẩn. Chấm dứt bằng cách tăng ZeroDivisionErrorngoại lệ, vì điều đó dường như được cho phép .

Ví dụ, nếu đầu vào là (0, 3, 2, 2, 8, 4), (7, 8, 7, 2), chương trình sẽ in

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

để stdout và trac trở lại ngoại lệ cho stderr.


Bạn có thể thoát khỏi chương trình bằng cách ném lỗi . Sau đó, bạn có thể có được vòng lặp thành một dòng duy nhất.
Zgarb

2

J , 34 32 byte

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

Hãy thử trực tuyến!

Giải trình

[:(<;.1~*)/[:+/*.&#$&>,:&(;2>#\)  Input: array A (LHS), array B (RHS)
                             #\   Length of each prefix of A and B
                           2>     Less than 2
                          ;       Link each with A and B
                      ,:&         Pair them
                  #               Length of A and B
               *.&                LCM of the lengths
                    &>            For each box
                   $              Reshape it to the LCM of the lengths
           [:+/                   Reduce by addition
[:        /                       Reduce by
        *                           Sign of RHS
   <;.1~                            Box each partition of LHS

1

Haskell, 166 byte

Đây có lẽ không phải là cách tiếp cận tao nhã nhất: Về cơ bản, hàm ?tạo ra một danh sách độ dài cần thiết với các luận điểm và %sẽ cắt tổng này một lần nữa. !là chức năng cuối cùng hợp nhất hai.

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]

Bạn có thể thay thế indbằng khoặc một cái gì đó, và có một số dấu ngoặc đơn không cần thiết xung quanh drop i lmap(+(-i))ind. Xem xét cũng có hai trường hợp cho %, với mô hình phù hợp trên 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;}

Phiên bản đẹp:

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

Đầu ra:

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

Vẽ ngay cả với tôi bằng các chỉnh sửa này: $i=$j=$k=0;không cần thiết nếu bạn sử dụng +$ivv cho các chỉ mục mảng trong phép gán bổ sung (-8 byte). $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, hai lần). $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6). return$O;không cần không gian (-1).
Tít

@Titus không thể xóa $i=$j=0;một phần vì các giá trị đầu tiên từ mảng sẽ không chính xác. Tôi đã sửa đổi logic một chút để không chắc chắn cách triển khai các toán tử ternary trong trường hợp này. Cảm ơn ++$ilời khuyên.
Dexa

Hãy thử unset($i);$A[+$i]. Ý +chí đúc nullthành số nguyên 0.
Tít

if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;vẫn tiết kiệm được 5 byte mỗi cái. Tiết kiệm thêm một $f<2thay vì $f!=2. và hai cái khác while($f=$f<3){...}thay vì while($f<2){$f=0;...}(khởi tạo và đặt lại $fthành 1 trừ khi nó tăng gấp đôi hai lần)
Titus

@Titus Cảm ơn rất nhiều, bây giờ nó ngắn hơn.
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

Hãy thử trực tuyến!

( Chào mừng các đề xuất chơi gôn. Tôi cảm thấy có thể có thêm 10 đến 15 byte có thể được vắt ra từ đây. )

Lấy đầu vào là hai mảng rõ ràng (với @(...)cú pháp) làm đối số dòng lệnh. Trả về một hàm băm của các mảng kết quả, bởi vì các mảng đa chiều trong PowerShell có thể trở nên kỳ lạ, và điều này phù hợp hơn. Bộ một số biến ban đầu, sau đó đi vào một do/ untillặp lại, với các điều kiện cho đến khi $ilcm của tội mảng .

Mỗi lần lặp lại, chúng ta cộng các giá trị $a$bgiá trị tương ứng lại với nhau, coi nó như một mảng ,(...)trước khi thêm nó vào hàm băm $otại vị trí thích hợp $j. Việc đóng gói mảng là cần thiết để ngăn chặn sự bổ sung số học - điều này buộc +=phải quá tải để nối mảng thay thế. Sau đó, một điều kiện trên $x$y(số đếm) để xác định xem chúng ta có ở cạnh mảng không - nếu vậy, chúng ta sẽ tăng lên $j.

Cuối cùng, chúng tôi để lại $otrên đường ống và đầu ra là ẩn.
(NB: Do cách PowerShell liệt kê các Write-Outputhàm băm với mặc định , điều này có xu hướng là đầu ra "lạc hậu", như trong, mảng kết quả "0" nằm ở "đáy" của đầu ra. Bản thân hàm băm là tốt, và sẽ là chỉ được sử dụng tốt nếu bạn ví dụ, đóng gói mã này trong một biến trả về ... nó chỉ trông lạ khi được in.)

Đã lưu 2 byte bằng cách di chuyển $ x và $ y vào lập chỉ mục mảng thay vì tách riêng (lưu hai dấu chấm phẩy).


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

Này có thể nots có <1s để thay thế?
Zgarb

1

Python 3.5, 210 176 173 169 158 byte

def f(a,b):
 x=[];e=f=0              
 while 1:
  if e==len(a):         
   print(x);x=[];e=0;
   if f==len(b):break
  if f==len(b):print(x);x=[];f=0
 x+=a[e]+b[f],;e+=1;f+=1

Lấy hai danh sách làm đầu vào và in tất cả các danh sách.

Đó là câu trả lời đầu tiên của tôi và tôi chưa biết chơi golf. Ý tưởng cơ bản mà tôi đã sử dụng là có hai bộ đếm cho mỗi danh sách chỉ ra sự phân chia và danh sách hiện tại nơi các giá trị gia tăng được thêm vào; ngay khi gặp phải sự phân tách, chúng tôi sẽ in danh sách hiện tại và tạo một danh sách trống mới.

  • Đã lưu 34 byte : Nhờ DennisTimmyD
  • Đã lưu 3 byte : đã sử dụng c và d cho len (a) và len (b), nhưng hóa ra chúng không hữu ích
  • Đã lưu 4 byte : Nhờ orlp , đã loại bỏ parantener không mong muốn
  • Đã lưu 11 byte : sắp xếp lại một số khối và hạ chúng xuống

1
Xin chào, và chào mừng bạn đến với Câu đố lập trình & Code Golf! Không cạnh tranh có nghĩa là một cái gì đó khác ở đây; bạn nên loại bỏ nó Bạn có thể lưu khá nhiều byte bằng cách loại bỏ khoảng trắng. Ví dụ, dòng 2 đến 5 có thể trở thành x=[];c=len(a);d=len(b);e=f=0. Ngoài ra, truecó thể trở thành 1, và x.append(a[e]+b[f])có thể trở thành x+=a[e]+b[f],.
Dennis

1
Chào mừng đến với PPCG! Ngoài các tinh chỉnh cụ thể của Dennis, hãy xem Mẹo chơi gôn trong Python để có một số gợi ý và mẹo chung hơn.
admBorkBork

1
ifwhilebáo cáo không cần dấu ngoặc đơn.
orlp

1

Vợt 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))])))

Ung dung:

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

Kiểm tra:

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

Đầu ra:

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

1

Clojure, 280 206 byte

(fn[a b](let[A(count a)B(count b)Q quot](map #(map last %)(partition-by first(take-while #((% 0)2)(map-indexed(fn[i s][[(Q i A)(Q i B)(or(= i 0)(>(mod i A)0)(>(mod i B)0))]s])(map +(cycle a)(cycle b))))))))

Vâng, điều này có ý nghĩa hơn rất nhiều. Tạo tổng thành phần tử, thêm siêu dữ liệu vị trí, trong khi chúng ta chưa lặp lại và đặt giá trị tổng cho mỗi phân vùng.

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

Bản gốc: Tôi hy vọng sẽ cải thiện điều này nhưng đây là thứ tốt nhất tôi có bây giờ.

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

Bắt đầu bằng cách "hợp nhất" một chu kỳ vô hạn của các bộ sưu tập ab, thêm siêu dữ liệu vào chỉ mục của từng thành phần trong bộ sưu tập, cho đến khi cả hai chuỗi bắt đầu lại từ chỉ số 0.

Bộ sưu tập cnày sau đó được hợp nhất với dữ liệu phân vùng (tổng tích lũy của số và số 0), được phân vùng và phần tử cuối cùng (là tổng của các mục) được chọn.

Tôi nghĩ rằng để cải thiện đáng kể một cách tiếp cận hoàn toàn khác là cần thiết.


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

hàm ẩn danh lấy đầu vào là mảng.

phá vỡ

while($i<2|$x|$y)   // loop while either $a or $b has NO cut
    $r[
                // if either $a or $b has a cut, increment $k; post-increment $i
        $k+=!($x=$i%count($a))|!$y=$i++%count($b)
                // append current $a + current $b to $r[$k]
    ][]=$a[$x]+$b[$y];
array_pop($r);  // $r has one element too much; remove it
return$r;

0

C ++ 14, 206 byte

Như lambda giấu tên generic, đòi hỏi container đầu vào P, Qvà chứa đầu ra Rđược như 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 và cách sử dụng:

#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

Toán học 112 byte

Điều này có lẽ có thể được cải thiện. Ý tưởng là tạo ra một mảng 2D với phần tử thứ hai được sử dụng để theo dõi bên cho thuê của bộ đếm i mod độ dài của mỗi mảng đầu vào.

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

Sử dụng

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

0

JavaScript (ES6), 131 byte

(a,b,g=(r,[n,...d]=a,[m,...e]=b,s=[])=>1/n?1/m?g(r,d,e,[...s,n+m]):g([...r,s],[n,...d]):1/m?g([...r,s],a,[m,...e]):[...r,s])=>g([])

Hơi vô dụng:

(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]
  • Nếu cả hai mảng dechứa số, tổng của số đầu tiên được nối vào svà các phần tử còn lại được xử lý đệ quy
  • Nếu một trong các mảng chứa số, mảng tổng sđược gắn vào kết quả rvà mảng khác được đặt lại thành mảng ban đầu của nó
  • Nếu cả hai mảng đều trống thì chỉ cần trả về kết quả với số tiền cuối cùng được nối.

Đáng buồn thay, giải pháp này không có hiệu quả tàn nhẫn của @ Arnauld, nhưng ít nhất tôi nghĩ đó là một giải pháp đẹp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.