เศษส่วนต่อเนื่องของตัวเลขเป็นสองเท่า


21

งานของคุณคือให้เอาท์พุทx 2*xถูกต้องง่าย! แต่มีการจับ: xจะได้รับเป็นเศษส่วนต่อเนื่อง (อาจไม่มีที่สิ้นสุด) และผลผลิตจะต้องเป็นเศษส่วนต่อเนื่อง ข้อมูลเข้ารับประกันได้ว่าเป็นจำนวนพีชคณิตจริงซึ่งมีระดับไม่เกิน 2

การป้อนข้อมูล : xเศษอย่างต่อเนื่องของ สิ่งนี้แบ่งออกเป็น 3 ส่วนคือส่วนจำนวนเต็มคำนำหน้าและส่วนที่ทำซ้ำ ส่วนจำนวนเต็มประกอบด้วยจำนวนเต็มเดียว ส่วนนำหน้าและส่วนทำซ้ำคืออาร์เรย์ (อาจว่าง) ของจำนวนเต็มบวกซึ่งอธิบายส่วนนำหน้าและทำซ้ำส่วนของเศษส่วนต่อเนื่อง ยกตัวอย่างเช่นการป้อนข้อมูลหมายถึงส่วนอย่างต่อเนื่อง(3, [1], [2, 4])[3; 1, 2, 4, 2, 4, ...]

หากส่วนที่ทำซ้ำว่างเปล่าแสดงว่าเป็นจำนวนตรรกยะ ยกตัวอย่างเช่นการแสดงให้เห็นถึง(3, [1, 2], []) [3; 1, 2] = 11/3คุณต้องยอมรับทั้งสองรูปแบบของจำนวนตรรกยะ (เช่น(3, [1, 1, 1], [])ซึ่ง[3; 1, 1, 1] = 11/3ควรเป็นอินพุตที่ถูกต้อง)

เอาท์พุท : เอาท์พุทเศษส่วนต่อเนื่องของอินพุทเป็นสองเท่าในรูปแบบเดียวกับอินพุต หากผลลัพธ์เป็นจำนวนตรรกยะคุณอาจส่งออกรูปแบบของเศษส่วนต่อเนื่อง ตราบใดที่คำตอบนั้นเทียบเท่ากับคำตอบที่ถูกต้องมันก็ใช้ได้ ไม่จำเป็นต้องมี "การบีบอัด" ดังนั้นส่วนที่ไม่มีที่สิ้นสุดอาจเป็น "unrolled" เล็กน้อย (เช่น[1; 4, 2, 3, 2, 3...]อาจถูกเขียน(1, [4], [2, 3])หรือ(1, [4, 2, 3], [2, 3])) คำตอบทั้งหมดจะต้องแน่นอน

กรณีทดสอบ : ได้รับคอลัมน์ฟอร์มที่แน่นอนเพื่อความสะดวก

Input               Exact Form       Output
(0, [] [])          0                (0, [] []) or (-1, [1], [])
(-5, [1, 1], [])    -4.5             (-9, [], []) or (-10, [1], [])
(3, [1, 2], [])     11/3             (7, [3], []) or (7, [2, 1], [])
(1, [], [2])        sqrt(2)          (2, [], [1, 4])
(-1, [2], [2, 1])   -1/sqrt(3)       (-2, [1, 5], [2, 6])

(0, [1], [6, 1, 3, 1, 42, 1, 3, 1, 6, 2]) --> (1, [], [1, 2, 1, 8, 1, 20, 1, 8, 1, 2, 1, 2])และในที่สุดกรณีทดสอบขนาดใหญ่กว่าเล็กน้อยเพื่อให้แน่ใจว่ามีความแม่นยำ:

รหัสที่สั้นที่สุดชนะ!

คำแนะนำ : คุณสามารถดำเนินการทางคณิตศาสตร์ในลักษณะที่ค่อนข้างตรงไปตรงมาใน fractions ต่อเนื่องตามที่อธิบายไว้ที่นี่ การเสแสร้งเศษส่วนต่อเนื่องเป็นเพียงกรณีพิเศษของอัลกอริธึมนี้ (แม้ว่าส่วนที่ยุ่งยากอาจจะพบเมื่อส่วนที่ต่อเนื่องซ้ำเกิดซ้ำ)



@Pavel ไม่มีคุณจะต้องสามารถระบุการป้อนข้อมูล Sqrt[2]แต่เพียงผู้เดียวบนพื้นฐานของจำนวนเต็มคำนำหน้าและการทำซ้ำชิ้นส่วนมากกว่าที่จะเป็น
soktinpk

ขออภัยนั่นเป็นข้อผิดพลาดในส่วนของฉัน นี่คือลิงค์ที่มีเศษส่วนต่อเนื่องที่เกิดขึ้นจริงเป็นอินพุต: tio.run/##y00syUjNTSzJTE78n2b73zk/ryQzrzQ1xa0oMbkkMz8v2kjLrSg/…
Pavel

1
[3; 1, 1, 1]จะอยู่(3, [1, 1, 1], [])ในรูปแบบอินพุตที่เราใช้ - ดังนั้นคำถามน่าจะพูดถึงมันในรูปแบบนั้น (ในย่อหน้าที่สาม) เพียงเพื่อความชัดเจน
sundar - Reinstate Monica

2
มีข้อ จำกัด อะไรบ้างเกี่ยวกับวิธีลดเอาต์พุตให้น้อยที่สุด? เช่นจะ(-2, [1, 5, 2], [6, 2])เป็นเอาท์พุทที่ยอมรับได้สำหรับการป้อนข้อมูล(-1, [2], [2, 1])? แล้วไง(-2, [1, 5, 2, 6, 2, 6], [2, 6])ล่ะ
ปีเตอร์เทย์เลอร์

คำตอบ:


7

ภาษา Wolfram (Mathematica)ขนาด 44 ไบต์

ContinuedFraction[2FromContinuedFraction@#]&

ลองออนไลน์!

Mathematica มี builtin! เย้! builtin ของ Mathematica นั้นยาวมาก Aww

เศษส่วนต่อเนื่องของ Mathematica ดูเหมือนว่า {integer, ...prefix, {...repeating}}

-1 ต้องขอบคุณจองฮวานมิน


4
คุณสามารถละเว้น*เพราะคั่นเริ่มต้นของ Mathematica Timesถ้ามีไม่ได้เป็นหนึ่งคือ
JungHwan Min

3
เมื่อภาษาของคุณสร้างขึ้นสำหรับทุกอย่างตั้งแต่การให้คะแนน Scrabbleไปจนถึงการรับรู้ถึงแพะชื่อของพวกเขาบางส่วนจะต้องเป็น :)
sundar - Reinstate Monica

1
@sundar ไม่ Mathematica มีเพียง 5,000 เครื่องเท่านั้น เป็นไปได้ที่จะทำให้แต่ละบิลด์ 2 ไบต์มากที่สุด (ดู Mthmtca)
user202729

@ user202729 แต่ Mathematica คงไม่ได้รับความนิยมมากนักถ้าเป็นเช่นนั้น: P
mbomb007

3

JavaScript (ES6), 267 ไบต์

(n,f,r)=>eval(`f=[0,...f];e=i=[0,2,1,0];o=j=[];k=[];m={};while([a,b,c,d]=e,c|d&&o)i*m[s=i+m+(e=c*d&&(q=a/c|0)==(b/d|0)?(o.push(q),[c,d,a-c*q,b-d*q]):1/(++i,[p,...f]=f+f?f:(i=r[0],r),p)?[b,a+b*p,d,c+d*p]:[b,b,d,d])]?k+(o=k)?o=0:(m={})[s]=1:m[s]=1;[2*n+j.shift(),j,k]`)

ยอมรับข้อโต้แย้ง 3 ข้อ (n = ส่วนจำนวนเต็ม, f = คำนำหน้า, r = ส่วนที่ทำซ้ำ) ส่งออกสามส่วนในอาร์เรย์ ลองออนไลน์!

คำอธิบาย

มันเป็นเรื่องการดำเนินงานอย่างเป็นธรรมโดยตรงของอัลกอริทึมสำหรับการคำนวณทางคณิตศาสตร์เศษส่วนต่อเนื่องเชื่อมโยงในความท้าทายที่นี่ เงื่อนไขการทำซ้ำได้รับการจัดการโดยการจัดเก็บเมทริกซ์กลางในตารางการค้นหารอการทำซ้ำและการส่งออกคำจนกว่าการปรากฏตัวต่อไปของที่ซ้ำกันต่อไป มันไม่ค่อยซับซ้อนและเกือบเป็นสองเท่าของไบต์ที่ต้องใช้ในการจัดการเศษส่วนต่อเนื่อง แต่ฉันไม่สามารถคิดทางเลือกที่ดีกว่าได้

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

<index of input repeating part><delimiter><matrix values>เพื่อป้องกันไม่ให้ผลบวกปลอมเมื่อรอรอบซ้ำร้านค้าตารางการค้นหาข้อมูลดังต่อไปนี้:

โปรดทราบว่าเวอร์ชัน golfed ใช้evalเพื่อบันทึก 1 ไบต์

(n, f, r) => {
    f = [0, ...f];                       // use a 0 to chop off the integer part
    e = i = [0,2,1,0];                   // e: matrix with starting values to handle doubling
                                         // 0 + 2x
                                         // ------
                                         // 1 + 0x
                                         // i: tracks index of repeating part; until the function loops through the
                                         // repeating part, i is equivalent to NaN
    o = j = [];                          // o: alias for group of terms currently being computed
                                         // j: output array of non-repeating terms
    k = [];                              // k: output array of repeating terms
    m = {};                              // lookup table
    while ([a,b,c,d] = e, c | d && o)    // destructure matrix
                                         // c | d stops loop if both a/c and b/d equal infinity
        i * m[s = i + m + (              // m also serves as the delimiter; JS will stringify it as "[object Object]"
                                         // if i equals a value that is coerced to NaN, this multiplication
                                         // will be falsy
            e = c * d && (q=a/c|0) == (b/d|0) // checks if either c or d is 0 to avoid converting an Infinity value to 0 using the bitwise or
                ? (o.push(q), [c, d, a - c*q, b - d*q]) // append the output term and compute the new matrix
                : 1/(++i, [p, ...f] = f+f ? f : (i=r[0], r), p) // 1/(... p) checks if p is a valid number
                                         // f+f is a short way to check length of f; if f is an empty
                                         // array, f+f = '' (which is falsy)
                                         // if f is empty, try to replace with r
                                         // if r is empty, the value of i will be set to undefined (e.g. NaN)
                    ? [b, a + b*p, d, c + d*p]
                    : [b,b,d,d]
            )
        ]                                // checks if matrix has been cached in lookup table
            ? k+(o=k)                    // if the repeating part of the output has a value...
                ? o=0                    // o serves as a flag to halt the loop
                : (m={})[s] = 1          // reset lookup table to only hold the first duplicate matrix
            : m[s] = 1;                  // otherwise flag a matrix as seen
    return [2*n + j.shift(), j, k]       // add the doubled integer part to the first term
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.