Спростіть фракцію, що продовжується


21

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

введіть тут опис зображення

Або їх можна представити у вигляді списку значень: [a0; a1, a2, a3, ... an]

Змагання:

візьміть базовий номер: і список знаменників: і спростіть продовження дробу до спрощеного раціонального дробу: поверніть чи друкуйте чисельник і знаменник окремо.a0[a1, a2, a3, ... an]

Приклади:

  • √19 : [4;2,1,3,1,2]: 170/39
  • ℯ: [1;0,1,1,2,1,1]: 19/7
  • π: [3;7,15,1,292,1]: 104348/33215
  • ϕ: [1;1,1,1,1,1]: 13/8

Приклад реалізації: (python)

def foo(base, sequence):
    numerator = 1
    denominator = sequence[-1]
    for d in sequence[-2::-1]:
        temp = denominator
        denominator = d * denominator + numerator
        numerator = temp
    return numerator + base * denominator, denominator

Перемога:

найкоротший код у байтах: --не вбудовані файли, які роблять усю проблему дозволеною--


Ви повинні зробити це речення більш чітким, "і спростити продовження дробу до одного дробу"; якщо ви не задумали, що формулювання означає результат, 2.002можна виразити як 2002/1000. Технічно це "одиничний дріб", ви, мабуть, хочете сказати, "одиничний дріб у його найпростішому вигляді".
Чарівна восьминога урна

@carusocomputing пункт взятий .. хоча я б не почувався надто погано щодо 2/4 (або подібного), оскільки він все ще спростив структуру множинних дробів до однієї дробу
Аарон

Хм ... Я думаю, що є спосіб це використати, але, відповідаючи на гольфскрипт у 13 байтів, мені довелося б скористатися MATL, щоб перемогти.
Чарівна восьминога урна

@carusocomputing Я б сказав, щоб піти на це ... Якщо ви зможете перемогти відповідь на 13 байт, це було б приголомшливо
Аарон

Ви можете зробити пі-зупинку раніше - 355/113.
Thorbjørn Ravn Andersen

Відповіді:


15

J, 8 5 байт

Те саме, що це , але використовує вбудований модуль для раціоналів.

Аргумент є {a0, a1, a2, a3, ...} як список J розширених раціональних чисел точності. Результат є дробом у вигляді J розширеного раціонального числа точності.

(+%)/

(+%) плюс-зворотна відповідність

/ скорочення над

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

-3 завдяки милі .


Якщо ви приймаєте вхід як список розширених цілих чисел, ви можете зберегти 3 байти. Також ви в поясненні використовували поділ APL.
милі

@miles Дякую Не можу наблизитися до вбудованої заборони, ніж це. Шкода, що J не має символу композиції гака, як у Dyalog APL .
Adám

Онлайн-посилання try J перервана
Chiel ten Brinke

@ChieltenBrinke Дякую Виправлено.
Adám

12

Haskell, 37 36 18 байт

foldr1$(.(1/)).(+)

Ця функція очікує Ratioвведення типу Haskell . Приклад використання:

Prelude Data.Ratio> ( foldr1$(.(1/)).(+) )  [4%1,2,1,3,1,2] 
170 % 39

Примітка: одного явного Ratioсписку вхідних даних ( 4%1) достатньо, системи типів визначають, що і інші повинні бути Ratios.

Редагувати: @Lynn зберегла байт. Спасибі!

Правка II: видалено import(див. Це обговорення на мета ).


1
Ооо, приємний край край. Сама функція поліморфна, тому її не потребує import. Однак, щоб зателефонувати, вам доведеться подати Ratioїї до того, що потрібно import. Чи слід додати importкількість байтів чи ні?
німі

1
Це здається гарним питанням для мета.
Мартін Ендер

Я ніколи не використовував Haskell, тому виправте мене, якщо я помиляюся, але якщо еквівалент python буде: from fractions import Fractionробити операції з Fractionоб'єктами, також враховується оператор імпорту.
Аарон

.. у нас це було раніше .
nimi

@Aaron: проблема полягає в тому, що визначення функції не потребує імпорту, оскільки це поліморфно. Коли ви хочете зателефонувати, вам потрібно вказати номери типу, Ratioякі можна побудувати лише через %, для чого потрібен імпорт. Зазвичай ми не рахуємо байти для виклику накладних витрат, лише для самої функції.
німі

11

GolfScript , 13 байт

~]-1%{\-1?+}*

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

Так, для прихованих раціоналів GolfScript . :)

Пояснення

Єдиний "офіційний" номер GolfScript - це цілі числа. Але оператор експоненції не приводить свого результату до цілого числа, а зручно для власного результату цілочисельної експоненції в Ruby (мова інтерпретатора GolfScript) - це раціональне число. Тож ми можемо легко отримати дроби, піднявши щось до сили -1. Зручно, ми хочемо взагалі взагалі ...

~]     # Evaluate input and wrap all a_i in a list.
-1%    # Reverse the list so that a_n is at the start and a_0 at the end.
{      # Fold... (apply this block to each element from a_n-1 down to a_0, with
       # the previous result on the stack)
  \    #   Swap previous result with current a_i.
  -1?  #   Raise previous result to the power of -1, computing its reciprocal
       #   as a rational number.
  +    #   Add a_i.
}*

11

Математика, 23 22 байти

Fold[#2+1/#&]@*Reverse

По суті, порт моєї відповіді GolfScript . Ось кілька альтернатив:

Для 24 байтів ми можемо записати рекурсивну варіативну функцію:

f@n_=n
n_~f~m__:=n+1/f@m

Для 21 байта ми можемо навіть визначити "варіативного оператора", але його умова виклику була б такою дивною, що я неохоче рахую цей:

±n_=n
n_ ±m__:=n+1/±m

Вам доведеться викликати це послідовністю вхідних значень, наприклад, ±Sequence[3, 7, 15, 1, 292, 1]або ±##&[3, 7, 15, 1, 292, 1].

А також для 21 байта буде вбудований (заборонений):

FromContinuedFraction

10

LabVIEW, 36 еквівалентних байтів

Досить прямо наївна реалізація з використанням алгоритму ОП. Чи є кращий спосіб це зробити?

введіть тут опис зображення


5
Показано ваш ступінь електротехніки.
Чарівна восьминога урна

1
@ijustlovemath Реквізит, але ..... актуально
Аарон

Так, це певна мова. Я бачу LabVIEW як "я ненавиджу математику" у світі програмістів. Проблема полягає не в самій математиці, а в тому, як її навчають (або часто відсутність взагалі викладання).
ijustlovemath

6

Діалог APL , 10 байт

Навіть не використовує вбудований для раціоналістів.

Бере {a 0 , a 1 , 2 , a 3 , ...} як аргумент, повертає {знаменник, чисельник}.

1(,÷∨)+∘÷/

1(,÷∨) 1-попередньо-ділити на GCD на 1 і

+∘÷ плюс-зворотний

/ скорочення над

СпробуйтеAPAP онлайн!


6

Python 2, 62 байти

a=d=0
b=c=1
for n in input():a,b=b,n*b+a;c,d=d,n*d+c
print b,d

Це, на жаль, не настільки вибагливо (див. Відповідь @ xnor коротше), але він обчислює дріб, не потребуючи зворотного введення. Для цього використовується підхід "магічної таблиці" для конвергентів - з огляду на дві останні фракції a/cі b/d, наступний дріб є (n*b+a)/(n*c+d).

Наприклад, для pi:

          3    7    15     1      292        1

  0   1   3   22   333   355   103993   104348
  1   0   1    7   106   113    33102    33215

Ми можемо бачити , що 15*22 + 3 = 333, 15*7 + 1 = 106, 1*333 + 22 = 355, 1*106 + 7 = 113і т.д.


4

М, 5 байт

Ṛİ+¥/

Вхід - це список значень, [a0, a1, ..., aN]і він виводить раціональне число.

Спробуйте в Інтернеті! або Перевірте всі тестові випадки.

Пояснення

Ṛİ+¥/  Input: list A
Ṛ      Reverse A
    /  Reduce A from left to right using
   ¥     A dyadic chain
 İ         Take the reciprocal of the left value
  +        Add the reciprocal to the right value
       Return and print implicitly

1
Що це? Якийсь новий діалект желей?
Адам

@miles насправді 9 байт вибачте :(
Аарон

@ Adám Це стара вилка Jelly, призначена для математики та символіки. Ось його ретро Github .
милі

1
@Aaron M використовує ту саму кодову сторінку , що і Jelly, і її можна закодувати за допомогою байта для кожного символу.
милі

@miles ОК, додано .
Adám

4

Haskell, 30 байт

foldr(\h(n,d)->(h*n+d,n))(1,0)

Рекурсивно додає кожен шар, виходячи назовні, оновлюючись n/dдо h+(1/(n/d)), що дорівнює h+d/nабо (h*n+d)/n. Фракція зберігається як кортеж (num,denom). Початкова частка (1,0)фліп до 0/1якої становить 0.


3

Пітон, 50 байт

f=lambda l,n=1,d=0:l and f(l,l.pop()*n+d,n)or(n,d)

Побудова триває дробу з кінця списку, що йде назад, повторно оновлюючи дріб n/dна останньому елементі xяк n/d -> 1+1/(n/d) == (x*n+d)/n.


3

 Загальний Лісп, 54

Дещо багатослівна складка вправо:

(lambda(s)(reduce(lambda(a r)(+(/ r)a))s :from-end t))

Тести

PASS  NAME  ACTUAL               EXPECTED
===============================================
T     √19   170/39               170/39              
T     ℯ     19/7                 19/7                
T     π     104348/33215         104348/33215        
T     ϕ     13/8                 13/8                

2

Джулія (53 байти)

Це мій перший раз, коли я використовую Джулію, якби я не помітив ітератора, я міг би втратити ще кілька байт, дайте мені знати. Ось підказка всім, хто не знає, яку мову вибрати для цього конкретного виклику: https://en.wikipedia.org/wiki/Rational_data_type

f(x,c)=(a=0;for b in x[end:-1:1];a=1//(b+a);end;a+c;)
  • Зворотний вхідний масив.
  • Ітерайте через нього раціональним поділом.
  • До десяткового результату додайте c.

ви можете зберегти два байти, визначивши оператора (наприклад ) замість функції
Tasos Papastylianou

також на деякий час змініть цикл for і x∘c=(a=0;while x!=[];a=1//(pop!(x)+a);end;a+c;)
натисніть

1
25: x->foldr((x,y)->x+1//y,x)(те саме, що і рішення Haskell). використання:(x->foldr((x,y)->x+1//y,x))([4//1,2,1,3,1,2])
Fengyang Wang

Ооо ... Функція зворотного складання? Це прекрасно! Я не заслуговую на те, щоб брати за це кредит, ха-ха.
Чарівна восьминога урна

2

Javascript (ES6), 55 байт

s=>eval('for(F=[1,0];s+"";)F=[s.pop()*F[0]+F[1],F[0]]')

Тестові кейси

var f =
s=>eval('for(F=[1,0];s+"";)F=[s.pop()*F[0]+F[1],F[0]]')

console.log(f([4, 2, 1, 3, 1, 2]));
console.log(f([1, 0, 1, 1, 2, 1, 1]));
console.log(f([3, 7, 15, 1, 292, 1]));
console.log(f([1, 1, 1, 1, 1, 1]));


2

CJam , 18 16 байт

XUq~W%{2$*+\}/]p

Онлайн-перекладач .

XU                  Push 1 and 0 to the stack
  q~W%              Push input, eval and reverse it
      {     }/      For each n in the reversed input...
       2$             Copy numerator
         *+           Calculate n*denominator + numerator
           \          Swap numerator and denominator
              ]p   Wrap in array and output

2

05AB1E , 19 17 байт

R¬V¦vyY*X+YUV}YX)

Пояснення

Введення прийнято як список чисел

                     # variable X is initialized as 1
R¬V¦                 # reverse the list, remove the first item and store it in variable Y
    v        }       # for each item N left in list
     yY*X+  V        # store N*Y+X in Y
          YU         # store Y in X
              YX)    # wrap X and Y in a list

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



1

Javascript (ES6), 50 байт

f=(s,n=1,d=s.pop())=>s+""?f(s,d,s.pop()*d+n):[d,n]

Це завдяки відповіді Арнальда, перед тим, як побачити, я затримався на 66 байтах:

f=(b,s,i=s.length-1,n=1,d=s[i])=>i?f(b,s,--i,d,s[i]*d+n):[n+b*d,d]

Приклад:
Дзвінок: f([1, 0, 1, 1, 2, 1, 1])
вихід:Array [ 19, 7 ]


1

Perl 6 , 24 байти

{[R[&(1/*+*)]](@_).nude}

Пояснення:

  • 1 / * + *- лямбда з двома параметрами ( *), яка приймає зворотну частину першого, а додає другий. (повертає щура )

  • R[&(…)]використовує це, як ніби це інфіксний оператор, і реверсує його.
    (у тому числі зробити його правильним асоціативним)

  • […](@_) приймає це і використовує його для зменшення введення.

  • … .nudeповертає ню merator і де чисельник від Щура .

  • { … }зробіть це голий блок лямбда з неявним параметром @_.

Використання:

say {[R[&(1/*+*)]](@_).nude}(3,7,15,1,292,1) #*/# (104348 33215)

my &code = {[R[&(1/*+*)]](@_).nude}; # stupid highlighter */

say code 4,2,1,3,1,2;    # (170 39)
say code 1,0,1,1,2,1,1;  # (19 7)
say code 1,1,1,1,1,1;    # (13 8)

1

Зефір , 145 байт

input n as Integer
set a to Array(n)
for i from 1to n
input a[i]as Integer
next
set r to a[n]
for i from 1to n-1
set r to(/r)+a[n-i]
next
print r

Зефір - перша мова програмування, яку я коли-небудь створив. Він був розроблений так, щоб бути інтуїтивно зрозумілим і мати чистий синтаксис - швидше за рахунок стислості. Чому я гольфу з ним, запитаєте ви? Тому що, на відміну від будь-якої мови, якою я писав, вона має вбудований Fractionтип. Можна навіть скористатися оператором поділу/ як одинаковий оператор для "зворотного" (функція, яку я запозичив для Піпа).

Зараз існують значні обмеження. Найбільшою проблемою для цього виклику є те, що масиви повинні визначатися з фіксованим розміром, а це означає, що програма починається з зчитування розміру масиву у користувача. (Я сподіваюся, що це нормально; альтернативою є жорстке кодування розміру.) Існує також незначна проблема в тому, що пріоритет оператора не існує, тобто багатовиробничі вирази повинні мати круглі дужки.

Ось приклад запуску:

C:\Zephyr> python zephyr.py contfrac.zeph
6
1
1
1
1
1
1
13/8

1

Рубін, 34 байти

->a{a.reverse.inject{|b,i|i+1r/b}}

Це виконує праву складку (обертаючи назад, а потім ліву складку), додаючи кожен елемент до 1 над загальною кількістю (елементи праворуч). Рубі має тип Раціональний, що дуже добре. А буквальні раціонали - це число, суфікс r.



1

APL (NARS), 15 + 1 символів, 30 + 2 байти

{1=≢⍵:↑⍵⋄+∘÷/⍵}

Переклад у Apl (Nars) з рішення Дж. Адама ... вхід, дозволений для цієї функції, буде весь список цілих чисел, де перший елемент буде тип раціональним. Тест:

  f←{1=≢⍵:↑⍵⋄+∘÷/⍵}      
  f 4x 2 1 3 1 2
170r39 
  f 1x 0 1 1 2 1 1
19r7 
  f 3x 7 15 1 292 1
104348r33215 
  f 1x 1 1 1 1 1
13r8 
  f 3x 89 888 999 11 222 373 7282 9272 3839 2828 
158824716824887954093160207727r52744031585005490644982548907 
  f ,0x
0 
  f ,9x
9 

тож було б 15 символів як довжина функції та 1 символ для "х" для введення типу вводу, який я хочу, і виходу з типу, який я хочу ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.