LoginSignup
0
3

More than 1 year has passed since last update.

pythonを便利に使おう第二回! 数学編

Posted at

初めに

問題を解くのに利用するとすれば、何が良いのか。紙には自由自在に文字を書き殴れるという利点があり、パソコンであれば、プログラムにあらゆる処理を肩代わりさせることが出来るという利点がある。それぞれの利点は、お互いの弱点にもなり得るのは、わかりやすい問題点でしょう。
ここで、どちらのほうが良いのか、という問に対して、一言で答えを出すというのは難しいことでしょう。ならば、試してみれば良いのです。
正答率が高いほうが、より優秀な手段と言えるでしょう。人類が先に、先に進むのであれば、優秀な手段でより優秀な手段を子供に学習させていくという必要があるでしょうし、教育の研究等にはきっとこういうことなのでしょう(何も知らないけど)。

とかいう前置きはさておき!

数学の問題をpythonで解いてやろうというお話です。
問題を解く上でのレギュレーションとしては人に答えを聞きに行かないこと、それ以外であれば問題を解くための何をしてもOK!という気分でやってきます。

問題としてこちらを使わせていただきました。
https://web.math-aquarium.jp/reidai-zissuu_1zihutousiki-2.pdf

実数,1 次不等式

人にとって記憶するというのが一番苦手な人も多いでしょう。数学は記憶することが少ないから得意、という人はたまにいます。確かに、数学に記憶することが少ないというのはわかりますが、しかしほんの少しは覚える必要のあることがあります。
数学を使うということは、覚える必要のある物事をほんの少しでも覚えておく必要がありますが、それをプログラムで解決して、記憶しないという効率化を図りたいと思います。

第一問 次の分数を小数で表わせ。

\frac{1}{6}\qquad\frac{1}{8}\qquad\frac{1}{11}\\

これについてはsympyに入れずに、とりあえずpythonで出力させましょう

>>> 1/6
0.16666666666666666
>>> 1/8
0.125
>>> 1/11
0.09090909090909091

しかし解答を見てみると、循環小数で表現するようにとなっています。つまりは0.16の6に上にドットを置く書き方が良いでしょう。それがsympyで出来る関数があれば良いのですが…と、アニメ(ひげを剃って女子高生を拾うやつ)を一話見終わるくらいの時間ググってみたんですが、見つかりませんでした。
これでは効率化を出来ません。では、どうしましょう。
ちょっくら循環小数について研究してみましょう。

小数

先に言っておきますが、行き当りばったりでやっています。答えが出ないことがありますので、悪しからず。
んなわけで、小数について調べて…みずに、とりあえずpythonで色々やってみる!

for i in range(0,10):
    print("i="+str(i+1))
    print("1/i="+str(1/(i+1))+"\n")

>>> %Run a.py
i=1
1/i=1.0

i=2
1/i=0.5

i=3
1/i=0.3333333333333333

i=4
1/i=0.25

i=5
1/i=0.2

i=6
1/i=0.16666666666666666

i=7
1/i=0.14285714285714285

i=8
1/i=0.125

i=9
1/i=0.1111111111111111

i=10
1/i=0.1

以上のようなことを1~10だけではなく30まで確認してみました。
有限小数はiが2,4,5,8,10,16,20,25。これはつまり、2と5の倍数のときだけということです。もしくは他の言い方をすれば、2と5以外の素数のある倍数ではない、ということです。
とりあえず、有限小数を除外する目的にも、有限小数を求めるプログラムを作成してみましょう。

for i in range(0,30):
    value = i+1
    while value>0:
        if value%2==0:
            value/=2
        elif value%5==0:
            value/=5
        else:
            break
    if value==1:
        print("i="+str(i+1))
        print("1/i="+str(1/(i+1)))

>>> %Run a.py
i=1
1/i=1.0
i=2
1/i=0.5
i=4
1/i=0.25
i=5
1/i=0.2
i=8
1/i=0.125
i=10
1/i=0.1
i=16
1/i=0.0625
i=20
1/i=0.05
i=25
1/i=0.04

とりま、作ってみました。適当に作ってたら出来ましたね。求めたいのは循環小数のわけなので、とりあえず、これの逆を表示してみましょう。

for i in range(0,30):
    value = i+1
    while value>0:
        if value%2==0:
            value/=2
        elif value%5==0:
            value/=5
        else:
            break
    if value!=1:
    #!変更部分   == を != に
        print("i="+str(i+1))
        print("1/i="+str(1/(i+1)))

>>> %Run a.py
i=3
1/i=0.3333333333333333
i=6
1/i=0.16666666666666666
i=7
1/i=0.14285714285714285
i=9
1/i=0.1111111111111111
i=11
1/i=0.09090909090909091
i=12
1/i=0.08333333333333333
i=13
1/i=0.07692307692307693
i=14
1/i=0.07142857142857142
i=15
1/i=0.06666666666666667
i=17
1/i=0.058823529411764705
i=18
1/i=0.05555555555555555
i=19
1/i=0.05263157894736842
i=21
1/i=0.047619047619047616
i=22
1/i=0.045454545454545456
i=23
1/i=0.043478260869565216
i=24
1/i=0.041666666666666664
i=26
1/i=0.038461538461538464
i=27
1/i=0.037037037037037035
i=28
1/i=0.03571428571428571
i=29
1/i=0.034482758620689655
i=30
1/i=0.03333333333333333

iが3の倍数の時は比較的に分かりやすく循環小数が展開されていますね。

3の時は0.3333333333333333。
6の時は0.16666666666666666。
9の時は,0.1111111111111111。
12の時は0.08333333333333333。
15の時は0.06666666666666667。
18の時は0.05555555555555555。

2の倍数が絡んできたときには、循環を始める地点が変更されていますね。2だけであれば一つ位が下がり、2の二乗であれば二つ位が下がっています。
ただ、18の3の二乗と2の二乗の時は循環は位を一つ下げるだけです。
次に21の時ですが、これが興味深い。

21の時は0.047619047619047616。
24の時は0.041666666666666664。

と、21のときだけ、循環に6個の幅が出来ています。その次の24は単にpythonの割り算の形式的にこのような微妙な最後になっているだけで6で循環しています。すなわち、3×7の21だけが、今までで、中々におかしな挙動をしているのです。
ならば、次は7の倍数について見ていきましょう。

7の時は0.14285714285714285
14の時は0.07142857142857142

7の時の循環の幅は6でこの幅は21のときと同等です。14の循環の始りは位が一つ下がっており、循環の幅は6です。

これよりわかることといえば、おそらくですが、それぞれの素数の循環の性質は、素数同士を掛けると性質を足し合わせたような結果を得られるということでしょうか?
素数には「それぞれの性質が存在するよ」として、これまでのプログラムには有限小数は2と5の倍数だけとしましたが、他の素数でも存在するかもしれません。
その可能性を考えて、プログラムを再始動

for i in range(0,300):
    value = i+1
    while value>0:
        if value%2==0:
            value/=2
        elif value%5==0:
            value/=5
        else:
            break
    if value!=1:
        print("i="+str(i+1))
        print("1/i="+str(1/(i+1)))

これで短めの小数点を出すものが存在しないのか、調べてみましたが、残念ながら見当たりませんでした。2と5という数字が特別なのか…だとすれば、なぜ特別なのか…それとも、私が単純に他の素数を見落としているのか。

素数にそれぞれ性質があるという可能性があるのであれば、2と5,3と7以外の素数も探してみるべきなんでしょうけれど、一日という時間は24という数字に縛られているもので、タイムアップです。

最後

数学の根底のようなお話は、きちんと数学を理解しながらではなければ、答えを求めるに至れないのでしょう。
問題解決の効率化するために、循環小数というものをどのように求めるか、ということについて調べようとしましたが、調べた内容すらも理解できないのでは、自分はもっと精進しなければいけないのでしょう。

しかし、この循環小数について、法則性を求める旅は、今回は時間がなかったために短かった上に中途半端で終わってしまいますが、中々に楽しいものでした。
今後に、またこのような問題を振り返ってやってみることにしましょう。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3