クイズ 連分数

PythonのSymPyのネットにあるチュートリアルを読んでいたら、連分数のクイズがありました。

連分数とは分数の中に分数があるような以下のような形の分数です。

from sympy import *
init_printing()
x,y,z = symbols('x y z')

def list_to_frac(l):
    expr = Integer(0)
    for i in reversed(l[1:]):
        expr += i
        expr = 1 / expr
    return l[0] + expr
frac = list_to_frac([x,y,z])
frac

$$x + \frac{1}{y + \frac{1}{z}}$$

一般的な形としては添字付きの変数であらわします。

syms = symbols('a0:5')
syms

$$\left ( a_{0}, \quad a_{1}, \quad a_{2}, \quad a_{3}, \quad a_{4}\right )$$

a0, a1, a2, a3, a4 = syms

frac = list_to_frac(syms)
frac

$$a_{0} + \frac{1}{a_{1} + \frac{1}{a_{2} + \frac{1}{a_{3} + \frac{1}{a_{4}}}}}$$

さてこれを通分すると次のようになります。

frac=cancel(frac)
frac

$$\frac{a_{0} a_{1} a_{2} a_{3} a_{4} + a_{0} a_{1} a_{2} + a_{0} a_{1} a_{4} + a_{0} a_{3} a_{4} + a_{0} + a_{2} a_{3} a_{4} + a_{2} + a_{4}}{a_{1} a_{2} a_{3} a_{4} + a_{1} a_{2} + a_{1} a_{4} + a_{3} a_{4} + 1}$$

で問題は、変数をランダムに混ぜて、cancelされた式から元の連分数をつくれ、というものです。

import random
l = list(symbols('a0:5'))
random.shuffle(l)
orig_frac = frac = cancel(list_to_frac(l))
del l

ここでlを求めるわけですが、先に答えを見たりしないようにご丁寧にlを消去しています。
解いたあと、正解かどうかはorig_fracと、求めたlでcancel(list_to_frac(l))したものを比べれば確認できます。

frac

$$\frac{a_{0} a_{1} a_{2} a_{3} a_{4} + a_{0} a_{1} a_{3} + a_{0} a_{2} a_{4} + a_{0} + a_{1} a_{2} a_{4} + a_{1} a_{3} a_{4} + a_{1} + a_{4}}{a_{0} a_{2} a_{3} a_{4} + a_{0} a_{3} + a_{2} a_{4} + a_{3} a_{4} + 1}$$

l=[]
frac = apart(frac, a1)
frac

$$a_{1} + \frac{a_{0} a_{2} a_{4} + a_{0} + a_{4}}{a_{0} a_{2} a_{3} a_{4} + a_{0} a_{3} + a_{2} a_{4} + a_{3} a_{4} + 1}$$

l.append(a1)
frac = 1/(frac - a1)
frac

$$\frac{1}{a_{0} a_{2} a_{4} + a_{0} + a_{4}} \left(a_{0} a_{2} a_{3} a_{4} + a_{0} a_{3} + a_{2} a_{4} + a_{3} a_{4} + 1\right)$$

frac = apart(frac, a3)
frac

$$a_{3} + \frac{a_{2} a_{4} + 1}{a_{0} a_{2} a_{4} + a_{0} + a_{4}}$$

l.append(a3)
frac = 1/(frac - a3)
frac

$$\frac{a_{0} a_{2} a_{4} + a_{0} + a_{4}}{a_{2} a_{4} + 1}$$

frac = apart(frac, a0)
frac

$$a_{0} + \frac{a_{4}}{a_{2} a_{4} + 1}$$

l.append(a0)
frac = 1/(frac - a0)
frac

$$\frac{1}{a_{4}} \left(a_{2} a_{4} + 1\right)$$

frac = apart(frac, a2)
frac

$$a_{2} + \frac{1}{a_{4}}$$

l.append(a2)
frac = 1/(frac - a2)
frac

$$a_{4}$$

frac = apart(frac, a4)
frac

$$a_{4}$$

l.append(a4)
list_to_frac(l)

$$a_{1} + \frac{1}{a_{3} + \frac{1}{a_{0} + \frac{1}{a_{2} + \frac{1}{a_{4}}}}}$$

l

$$\left [ a_{1}, \quad a_{3}, \quad a_{0}, \quad a_{2}, \quad a_{4}\right ]$$

orig_frac

$$\frac{a_{0} a_{1} a_{2} a_{3} a_{4} + a_{0} a_{1} a_{3} + a_{0} a_{2} a_{4} + a_{0} + a_{1} a_{2} a_{4} + a_{1} a_{3} a_{4} + a_{1} + a_{4}}{a_{0} a_{2} a_{3} a_{4} + a_{0} a_{3} + a_{2} a_{4} + a_{3} a_{4} + 1}$$

cancel(list_to_frac(l))

$$\frac{a_{0} a_{1} a_{2} a_{3} a_{4} + a_{0} a_{1} a_{3} + a_{0} a_{2} a_{4} + a_{0} + a_{1} a_{2} a_{4} + a_{1} a_{3} a_{4} + a_{1} + a_{4}}{a_{0} a_{2} a_{3} a_{4} + a_{0} a_{3} + a_{2} a_{4} + a_{3} a_{4} + 1}$$