นอกจากนี้การจัดตำแหน่งอาร์เรย์


39

บทนำ

พิจารณาสองไม่ว่างเปล่าอาร์เรย์จำนวนเต็มบอกว่าA = [0 3 2 2 8 4]และB = [7 8 7 2] ในการเพิ่มการจัดตำแหน่งให้กับพวกเราเราทำดังต่อไปนี้:

  1. ทำซ้ำแต่ละครั้งอาร์เรย์พอที่จะมีความยาวรวมLCM (ความยาว (A), ความยาว (B)) ที่นี่lcmหมายถึงตัวคูณร่วมน้อย

    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. ดำเนินการเพิ่มองค์ประกอบที่ชาญฉลาดในอาร์เรย์ที่ทำซ้ำและตัดผลลัพธ์ที่ได้ในทุกตำแหน่งที่มีการตัดทั้งสองอย่าง

    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. อาร์เรย์ของอาร์เรย์นี้เป็นผลลัพธ์ของคุณ

งาน

อินพุตของคุณคืออาร์เรย์ที่ไม่ว่างสองจำนวนเต็มและเอาต์พุตของคุณจะเป็นผลมาจากการเพิ่มการจัดตำแหน่งตามที่กำหนดไว้ข้างต้น อินพุตและเอาต์พุตสามารถอยู่ในรูปแบบที่เหมาะสม คุณไม่ต้องกังวลกับการล้นจำนวนเต็มเมื่อทำการเพิ่ม

กฎและการให้คะแนน

คุณสามารถเขียนโปรแกรมเต็มรูปแบบหรือฟังก์ชั่น จำนวนไบต์ต่ำสุดชนะ

กรณีทดสอบ

[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 ไม่มีวิธีทราบความยาวของอาร์เรย์ฉันสามารถขอความยาวของอาร์เรย์เป็นอาร์กิวเมนต์หรือเก็บไว้ที่จุดเริ่มต้นของอาร์เรย์ได้หรือไม่
แมว

1
@cat คุณสามารถใช้ความยาวเป็นอาร์กิวเมนต์พิเศษได้หากไม่มีวิธีอื่นในการรับ
Zgarb

คำตอบ:


9

JavaScript (ES6), 101 99 ไบต์

รับอินพุตเป็น 2 อาร์เรย์ ส่งคืนสตริง

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

มันทำงานอย่างไร

เราย้ำในอาร์เรย์แรกaที่มีตัวชี้iขณะที่การปรับปรุงตัวชี้อื่นเข้าแถวที่สองj bจำนวนเงินที่ถูกผนวกเข้ากับสตริงเอาท์พุทa[i] + b[j] sตัวคั่นจะถูกแทรกในแต่ละครั้งหรือi == 0 j == 0เราทำซ้ำขั้นตอนนี้จนกว่าjจะกลับมาที่จุดเริ่มต้นbในตอนท้ายของการทำซ้ำ

หมายเหตุ:เมื่อมี|การใช้โอเปอเรเตอร์จะa.map(...)ถูกรวมกับNaN(ถ้าaมีมากกว่าหนึ่งองค์ประกอบ) หรือค่าปัจจุบันของj(หากaมีองค์ประกอบหนึ่งองค์ประกอบ) ดังนั้นa.map(...)|j == jในทุกกรณีและปลอดภัยที่จะใช้ที่นี่

กรณีทดสอบ


ฉันไม่ได้พยายามแม้จะเข้าใจคำตอบที่ 1 สำหรับโน้ต ฉันจะคัดลอกและวางเพื่อวางเมื่อจำเป็น
edc65

6

Haskell, 84 79 ไบต์

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

รุ่นแรกของฉันเหมือนกันในรูปแบบที่อ่านได้มากขึ้น:

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

การใช้คำนิยามในท้องถิ่นที่จะหลีกเลี่ยงที่จะให้(%)การขัดแย้งพิเศษสำหรับและa bน่าประหลาดใจนี่เป็นวิธีแก้ปัญหาเดียวกับที่ได้รับเกือบในเวลาเดียวกับ @ nimi's จากผู้ที่ฉันใช้ความคิดในการใช้เพียงบรรทัดเดียวสำหรับการกำหนดท้องถิ่น

การใช้งาน:

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

โอ้เป็นวิธีที่ดีในการรวมยอดรวมกับองค์ประกอบแรกของรายการ !ไกลสั้นกว่ายุ่งยากของฉัน
nimi

4

PHP, 126 120 ไบต์

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

ลองที่นี่!

ฟังก์ชั่นไม่ระบุชื่อที่ส่งคืนอาร์เรย์ผลลัพธ์ของอาร์เรย์

โดยพื้นฐานแล้วเราวนรอบเนื้อหาของทั้งสองอาร์เรย์ของเราปรับเปลี่ยนตัววนซ้ำตามความยาวของอาร์เรย์เพื่อจำลอง 'คัดลอก' พวกเขา $cการแต่ละค่าจากอาร์เรย์เรารวมพวกเขาและเพิ่มพวกเขาไปยังอาร์เรย์ใน ถ้าเรามาถึงจุดสิ้นสุดของหนึ่งในอาร์เรย์การป้อนข้อมูลของเรา (แยกในแง่ของความท้าทาย) $cเราเริ่มต้นกำหนดเป็นแถวใหม่ใน

เหตุผลในการที่do whileห่วงเป็นเพราะสภาพของเราอยู่บนพื้นฐานซึ่งเริ่มต้นที่$i 0หากเราใช้การวนซ้ำที่ตรวจสอบสภาพที่จุดเริ่มต้นการวนซ้ำจะไม่ทำงาน

เราจะจบการสรุปเมื่อเราไปถึงจุดสิ้นสุดของอาร์เรย์ทั้งสองในเวลาเดียวกันซึ่งจะหมายถึง LCM


$b[$i%$y]ไม่ควรใช่มั้ย คุณสามารถบันทึก 3 ไบต์โดยการย้าย$x=count($a)ไปใช้งานครั้งแรกของ$x; เหมือนกัน$y=count($b)และหนึ่งไบต์ที่มี bitwise หรืออยู่ในwhileเงื่อนไข
ติตัส

แต่ฉันคิดว่าฟังก์ชั่นนิรนามถือว่าเป็นตัวอย่างและดังนั้นจึงไม่มีคำตอบที่ถูกต้อง
ติตัส

ฟังก์ชั่น @Titus ไม่ประสงค์ออกนามที่ได้รับอนุญาตโดยค่าเริ่มต้นตามฉันทามติเกี่ยวกับ Meta
Zgarb

ขอบคุณสำหรับคำแนะนำ @Titus ฉันแค่โยนมันด้วยกันเพราะฉันต้องการเอาชนะคำตอบ PHP อื่น ๆ : P
Xanderhall

4

Haskell, 87 84 ไบต์

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

ตัวอย่างการใช้งาน: ->[0,3,2,2,8,4] # [7,8,7,2][[7,11,9,4],[15,12],[7,5],[9,10,15,6]]

เรียกซ้ำง่าย ๆ กรณีพื้นฐาน: ทั้งสองรายการว่างเปล่า หากหนึ่งในนั้นว่างเปล่าให้รีสตาร์ทด้วยเวอร์ชันเต็มและเริ่มต้นคลัสเตอร์ใหม่ในเอาต์พุต หากไม่มีสิ่งใดว่างให้รวมยอดรวมกับองค์ประกอบจาก

ได้ดูคำตอบของ @Christian Sieversซึ่งเกือบเหมือนกันและโพสต์เมื่อไม่กี่วินาทีก่อนหน้านี้


คุณแน่ใจไหม? มีวิธีรับเวลาที่แน่นอนหรือไม่?
Christian Sievers

@ChristianSievers: ฉันไม่รู้ว่าคุณสามารถดูเวลาโดยตรง เมื่อเวลาของการแก้ไขของเราปรากฏในไม่กี่นาทีฉันจำได้ว่าคุณนับเวลาเร็วกว่าของฉันสองสามวินาที (ประมาณ 20)
nimi

คุณพูดถูก: ฉันพบการประทับเวลาในซอร์สโค้ด html ของหน้านี้
Christian Sievers

วางเมาส์เหนือช่วงเวลาใน "ตอบ 2 วันที่ผ่านมา" เพื่อดูเวลาที่แน่นอน (คำแนะนำ: นี่คือ UI มาตรฐานทั่วอินเทอร์เน็ตดังนั้น (a) ถ้าคุณต้องการเวลาที่แน่นอนลองโฮเวอร์เวลาที่สัมพันธ์กันและ (b) ถ้าคุณเคยใช้บางอย่างที่แสดงเวลาที่สัมพันธ์กันโปรดแสดงเวลาที่แน่นอนในโฮเวอร์ !)
wchargin

2

ระดับเสียงคู่, 113 ไบต์

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

ฟังก์ชั่นนี้สามารถเรียกใช้ได้โดยตรงเพื่อวางมันไว้ในวงเล็บและเรียกว่าเป็น (@ (a, b) ... ) ([1 2 3 4], [6 4 5])


1
ตอนนี้ TIO-Nexus รองรับอ็อกเทฟ นี่คือลิงก์สำหรับทดสอบโค้ด
Luis Mendo

@ LuisMendo ขอบคุณบริการที่น่าสนใจ
rahnema1

2

CJam , 30 ไบต์

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

ลองออนไลน์!

รับอินพุตเป็นรายการคู่

คำอธิบาย

แนวคิดคือการแทรกเครื่องหมายลงในอาร์เรย์อินพุต (ในรูปแบบของสตริงสั้น ๆ ) ซึ่งระบุว่าอาเรย์สิ้นสุดลงแล้วและตำแหน่งที่เราต้องแทรกตัวแบ่งในอาร์เรย์ วิธีนี้เราสามารถหลีกเลี่ยงการคำนวณ 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

เยลลี่ , 21 20 18 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

ṁ€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 ไบต์

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

ฉันไม่สามารถหาวิธีใส่ลูปทั้งหมดในหนึ่งบรรทัดได้

การแก้ไข:

  • ขอบคุณzgarb สำหรับการบันทึก 9 ไบต์!
  • ขอบคุณvaultahสำหรับการบันทึก 3 ไบต์!
  • ขอบคุณmathmandan ที่ประหยัด 5 ไบต์!

นี้จะช่วยให้ข้อผิดพลาดสำหรับฉัน gcdฟังก์ชั่นในไม่fractions math
Zgarb

@Zgarb GCD ในโมดูลเศษส่วนจะเลิกคุณสามารถตรวจสอบการเปลี่ยนแปลงที่นี่ ฉันเดา Rexter 3.4.3ใช้รุ่นเก่า
Gurupad Mamadapur

ไม่เป็นไรฉันไม่รู้เกี่ยวกับการเปลี่ยนแปลงนี้ คุณควรทำเครื่องหมายภาษาว่า "Python 3.5" เนื่องจากไม่สามารถใช้งานได้ใน 3.4 หรือเร็วกว่า นอกจากนี้คุณสามารถวางวงเล็บไว้รอบ ๆl*kและมีprint(r);r=[]ในบรรทัดสุดท้าย
Zgarb

คุณแน่ใจหรือไม่ว่าจำนวนไบต์ของคุณถูกต้อง? ฉันคิดว่ามีเพียง 145 ไบต์
vaultah

1
ฉันได้รับ 142 ไบต์ คุณใช้ Windows หรือเปล่า Windows มักจะนับบรรทัดใหม่เป็น 2 ไบต์ แต่ที่นี่แต่ละบรรทัดจะนับเป็นไบต์เดียว
mathmandan

2

Python 2, 119 ไบต์

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 เป็นสอง tuples คั่นด้วยเครื่องหมายคอมมาเอาต์พุตรายการผลลัพธ์เป็น stdout ยุติโดยการเพิ่มZeroDivisionErrorข้อยกเว้นตั้งแต่ที่ดูเหมือนว่าจะได้รับอนุญาต

ตัวอย่างเช่นหากมีการป้อนข้อมูล(0, 3, 2, 2, 8, 4), (7, 8, 7, 2)โปรแกรมจะพิมพ์

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

เพื่อ stdout และข้อยกเว้นการติดตามย้อนกลับเป็น stderr


คุณสามารถออกจากโปรแกรมโดยการขว้างปาข้อผิดพลาด จากนั้นคุณอาจได้รับการวนซ้ำเป็นบรรทัดเดียว
Zgarb

2

J , 34 32 ไบต์

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

ลองออนไลน์!

คำอธิบาย

[:(<;.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 ไบต์

นี่อาจไม่ใช่วิธีที่หรูหราที่สุด: โดยทั่วไปฟังก์ชั่น?จะสร้างรายการความยาวที่ต้องการด้วย thesums และ%ตัดยอดรวมนี้อีกครั้ง !เป็นฟังก์ชั่นสุดท้ายที่รวมสองคนนั้นเข้าด้วยกัน

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]

คุณสามารถแทนที่indโดยkหรือบางสิ่งบางอย่างและมีบางส่วนที่ไม่จำเป็นวงเล็บรอบและdrop i l map(+(-i))indพิจารณายังมีสองกรณีที่มีการจับคู่แบบบน% l
Zgarb

1

[PHP], 183 152 135 ไบต์

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

รุ่นที่ดี:

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

เอาท์พุท:

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

วาดแม้กับฉันโดยใช้ tweaks เหล่านี้: $i=$j=$k=0;ไม่จำเป็นถ้าคุณใช้+$iฯลฯ สำหรับดัชนีอาเรย์ในการต่อท้ายการกำหนด (-8 ไบต์) $i++;if(!isset($A[$i])){$i=0;$k++;}-> isset($A[++$i])?:$i=!++$k;(-9, สองครั้ง) $i==0&&$j==0&&!isset()-> !$i&!$j&!isset()(-6) return$O;ไม่ต้องการพื้นที่ (-1)
ติตัส

@Titus ไม่สามารถลบ$i=$j=0;ส่วนหนึ่งได้เนื่องจากค่าแรกจากอาร์เรย์จะไม่ถูกต้อง ฉันได้แก้ไขตรรกะเล็กน้อยดังนั้นไม่แน่ใจว่าจะใช้ตัวดำเนินการประกอบในกรณีนี้ได้อย่างไร ขอบคุณสำหรับ++$iคำแนะนำ
Dexa

ลองunset($i);$A[+$i]ดู +จะเหวี่ยงให้เป็นจำนวนเต็มnull 0
ติตัส

if(!isset($A[++$i])){$i=0;++$k;++$f;}-> isset($A[++$i])?:$i=!++$k|!++$f;ยังคงบันทึกได้ 5 ไบต์ต่อครั้ง บันทึกอีกหนึ่งแทน$f<2 $f!=2และอีกสองคนกับwhile($f=$f<3){...}แทนwhile($f<2){$f=0;...}(initializes และรีเซ็ต$f1 เว้นแต่ it's เพิ่มขึ้นครั้งที่สอง)
ติตัส

@Titus ขอบคุณมากมันสั้นลงแล้ว
Dexa

1

PowerShell , 147 145 ไบต์

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

ลองออนไลน์!

( ยินดีให้คำแนะนำเกี่ยวกับการเล่นกอล์ฟฉันรู้สึกว่าอาจมีอีก 10 ถึง 15 ไบต์ที่สามารถบีบออกได้ )

รับอินพุตเป็นสองอาร์เรย์ที่ชัดเจน (ด้วย@(...)ไวยากรณ์) เป็นอาร์กิวเมนต์บรรทัดคำสั่ง ส่งคืน hashtable ของอาร์เรย์ผลลัพธ์เนื่องจากอาร์เรย์หลายมิติใน PowerShell สามารถแปลกและสิ่งนี้สอดคล้องกันมากขึ้น ชุดตัวแปรเริ่มต้นบางส่วนแล้วเข้าdo/ untilห่วงอีกครั้งกับความเป็นอยู่ตามเงื่อนไขจน$iเป็นLCM ของการนับอาร์เรย์

แต่ละซ้ำห่วงเราเพิ่มที่สอดคล้องกัน$aและ$bค่ากันรักษามันเป็นอาร์เรย์,(...)ก่อนที่จะเพิ่มเข้ามาใน Hashtable ที่จุดที่เหมาะสม$o $jการห่อหุ้มอาเรย์เป็นสิ่งที่จำเป็นเพื่อป้องกันการเพิ่มทางคณิตศาสตร์ - นี่เป็นการบังคับ+=ให้โอเวอร์โหลดไปยังการต่อข้อมูลอาเรย์แทน จากนั้นมีเงื่อนไขใน$xและ$y(นับ) เพื่อตรวจสอบว่าเราอยู่ที่ขอบอาร์เรย์ - $jถ้าเช่นนั้นเราเพิ่มขึ้น

ในที่สุดเราปล่อยให้$oไปป์ไลน์และเอาท์พุทเป็นนัย
(หมายเหตุ: เนื่องจาก PowerShell ระบุWrite-Outputแฮชเทเบิลด้วยค่าเริ่มต้นนี่จึงเป็นเอาต์พุต "ย้อนกลับ" ในขณะที่อาร์เรย์ผลลัพธ์ "0th" อยู่ที่ "ด้านล่าง" ของเอาต์พุตแฮชเองนั้นใช้ได้และจะเป็น ใช้ดีถ้าคุณเช่น encapsulated รหัสนี้ในตัวแปรกลับ ... มันก็ดูแปลกเมื่อมันพิมพ์)

บันทึก 2 ไบต์ด้วยการย้าย $ x และ $ y ไปยังการจัดทำดัชนีอาร์เรย์แทนที่จะแยก (บันทึกสองอัฒภาค)


1

Python 2, 113 ไบต์

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

จะnotเป็น<1s แทนได้หรือไม่
Zgarb

1

Python 3.5, 210 176 173 169 158 ไบต์

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

ใช้สองรายการเป็นอินพุตและพิมพ์รายการทั้งหมด

มันเป็นคำตอบแรกของฉันและฉันยังไม่รู้วิธีตีกอล์ฟ แนวคิดพื้นฐานที่ฉันเคยใช้คือมีสองตัวนับสำหรับแต่ละรายการซึ่งระบุการแยกและรายการปัจจุบันที่มีการเพิ่มค่าที่เพิ่มเข้ามา ทันทีที่พบการแยกเราจะพิมพ์รายการปัจจุบันและสร้างรายการใหม่ที่ว่างเปล่า

  • บันทึกแล้ว 34 ไบต์ : ขอบคุณDennisและ TimmyD
  • บันทึกแล้ว 3 ไบต์ : ใช้ c และ d สำหรับ len (a) และ len (b) แต่กลับกลายเป็นว่าพวกเขาไม่มีประโยชน์
  • บันทึกแล้ว 4 ไบต์ : ขอบคุณorlpลบ paranthesis ที่ไม่ต้องการออก
  • บันทึก 11 ไบต์ : จัดเรียงบล็อกใหม่บางส่วนและกระทืบลง

1
สวัสดีและยินดีต้อนรับสู่ Programming Puzzles & Code Golf! ไม่ใช่การแข่งขันหมายถึงอย่างอื่นที่นี่; คุณควรลบมัน คุณสามารถบันทึกได้ไม่กี่ไบต์โดยการกำจัดช่องว่าง ยกตัวอย่างเช่นสาย 2-5 x=[];c=len(a);d=len(b);e=f=0จะกลายเป็น นอกจากนี้ยังtrueสามารถกลายเป็น1และจะกลายเป็นx.append(a[e]+b[f]) x+=a[e]+b[f],
เดนนิส

1
ยินดีต้อนรับสู่ PPCG! นอกจากการปรับแต่งเฉพาะของเดนนิสแล้วให้ตรวจสอบเคล็ดลับสำหรับการเล่นกอล์ฟใน Pythonเพื่อรับคำแนะนำและเคล็ดลับทั่วไปเพิ่มเติม
AdmBorkBork

1
ifและwhileคำสั่งไม่จำเป็นต้องใส่วงเล็บ
orlp

1

แร็กเก็ต 373 ไบต์

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

การทดสอบ:

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

เอาท์พุท:

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

1

Clojure, 280 206 ไบต์

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

อย่างนี้ทำให้รู้สึกมากขึ้น การสร้างผลรวมองค์ประกอบที่ชาญฉลาดเพิ่มข้อมูลเมตาตำแหน่งในขณะที่เรายังไม่ได้ทำซ้ำและใส่มูลค่ารวมในแต่ละพาร์ทิชัน

(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: ฉันหวังว่าจะปรับปรุงสิ่งนี้ แต่นี่เป็นสิ่งที่ฉันทำได้ตอนนี้

(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 และ 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 %))))))

เริ่มต้นด้วยการ "รวม" วัฏจักรของคอลเลกชันที่ไม่มีที่สิ้นสุดaและbเพิ่มข้อมูลเมตาในดัชนีของแต่ละองค์ประกอบภายในคอลเลกชันจนกระทั่งทั้งสองลำดับเริ่มต้นจากดัชนี 0 อีกครั้ง

การรวบรวมนี้cจะถูกรวมเข้ากับข้อมูลพาร์ติชัน (ผลรวมสะสมของรายการและเลขศูนย์), การแบ่งพาร์ติชันและองค์ประกอบสุดท้าย (เป็นผลรวมของรายการ) ถูกเลือก

ฉันคิดว่าการปรับปรุงที่สำคัญจำเป็นต้องใช้วิธีการที่แตกต่างกันโดยสิ้นเชิง


1

PHP, 150 121 119 ไบต์

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

ฟังก์ชั่นที่ไม่ระบุชื่อรับอินพุตเป็นอาร์เรย์

ชำรุด

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 ไบต์

ในฐานะที่เป็นแลมบ์ดาชื่อทั่วไปที่กำหนดให้ภาชนะป้อนข้อมูลP, Qและภาชนะการส่งออกจะเป็นเหมือนRvector<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 และการใช้งาน:

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

สิ่งนี้อาจปรับปรุงได้ แนวคิดคือการสร้างอาร์เรย์ 2 มิติที่มีองค์ประกอบที่สองที่ใช้ในการติดตามผู้ให้เช่าของเคาน์เตอร์ฉันแก้ไขความยาวของแต่ละอาร์เรย์ใส่

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

การใช้

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

0

JavaScript (ES6), 131 ไบต์

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

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]
  • หากทั้งสองอาร์เรย์dและeมีตัวเลขผลรวมของหมายเลขแรกจะถูกผนวกเข้ากับsและองค์ประกอบที่เหลือจะถูกประมวลผลซ้ำ
  • หากหนึ่งในอาร์เรย์มีตัวเลขอาร์เรย์ของผลรวมsจะถูกต่อท้ายผลลัพธ์rและอาร์เรย์อื่นจะถูกรีเซ็ตเป็นอาร์เรย์เริ่มต้น
  • หากอาร์เรย์ทั้งสองนั้นว่างเปล่าให้ส่งคืนผลลัพธ์พร้อมกับผลรวมสุดท้ายที่ต่อท้าย

น่าเศร้าที่โซลูชันนี้ไม่มีประสิทธิภาพที่ไร้ความปราณีของ @ Arnauld แต่อย่างน้อยฉันคิดว่ามันเป็นวิธีที่สวยงาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.