継続的な分数を単純化する


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。それは技術的には「単一の分数」であり、おそらく「最も単純な形の単一の分数」と言いたいでしょう。
魔法のタコUr

@carusocomputing point taken .. 2/4(または同様)についてはそれほど悪くは感じませんが、それでも複数のフラクション構造が単一のフラクションに単純化されているため
アーロン

うーん...それを活用する方法はあると思いますが、13バイトのgolfscriptの答えでは、勝つためにおそらくMATLを使用する必要があります。
魔法のタコUr

@carusocomputing私はそれのために行くと言うでしょう... 13バイトの答えを打つことができるなら、それは素晴らしいことです
アーロン

piをより早く停止させることができます-355/113。
するThorbjörnRavnアンデルセン

回答:


15

J、8 5バイト

これと同じですが、有理数にビルトインを使用します。

引数は、J拡張精度有理数のリストとして{a0、a1、a2、a3、...}です。結果は、J拡張精度有理数としての分数です。

(+%)/

(+%) プラスの逆数

/ 削減

オンラインでお試しください!

マイルのおかげで-3 。


入力を拡張整数のリストとして取得すると、3バイト節約できます。また、説明でAPL部門を使用しました。
マイル

@milesありがとう。それよりもビルトイン禁止に近づくことはできません。Jには、Dyalog APLのようなフック構成文字がありません
アダム

試しJオンラインリンクが壊れている
Chiel 10 Brinkeを

@ChieltenBrinkeありがとう。一定。
アダム

12

Haskell、37 36 18バイト

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

この関数は、HaskellのRatio型を入力として期待します。使用例:

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

注:Ratio入力リスト(4%1)に明示的に1つあれば十分ですが、型システムは、他のものもRatiosである必要があると判断します。

編集:@Lynnはバイトを保存しました。ありがとう!

編集II:を削除しましたimportmetaに関するこの議論を参照)。


1
うーん、素敵なエッジケース。関数自体は多態性であるため、を必要としませんimport。ただし、それを呼び出すには、を必要とするにフィードRatioする必要がありimportます。importバイトカウントに追加する必要がありますか?
nimi

1
それはメタにとっては良い質問のように聞こえます。
マーティンエンダー

私はHaskellを使用したことがないので、間違っている場合は修正しますが、Pythonの等価性がオブジェクトのfrom fractions import Fraction操作を行うFraction場合、importステートメントもカウントされます。
アーロン


@Aaron:問題は、関数の定義がインポートである必要がないことです。なぜなら、それは多態的だからです。呼び出したい場合は、をRatio介してのみ構築できる型の番号を指定する必要があります%。これにはインポートが必要です。通常、呼び出し自体のオーバーヘッドはカウントせず、関数自体だけをカウントします。
nimi

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

Mathematica、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相当バイト

OPのアルゴリズムを使用したかなり単純な単純な実装。これを行うより良い方法はありますか?

ここに画像の説明を入力してください


5
電気工学の学位が表示されています。
魔法のタコUr

1
@ijustlovemath小道具、しかし..... 関連
アーロン

ええ、それは確かに議論の余地のある言語です。LabVIEWはプログラマの世界の「数学が嫌い」だと思っています。問題は数学そのものではなく、それがどのように教えられているか(またはしばしばまったく教えられていないこと)です。
-ijustlovemath

6

Dyalog APL、10 バイト

理性のためにビルトインさえ使用しません。

引数として{a 0、a 1、a 2、a 3、...}を取り、{denominator、numerator}を返します。

1(,÷∨)+∘÷/

1(,÷∨) 1の先頭に1のGCDで割った値と

+∘÷ プラスの逆数

/ 削減

TryAPLオンライン!


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の回答を参照)、入力を逆にする必要なく分数を計算します。これは、収束に対して「マジックテーブル」アプローチを使用します。最後の2つの分数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 = 33315*7 + 1 = 1061*333 + 22 = 3551*106 + 7 = 113、など


4

M、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 OK、追加しました
アダム

4

Haskell、30バイト

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

再帰的にそれぞれの層は、外側に行くの更新追加n/dh+(1/(n/d))等しい、h+d/nまたは(h*n+d)/n。分数はのタプルとして保存され(num,denom)ます。(1,0)フリップの最初の割合0/10です。


3

Python、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

 Common Lisp、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;)
  • 入力配列を逆にします。
  • 合理的な除算で繰り返します。
  • 10進結果にcを追加します。

あなたは、(例えばオペレータを定義することによって、2つのバイトを保存することができます関数の代わりに)
Tasos Papastylianou

また、しばらくの間、forループを変更するとポップアップ:x∘c=(a=0;while x!=[];a=1//(pop!(x)+a);end;a+c;)
Tasos Papastylianou

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])
豊陽王

うーん...逆折り畳み機能?美しいです!ハハですが、私はそれを称賛するに値しません。
魔法のタコUr

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

CJam18 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

05AB1E19 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

オンラインでお試しください!


2

JavaScript(ES6)、44バイト

a=>a.reduceRight(([n,d],v)=>[v*n+d,n],[1,0])

1

Javascript(ES6)、50バイト

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

Arnauldの答えのおかげです。それを見る前に、私は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 / * + *は2つのパラメーター(*)を持つラムダで、最初のパラメーターの逆数を取り、2番目のパラメーターを追加します。(Ratを返します)

  • R[&(…)]それを中置演算子であるかのように使用し、それを逆にします。
    (適切な関連付けを含む)

  • […](@_) それを受け取り、それを使用して入力を減らします。

  • … .nude戻りNUの 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

Zephyrは、私が作成した最初のプログラミング言語です。直感的で簡潔な構文を持つように設計されました-簡潔さを犠牲にします。なぜ私はそれでゴルフをしているのですか?なぜなら、それ以来私が書いたどの言語とも異なり、組み込みFraction型を持っているからです。除算演算子/を「逆」の単項演算子として使用することもできます(私はPipのために借りた機能です)。

現在、重大な制限があります。この課題の最大の問題は、配列を固定サイズで定義する必要があることです。つまり、プログラムはユーザーから配列のサイズを読み取ることで開始されます。(これが大丈夫であることを望みます;代替案はサイズをハードコーディングすることです。)演算子の優先順位が存在しないという小さな問題もあります。つまり、マルチ演算子式には括弧が必要です。

実行例を次に示します。

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を追加します。RubyにはRationalタイプがあり、これは本当に素晴らしいです。そして、リテラルの有理数は接尾辞が付いた数字rです。


1

スタックス、4 バイト

╣╩┼►

実行してデバッグする

小さいので、組み込みではありません。ビルトインされた理論的根拠はかなり役立ちます。asciiに解凍されたプログラムはrksu+です。

  1. 配列を逆にします。
  2. を使用して配列を折りたたみ(a, b) => (a + 1/b)ます。

1

APL(NARS)、15 + 1文字、30 + 2バイト

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

Adam Jソリューションからの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文字で、「x」は1文字で、必要な入力のタイプを入力し、必要なタイプを終了します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.