Gandakan pecahan lanjutan angka

21

Tugas Anda adalah, diberikan x, keluaran 2*x. Mudah kan !? Tapi ada tangkapan: xakan diberikan sebagai fraksi lanjutan (mungkin tak terbatas) , dan output harus fraksi lanjutan. Input dijamin menjadi bilangan aljabar nyata yang tingkatannya paling banyak 2.

Input : Fraksi lanjutan dari x. Ini dibagi menjadi 3 bagian: bagian integer, awalan, dan bagian berulang. Bagian integer terdiri dari satu integer. Awalan dan bagian berulang adalah (mungkin kosong) array bilangan bulat positif yang menggambarkan awalan dan bagian berulang dari fraksi lanjutan. Misalnya, input (3, [1], [2, 4])mewakili fraksi lanjutan [3; 1, 2, 4, 2, 4, ...].

Jika bagian berulang kosong, itu menunjukkan angka rasional. Misalnya, (3, [1, 2], [])mewakili [3; 1, 2] = 11/3. Anda harus menerima kedua bentuk bilangan rasional (yaitu (3, [1, 1, 1], []), yang [3; 1, 1, 1] = 11/3juga harus menjadi input yang valid).

Keluaran : Keluarkan fraksi lanjutan dari dua kali input, dalam format yang sama dengan input. Jika outputnya rasional, Anda dapat menampilkan salah satu bentuk fraksi lanjutan. Selama jawabannya setara dengan jawaban yang benar, itu baik-baik saja; tidak ada "kompresi" yang diperlukan, sehingga bagian yang tak terbatas mungkin "sedikit terbuka" (misalnya [1; 4, 2, 3, 2, 3...]dapat ditulis (1, [4], [2, 3])atau (1, [4, 2, 3], [2, 3])). Semua jawaban harus tepat.

Kasus uji : Kolom formulir yang tepat diberikan untuk kenyamanan.

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

Dan akhirnya kasus uji yang sedikit lebih besar untuk memastikan presisi: (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]).

Kode terpendek menang!

Petunjuk : Anda dapat melakukan aritmatika dengan cara yang langsung pada fraksi lanjutan seperti dijelaskan di sini . Menggandakan fraksi lanjutan hanya merupakan kasus khusus dari algoritma ini (meskipun bagian yang sulit adalah menemukan ketika fraksi lanjutan berulang).

soktinpk
sumber
@Pavel Tidak, Anda harus dapat menentukan input hanya berdasarkan integer, awalan, dan bagian berulang daripada sebagai Sqrt[2].
soktinpk
Maaf, itu kesalahan saya. Inilah tautan dengan fraksi lanjutan aktual sebagai masukan: tio.run/##y00syUjNTSzJTE78n2b73zk/ryQzrzQ1xa0oMbkkMz8v2kjLrSg/…
Pavel
1
[3; 1, 1, 1]akan berada (3, [1, 1, 1], [])dalam format input yang kami gunakan - jadi pertanyaannya mungkin harus menyebutkannya dalam format itu (dalam paragraf ketiga), hanya untuk memastikan kejelasan.
sundar - Reinstate Monica
2
Kendala apa yang ada pada bagaimana meminimalkan output harus? Misalnya akan (-2, [1, 5, 2], [6, 2])menjadi input yang dapat diterima (-1, [2], [2, 1])? Bagaimana dengan (-2, [1, 5, 2, 6, 2, 6], [2, 6])?
Peter Taylor

Jawaban:

7

Bahasa Wolfram (Mathematica) , 44 byte

ContinuedFraction[2FromContinuedFraction@#]&

Cobalah online!

Mathematica memiliki builtin! Yay! Builtin Mathematica sangat panjang. Aww.

Fraksi lanjutan Mathematica terlihat seperti {integer, ...prefix, {...repeating}}

-1 terima kasih kepada JungHwan Min

Pavel
sumber
4
Anda dapat menghilangkan *pembatas karena Mathematica, jika tidak ada, adalah Times.
JungHwan Min
3
Saat bahasa Anda memiliki dasar untuk semuanya, mulai dari penilaian Scrabble hingga pengenalan kambing , beberapa nama mereka harus "super panjang" karena kebutuhan. :)
sundar - Reinstate Monica
1
@sundar Tidak, Mathematica hanya memiliki ~ 5000 builtin. Dimungkinkan untuk membuat masing-masing builtin 2 byte paling banyak (lihat Mthmtca)
user202729
@ user202729 Tapi Mathematica tidak akan begitu populer jika melakukan itu: 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]`)

Menerima 3 argumen (n = bagian integer, f = awalan, r = bagian berulang). Output tiga bagian dalam sebuah array. Cobalah online!

Penjelasan

Ini adalah implementasi yang cukup langsung dari algoritma untuk menghitung fraksi aritmatika lanjutan yang terkait dengan tantangan di sini . Istilah berulang ditangani dengan menyimpan matriks perantara dalam tabel pencarian, menunggu duplikat, dan mengeluarkan persyaratan sampai tampilan duplikat berikutnya. Ini tidak valid dan hampir menggandakan byte yang diperlukan untuk menangani pecahan yang berkelanjutan, tapi saya tidak bisa memikirkan alternatif yang lebih baik.

Istilah terkemuka dihitung secara terpisah untuk memastikan bahwa pecahan lanjutan negatif mempertahankan nilai positif untuk semua syarat kecuali yang pertama.

Untuk mencegah positif palsu ketika menunggu siklus berulang, toko tabel data sebagai berikut: <index of input repeating part><delimiter><matrix values>.

Perhatikan bahwa versi golf digunakan evaluntuk menghemat 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
}
redundansi
sumber