Подвійне число продовження числа


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також має бути дійсним введенням).

Вихід : Виведіть триваючу частку в два рази в тому ж форматі, що і вхід. Якщо результат є раціональним, ви можете вивести будь-яку форму тривалої фракції. Поки відповідь еквівалентна правильній відповіді, це добре; не потрібно «стиснення», тому нескінченна частина може трохи «розкручуватися» (наприклад, [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]).

Найкоротший код виграє!

Підказка : Ви можете виконувати арифметику досить прямо на тривалих дробах, як описано тут . Подвійне продовження дробу є лише особливим випадком цього алгоритму (хоча складну частину можна знайти, коли повторний дріб повторюється).



@Pavel Ні, ви повинні мати можливість вказувати вхід виключно на основі цілого числа, префікса та повторюваних частин, а не як Sqrt[2].
soktinpk

Вибачте, це була помилка з мого боку. Ось посилання з фактичним продовжуваним дробом як вхідним: tio.run/##y00syUjNTSzJTE78n2b73zk/ryQzrzQ1xa0oMbkkMz8v2kjLrSg/…
Павло

1
[3; 1, 1, 1]буде (3, [1, 1, 1], [])у вхідному форматі, який ми використовуємо - тому питання, ймовірно, повинно згадувати його у тому форматі (у третьому абзаці), просто для забезпечення ясності
sundar

2
Які обмеження існують щодо того, наскільки мінімальним повинен бути вихід? Наприклад, чи (-2, [1, 5, 2], [6, 2])буде прийнятним вихід для введення (-1, [2], [2, 1])? Як щодо (-2, [1, 5, 2, 6, 2, 6], [2, 6])?
Пітер Тейлор

Відповіді:


7

Мова Вольфрама (Mathematica) , 44 байти

ContinuedFraction[2FromContinuedFraction@#]&

Спробуйте в Інтернеті!

У Mathematica є вбудований! Так! Математика вбудована дуже довго. Aww.

Продовжуються дроби Mathematica {integer, ...prefix, {...repeating}}

-1 спасибі ДжунХвану Мін


4
Ви можете опустити цей *роздільник, оскільки Mathematica за замовчуванням є, якщо його немає Times.
JungHwan Min

3
Коли у вашій мові є додаткові відомості про все, від зарахування Scrabble до розпізнавання козлів , деякі їхні назви повинні бути "надзвичайно довгими" за необхідності. :)
sundar

1
@sundar Ні, Mathematica має лише 5000 вбудованих. Можна зробити кожен вбудований максимум 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>.

Зверніть увагу, що версія 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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.