プログラミングの基礎 / 浅井健一
Ocamlで遊ぶ
fizzbuzz
(* int list -> string list *)
(* fizzbuzz: *)
(* 3n:fizz, 5n:buzz, 3n && 5n:fizzbuzz; else n;*)
let fizzbuzz lst =
let mod3 x = x mod 3 = 0 in
let mod5 x = x mod 5 = 0 in
let mod15 x = mod3 && mod5 in
List.fold_right (fun x y ->
if mod15 x then "fb" :: y
else if mod3 x then "f" :: y
else if mod5 x then "b" :: y
else "etc" :: y
) lst []
let lst1 = ["1"; "2"; "f"; "4"; "b"; "f"; "7"; "8"; "f"; "b"; "11"; "f"; "13"; "14"; "fb"]
let test1 = fizzbuzz [] = []
let test2 = fizzbuzz lst1 = ["etc"; "etc"; "f"; "etc"; "b"; "f"; "etc"; "etc"; "f"; "b"; "etc"; "f"; "etc"; "etc"; "fb"]
平方和 sum_of_squares
(* squared: 整数 m を与えられたら m を二乗して返す *)
(* int -> int *)
let squared m = m * m
(* squared_list: 整数の入ったリストを与えられたら、全要素を二乗して返す *)
(* int list -> int list *)
let squared_list lst = List.fold_right (fun x y -> squared x :: y) lst []
let test1 = squared_list [1; 2; 3; 4; 5] = [1; 4; 9; 16; 25]
(* average: 整数の入ったリストを与えられたら、その平均を返す *)
(* int list -> int *)
let average lst = (List.fold_right (+) lst 0) /List.length lst
let test1 = average [1; 2; 3; 4; 5] = 3
let test2 = average [55; 68; 41; 34; 23] = 44
(* sum: 整数の入ったリストを与えられたら、その合計を返す *)
(* int list -> int *)
let sum lst = List.fold_right (+) lst 0
let test1 = sum [1; 2; 3; 4; 5] = 55
(* sum_of_squares: 整数の入ったリストを与えられたら、その平方和を返す *)
(* int list -> int *)
(* 1: xiと平均の差の二乗の合計 *)
let sum_of_squares lst =
let avg = average lst in
sum (List.fold_right (fun x y -> squared (x - avg) :: y) lst [])
let test1 = sum_of_squares [55; 68; 41; 34; 23] = 1247
let test2 = sum_of_squares [1; 2; 3; 4; 5] = 10
(* 2: 二乗の合計値 - 合計値の二乗 / n *)
(* ΣXi^2 - (ΣXi)^2/n *)
let sum_of_squares2 lst =
sum (squared_list lst) - squared (sum lst) / List.length lst
let test1 = sum_of_squares [55; 68; 41; 34; 23] = sum_of_squares2 [55; 68; 41; 34; 23]
let test2 = sum_of_squares [1; 2; 3; 4; 5] = sum_of_squares2 [1; 2; 3; 4; 5]