Nhân đôi một số tiếp tục


21

Nhiệm vụ của bạn là, được đưa ra x, đầu ra 2*x. Dễ nhỉ!? Nhưng có một nhược điểm: xsẽ được đưa ra dưới dạng phân số tiếp tục (có thể là vô hạn) và đầu ra phải là phân số tiếp tục. Đầu vào được đảm bảo là một số đại số thực có mức độ nhiều nhất là 2.

Đầu vào : Phần tiếp tục của x. Điều này được chia thành 3 phần: phần nguyên, tiền tố và phần lặp lại. Phần nguyên bao gồm một số nguyên duy nhất. Tiền tố và phần lặp lại là các mảng (có thể trống) của các số nguyên dương mô tả phần tiền tố và phần lặp lại của phần tiếp tục. Ví dụ, đầu vào (3, [1], [2, 4])đại diện cho phần tiếp tục [3; 1, 2, 4, 2, 4, ...].

Nếu phần lặp lại trống, điều đó chỉ ra số hữu tỷ. Ví dụ, (3, [1, 2], [])đại diện [3; 1, 2] = 11/3. Bạn phải chấp nhận cả hai dạng số hữu tỷ (nghĩa (3, [1, 1, 1], [])[3; 1, 1, 1] = 11/3cũng phải là đầu vào hợp lệ).

Đầu ra : Xuất ra phần tiếp tục của hai lần đầu vào, có cùng định dạng với đầu vào. Nếu đầu ra là hợp lý, bạn có thể xuất một trong hai dạng của phân số tiếp tục. Miễn là câu trả lời tương đương với câu trả lời đúng, nó vẫn ổn; không có "nén" là cần thiết, vì vậy phần vô hạn có thể "không được kiểm soát" một chút (ví dụ [1; 4, 2, 3, 2, 3...]có thể được viết (1, [4], [2, 3])hoặc (1, [4, 2, 3], [2, 3])). Tất cả các câu trả lời phải chính xác.

Các trường hợp thử nghiệm : Cột biểu mẫu chính xác được đưa ra để thuận tiện.

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

Và cuối cùng là một trường hợp thử nghiệm lớn hơn một chút để đảm bảo độ chính xác : (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]).

Mã ngắn nhất sẽ thắng!

Gợi ý : Bạn có thể thực hiện số học theo cách khá đơn giản trên các phân số tiếp tục như được mô tả ở đây . Nhân đôi một phân số tiếp tục chỉ là một trường hợp đặc biệt của thuật toán này (mặc dù phần khó khăn có thể được tìm thấy khi phân số tiếp tục lặp lại).



@Pavel Không, bạn phải có thể chỉ định đầu vào chỉ dựa trên số nguyên, tiền tố và các phần lặp lại chứ không phải là Sqrt[2].
soktinpk

Xin lỗi, đó là một sai lầm về phía tôi. Đây là liên kết với phân số tiếp tục thực tế là đầu vào: tio.run/##y00syUjNTSzJTE78n2b73zk/ryQzrzQ1xa0oMbkkMz8v2kjLrSg/ của
Pavel

1
[3; 1, 1, 1]sẽ (3, [1, 1, 1], [])ở định dạng đầu vào mà chúng tôi đang sử dụng - vì vậy câu hỏi có lẽ nên đề cập đến ở định dạng đó (trong đoạn thứ ba), chỉ để đảm bảo sự rõ ràng.
- Phục hồi Monica

2
Có những hạn chế nào về cách tối thiểu hóa đầu ra phải được? Ví dụ, sẽ (-2, [1, 5, 2], [6, 2])được chấp nhận đầu ra cho đầu vào (-1, [2], [2, 1])? Thế còn (-2, [1, 5, 2, 6, 2, 6], [2, 6])?
Peter Taylor

Câu trả lời:


7

Ngôn ngữ Wolfram (Mathicala) , 44 byte

ContinuedFraction[2FromContinuedFraction@#]&

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

Mathematica có tích hợp! Yay! Nội dung của Mathicala là siêu dài. À.

Các phân số tiếp tục của Mathicala trông giống như {integer, ...prefix, {...repeating}}

-1 cảm ơn JungHwan Min


4
Bạn có thể bỏ qua *dấu phân cách mặc định của Mathicala, nếu không có, là Times.
JungHwan Min

3
Khi ngôn ngữ của bạn có nội dung cho mọi thứ, từ ghi điểm Scrabble đến nhận dạng Dê , một số tên của chúng sẽ phải "siêu dài" bởi sự cần thiết. :)
- Phục hồi Monica

1
@sundar Không, Mathicala chỉ có ~ 5000 nội dung. Có thể tạo tối đa 2 byte tích hợp (xem M tiết lộ)
user202729

@ user202729 Nhưng Mathicala sẽ không được yêu thích nếu nó làm điều đó: P
mbomb007

3

JavaScript (ES6), 267 byte

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

Chấp nhận 3 đối số (n = phần nguyên, f = tiền tố, r = phần lặp lại). Đầu ra ba phần trong một mảng. Hãy thử trực tuyến!

Giải trình

Đây là một triển khai khá trực tiếp của thuật toán để tính toán số học phân số liên tục trong thử thách ở đây . Các thuật ngữ lặp lại được xử lý bằng cách lưu trữ các ma trận trung gian trong bảng tra cứu, chờ đợi một bản sao và xuất ra các điều khoản cho đến khi xuất hiện tiếp theo của bản sao đó. Nó không phù hợp và gần gấp đôi số byte cần thiết để xử lý các phân số tiếp tục, nhưng tôi không thể nghĩ ra một giải pháp thay thế nào tốt hơn.

Thuật ngữ hàng đầu được tính riêng để đảm bảo rằng các phân số tiếp tục âm giữ lại các giá trị dương cho tất cả các thuật ngữ chặn đầu tiên.

Để ngăn chặn các kết quả dương tính giả khi chờ một chu kỳ lặp lại, bảng tra cứu lưu trữ dữ liệu như sau : <index of input repeating part><delimiter><matrix values>.

Lưu ý rằng phiên bản golf sử dụng evalđể tiết kiệm 1 byte.

(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
}
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.