Share
Embed
Transcript
38 slides
-
2を作ろう 2はどうしましょうか。 two = [one]としてもいいし、two = [zero, zero]としてもいいです。 ただ、今回はこうします。 zero
= [] one = [zero] # = [[]] two = [zero, one] # = [[], [[]]] -
自然数を作ろう 実は two + [two] = [zero, one] + [two]
= [zero, one, two] = threeとなります。 以降はそうやって自然数を作りましょう。 zero = [] one = [zero] # = [[]] two = [zero, one] # = [[], [[]]] three = two + [two] # = [zero, one, two] ※0は大学数学においては自然数に含む -
1を足す関数を作ろう さっき言ったようにこうやって x + 1を計算できます。 # 1を足す関数 後者関数 successor function
def suc(x: Natural) -> Natural: """ x + 1 を計算する""" return x + [x] ※Natural型 = list型 -
1を引く関数を作ろう 1を引く関数はリストの一番最後を消せばいいのでこうすればいいです。 int型の「-1」を使ってますが、pop()を使えばいいので省略記法として使います。 def pre(x: Natural) -> Natural: """ x
- 1 を計算する x=0ならエラー""" return x[:-1] 今できること • 1を足す -
大小関係を作ろう なんと大小関係が1行で判定できる。最高! def is_bigger(x: Natural, y: Natural) -> bool: """
x < y かを判定する""" return x in y 今できること • 1を足す • 1を引く -
足し算を作ろう 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を引く • 大小関係 -
掛け算を作ろう 足し算を繰り返して再帰で書きます。 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を引く • 大小関係 • 足し算 -
引き算を作りたい 引き算を「1を引く」の再帰で作ると答えが負のときに困るので、 やりたくないです。 どうにかして x - y = z を今できることで表現できないでしょうか…?
今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 x - y = z -
引き算を作りたい 引き算を「1を引く」の再帰で作ると答えが負のときに困るので、 やりたくないです。 どうにかして x - y = z を今できることで表現できないでしょうか…?
今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 x - y = z x = z + y ←!!!!!! -
整数を作ろう 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型は異なる -
整数を作ろう 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型は異なる -
整数の「=」を作ろう 整数が等しいかを判定するために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は許容 -
整数の足し算を作ろう (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を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 -
整数の単項マイナスを作ろう a-b = b-aなのでそのまま def neg_i(x: Integer) -> Integer: """
-x を計算する""" return (x[1], x[0]) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算 -
整数の引き算を作ろう 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を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 -
整数の掛け算を作ろう テキトーにやれば面倒だが出来る。 (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を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 -
整数と引き算が作れた 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転
◦ 引き算 ◦ 掛け算 もう自然数は整数の下位互換なので要りません やったー!! -
割り算を作りたい x / y = z ↑ これを足し算引き算掛け算だけで表現できないか 今できること •
整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 -
割り算を作りたい x / y = z x = z *
y 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 ←!!!!!! -
有理数を作ろう なんと!有理数は2つの整数から作ることが出来ます!知ってた。 有理数 x / y を(x, y) と表します! Rational
= tuple[Integer, Integer] 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 -
有理数の「=」を作ろう 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]) ) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 -
有理数の掛け算を作ろう 有理数はみなさん御存知の通り掛け算が一番楽なので作ります。 (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])) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 -
有理数の割り算を作ろう 有理数はみなさん御存知の通り割り算が二番楽(?)なので作ります。 (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])) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 -
有理数の単項マイナスを作ろう 分数をマイナスにするのは分子にマイナスつけるだけです。 def neg_r(x: Rational) -> Rational: """ -x を計算する"""
return (neg_i(x[0]), x[1]) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算 -
有理数の足し算を作ろう なんかごちゃごちゃ計算したらできます。 読まなくていいです。 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) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算 ◦ 正負逆転 -
有理数の引き算を作ろう なんかごちゃごちゃ計算したらできます2。 読まなくていいです2。 …と思いきや足し算と単項マイナスがあるので楽です。 今できること • 整数 ◦ 「=」 ◦
足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算 ◦ 正負逆転 ◦ 足し算 def minus_r(x: Rational, y: Rational) -> Rational: """ x-y を計算する""" return plus_r(x, neg_r(y)) -
有理数と割り算が作れた もう整数は有理数の下位互換なので要りません やったー!! 今できること • 有理数 ◦ 「=」 ◦ 掛け算
◦ 割り算 ◦ 正負逆転 ◦ 足し算 ◦ 引き算