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


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.