Upgrade to Pro — share decks privately, control downloads, hide ads and more …

pythonで0を作ってみんなも神になろう

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for 國友大地 國友大地
September 07, 2023

 pythonで0を作ってみんなも神になろう

pythonで0、自然数、整数、有理数を作り、四則演算を作ります。

Avatar for 國友大地

國友大地

September 07, 2023
Tweet

Other Decks in Programming

Transcript

  1. 自然数を作ろう 実は two + [two] = [zero, one] + [two]

    = [zero, one, two] = threeとなります。 以降はそうやって自然数を作りましょう。 zero = [] one = [zero] # = [[]] two = [zero, one] # = [[], [[]]] three = two + [two] # = [zero, one, two] ※0は大学数学においては自然数に含む
  2. 1を足す関数を作ろう さっき言ったようにこうやって x + 1を計算できます。 # 1を足す関数 後者関数 successor function

    def suc(x: Natural) -> Natural: """ x + 1 を計算する""" return x + [x] ※Natural型 = list型
  3. 大小関係を作ろう なんと大小関係が1行で判定できる。最高! def is_bigger(x: Natural, y: Natural) -> bool: """

    x < y かを判定する""" return x in y 今できること • 1を足す • 1を引く
  4. 足し算を作ろう 1を足すことと1を引くことしかできず、for文も禁止なので再帰で書きます。 x + 0 = x、x+y = (x+1)+(y-1)。それはそう。 def

    plus(x: Natural, y: Natural) -> Natural: if y == zero: return x # x + 0 = x else: return plus(suc(x), pre(y)) # x+y = (x+1)+(y-1) 今できること • 1を足す • 1を引く • 大小関係
  5. 掛け算を作ろう 足し算を繰り返して再帰で書きます。 x * 0 = 0、x * y =

    x * (y-1) + x。それはそう。 def mul(x: Natural, y: Natural) -> Natural: if y == zero: return zero # x * 0 = 0 else: # x * y = x * (y-1) + x return plus(mul(x, pre(y)), x) 今できること • 1を足す • 1を引く • 大小関係 • 足し算
  6. 整数を作ろう a - b = c - d の時、 a

    + d = c + b です。 整数を自然数の2つ組で表現しましょう! 自然数a,bを使って整数 a-bを(a, b)と表現します! (1,4) = -3 , (0,0) = 0, (20, 21) = -1, (0,3) = -3 です! Integer = tuple[Natural, Natural] 今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 ※int型とInteger型は異なる
  7. 整数を作ろう a - b = c - d の時、 a

    + d = c + b です。 整数を自然数の2つ組で表現しましょう! 自然数a,bを使って整数 a-bを(a, b)と表現します! (1,4) = -3 , (0,0) = 0, (20, 21) = -1, (0,3) = -3 です! (1,4) = (0,3) になってるけど大丈夫? Integer = tuple[Natural, Natural] 今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 ※int型とInteger型は異なる
  8. 整数の「=」を作ろう 整数が等しいかを判定するためにInteger型の「=」を作る。 a-b = c-d なら a+d = b+c なので簡単

    x[0]やx[1]はNatural型なので足し算できる! def eq_i(x: Integer, y: Integer) -> bool: """x[0] - x[1] == y[0] - y[1] かを判定する""" return plus(x[0], y[1]) == plus(y[0], x[1]) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 ※Integerを型ではなくクラスで表現すれば添字 [0][1]は使わずに済むので、ここでの int型0,1は許容
  9. 整数の足し算を作ろう (a-b) + (c-d) = (a+c) - (b+d)なので自然数の足し算だけで作れる! def plus_i(x:

    Integer, y: Integer) -> Integer: """ x+y を計算する""" # a-b + c-d = (a+c) - (b+d) return (plus(x[0], y[0]), plus(x[1], y[1])) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」
  10. 整数の単項マイナスを作ろう a-b = b-aなのでそのまま def neg_i(x: Integer) -> Integer: """

    -x を計算する""" return (x[1], x[0]) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算
  11. 整数の引き算を作ろう x - y = x + (-y)より作れる。 def minus_i(x:

    Integer, y: Integer) -> Integer: """ x-y を計算する""" return plus_i(x, neg_i(y)) # x-y = x + (-y) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転
  12. 整数の掛け算を作ろう テキトーにやれば面倒だが出来る。 (a-b)*(c-d)=(a*c-b*c) - (a*c - b*d) def mul_i(x: Integer,

    y: Integer) -> Integer: x_mul_y0: Integer = (mul(x[0],y[0]), mul(x[1],y[0])) x_mul_y1: Integer = (mul(x[0],y[1]), mul(x[1],y[1])) return minus_i(x_mul_y0, x_mul_y1) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算
  13. 整数と引き算が作れた 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転

    ◦ 引き算 ◦ 掛け算 もう自然数は整数の下位互換なので要りません やったー!!
  14. 割り算を作りたい x / y = z x = z *

    y 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 ←!!!!!!
  15. 有理数を作ろう なんと!有理数は2つの整数から作ることが出来ます!知ってた。 有理数 x / y を(x, y) と表します! Rational

    = tuple[Integer, Integer] 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算
  16. 有理数の「=」を作ろう a / b = c / d ならば a

    * d = c * bなのでこうなります。 def eq_r(x: Rational, y: Rational) -> bool: return eq_i( mul_i(x[0], y[1]), mul_i(x[1], x[0]) ) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算
  17. 有理数の掛け算を作ろう 有理数はみなさん御存知の通り掛け算が一番楽なので作ります。 (a / b) * (c / d) =

    (a*c) / (b*d) def mul_r(x: Rational, y: Rational) -> Rational: """ x*y を計算する""" return (mul_i(x[0], y[0]), mul_i(x[1], y[1])) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」
  18. 有理数の割り算を作ろう 有理数はみなさん御存知の通り割り算が二番楽(?)なので作ります。 (a / b) / (c / d) =

    (a*d) / (b*c) def div_r(x: Rational, y: Rational) -> Rational: """ x/y を計算する""" return (mul_i(x[0], y[1]), mul_i(x[1], y[0])) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算
  19. 有理数の単項マイナスを作ろう 分数をマイナスにするのは分子にマイナスつけるだけです。 def neg_r(x: Rational) -> Rational: """ -x を計算する"""

    return (neg_i(x[0]), x[1]) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算
  20. 有理数の足し算を作ろう なんかごちゃごちゃ計算したらできます。 読まなくていいです。 def plus_r(x: Rational, y: Rational) -> Rational:

    numerator = plus_i(mul_i(x[0], y[1]), mul_i(x[1], y[0])) denominator = mul_i(x[1], y[1]) return (numerator, denominator) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算 ◦ 正負逆転
  21. 有理数の引き算を作ろう なんかごちゃごちゃ計算したらできます2。 読まなくていいです2。 …と思いきや足し算と単項マイナスがあるので楽です。 今できること • 整数 ◦ 「=」 ◦

    足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算 ◦ 正負逆転 ◦ 足し算 def minus_r(x: Rational, y: Rational) -> Rational: """ x-y を計算する""" return plus_r(x, neg_r(y))