練習問題 5.7
与えられた自然数 r に対して、xx + yy = r であるような (x, y) (ただし x >= 0, y >= 0)の組すべてをリストとして列挙する関数 squares r を定義しなさい。
(検算用資料: r = 48612265 の時、32個の解があるそうです)。
組の重複を調べる関数をつくった。
リスト l は、(x, y)の組のリストである。
その中に、(x, y) = (y, x) であるリストは重複しているとして省きたい。
そのため、組(a, b) について、リストの中に重複しているものがあるかどうかを調べる関数をつくった。
let rec find (a, b) l =
match l with
[] -> false
| (x, y) :: rest ->
if ((b, a) = (x, y))
then true
else find (a, b) rest;;
問題の解答コードがこれ。
let squares r =
let rec keisan (x, y) ac =
let res = x * x + y * y in
if res <= r
then
if res = r
then
if find (x, y) ac
then keisan (x+1, y) ac
else keisan (x+1, y) ((x, y) :: ac)
else keisan (x+1, y) ac
else
if y*y < r
then keisan (1, y+1) ac
else
ac
in
keisan (1, 1) [];;