[b]このワークシートは[url=https://www.geogebra.org/m/twxxx3yq]Math by Code[/url]の一部です。[br][/b][br][br]前回はzipを使うと、yがxの単純な代数的な数式でなくても関数が作れることがわかったね。[br]今回はカリー化を使ってみよう。[br][br]数学の関数、特に数論で使う関数は2以上の変数の関数が多いけど、[br]多変数関数はコード化がしにくい。[br]そこで、高階関数をサポートしている言語で可能なカリー化を使ってみよう。[br][br]たとえば、xとyの2変数関数zがあるとしたら、[br]zを出すにはxとyを同時に入れないといけない。[br]でも、関数利用の場面では、xを一時的に定数にして、yだけ動かしたり、yを固定してxだけ動かして調べるとか、いろんな使い方がある。[br]たとえば、xとyの合計を出すadd(x,y)という関数があるとしよう。[br]これを細切りして、xを入れて、yをあとで入れてadd(x,y)を出すと再定義したcurryAddを作る。[br]すると、add_ten = curryAdd(10)とすると、x=10を固定した1変数関数add_ten(y)として[br]扱うことができるね。[br][br][size=150][color=#0000ff][b]#[OUT]julia[br]#======================[br][/b][/color][color=#0000ff][b]function add(x, y)[br] return x + y[br]end[br][br]curryAdd = x -> y -> add(x, y)[br][br]add_ten = curryAdd(10)[br]println(add_ten(5)) [br][/b][/color][color=#0000ff][b]#======================[br][OUT][br][/b][/color][/size]15[br][b][br][/b]
一番単純な[color=#0000ff][b]合同1次方程式[/b][/color]はどんな式だろうか?[br][br][b][color=#9900ff][size=200]ax≡b (mod p)[br][/size][/color][/b][br]とかけるね。[br]これを関数とみると、z=f(a,k,p)という3変数関数の値がbと等しくなるのを探すことになる。[br]問題によって、a,k,p,bの値が変わると、探し方も変わるね。[br][br]さあて、落ち着いて考えてみよう。[br][br][b][color=#0000ff][size=150]xの値はmod pの剰余だから、 [br]bが0でないなら、 xは1からp-1を動かして調べることになる。[/size][/color][/b][br][br]ということは、z=f(a,k,p)=bを探すのではなくz=f(a,p)=bを探せばよいことがわかる。[br]探し方はfの中でxを動かした結果としてzをリストで返し、そこにbを探せばよい。[br]では、juliaで作ってみよう[br]<juliaで合同1次方程式を解く>[br][size=150][color=#0000ff]#=====================================[br][/color][b]# ax≡b(mod p)の解がx[br][/b][color=#0000ff]function multmod(a,p)[br] k=1:p[br] [/color][color=#9900ff] return [a*x % p for x in k][br][/color][color=#0000ff]end[br][/color][br][size=200]crrymmod = p -> a -> multmod(a, p)[br][/size][color=#0000ff][br]# (例1)4x≡3(mod 19)」の解は? x ≡15[br]p=19;a=4;b=3[br][/color][br][size=200][b]mm = crrymmod(p)[br]x=findfirst(isequal(b),mm(a))[br][/b][/size][b]#=====================================[/b][/size][OUT][br]15[br][br]#===========================================[br][b][color=#0000ff]#(例2)「4x≡16(mod 28)」の解は? x ≡ 4 (mod 7)[br]p=29;a=4;b=16[br][/color][/b]mm = crrymmod(p)[br]x=findfirst(isequal(b),mm(a))[br]#===========================================[br][OUT][br]7[br]#===========================================[br]#(例3)「18x≡8(mod 14)」の解は?[color=#0000ff][b] x≡2 ,9 (mod 7)[/b][/color][br]p=14;a=18;b=8[br]mm = crrymmod(p)[br][b][color=#0000ff]x=findall(isequal(b),mm(a))[br][/color][/b]#===========================================[br][OUT][br]2-element Vector{Int64}:[br] 2[br] 9[br]
2次合同方程式もカレー化で、取り組もう。[br][br][color=#0000ff][b][u][size=150]質問:どのようにして、合同2次方程式が実装できますか。たとえばjuliaで作ってみよう。[br][/size][/u][/b][/color][br][color=#0000ff]#============================================[br]#x^2+ax≡b(mod p)の解がx[br]function squaremod(a,p)[br] k=1:p[br] return [(x^2+a*x) % p for x in k][br]end[br]crrymmod = p -> a ->squaremod(a,p)[br]#(例1)x^2+2x≡0(mod 7)の解は? x ≡ 0, 5 (mod 7)[br][br]p=7;a=2;b=0[br]mm = crrymmod(p)[br]x=findall(isequal(b),mm(a))[br][/color][color=#0000ff]#=============================================[br][/color][OUT][br]2-element Vector{Int64}:[br] 5[br] 7[br]mod 7なのにx=7がでるのは変だけど、1スタートの7エンドでxを動かしているので仕方ないね。[br]わかっていれば問題ない。[br][br]#============================================[br]#(例2)x^2+2x-1≡0(mod 7)の解は?x≡ 2, 3 (mod 7)[br]#左辺-7して因数分解すると、x2+2x-8=(x-2)(x+4)≡0(mod 7)から、x≡2, -4≡2,3(mod 7)[br]p=7;a=2;b=1[br]mm = crrymmod(p)[br]x=findall(isequal(b),mm(a))[br]#============================================[br][OUT][br]2-element Vector{Int64}:[br] 2[br] 3[br]#============================================[br]#(例3)x^2≡3(mod 10)の解は?なし[br]p=10;a=0;b=3[br]mm = crrymmod(p)[br]x=findall(isequal(b),mm(a))[br]#============================================[br][OUT][br]Int64[][br]これは解なしということだね。[br]