Skip to content

Commit

Permalink
format(p12)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmpknu committed Oct 22, 2024
1 parent 482baf1 commit 2892501
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 27 deletions.
2 changes: 1 addition & 1 deletion p12/.ocamlformat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
profile = janestreet
version = 0.26.2
margin = 80
5 changes: 4 additions & 1 deletion p12/lib/iterative.ml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ let count_divisors n =
if n mod i = 0 then if i = n / i then incr count else count := !count + 2
done;
!count
;;

let find_triangle_with_divisors limit =
let found = ref false in
let result = ref 0 in
let n = ref 1 in
while not !found do
let tri_num = triangle_number !n in
if count_divisors tri_num > limit then (
if count_divisors tri_num > limit
then (
result := tri_num;
found := true);
incr n
done;
!result
;;

let result = find_triangle_with_divisors 500
15 changes: 9 additions & 6 deletions p12/lib/map.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ let triangle_number n = n * (n + 1) / 2

let triangular_numbers limit =
let generate_range n = List.init n (fun i -> i + 1) in
List.map (fun n -> (n * (n + 1)) / 2) (generate_range limit)
List.map (fun n -> n * (n + 1) / 2) (generate_range limit)
;;

let count_factors_tail n =
let rec aux i count =
if i * i > n then count
else if n mod i = 0 then aux (i + 1) (count + if i * i = n then 1 else 2)
if i * i > n
then count
else if n mod i = 0
then aux (i + 1) (count + if i * i = n then 1 else 2)
else aux (i + 1) count
in
if n <= 0 then 0 else aux 1 0
;;

let find_first_triangular_with_factors limit factor_count_threshold =
let triangulars = triangular_numbers limit in
List.find_opt
(fun x -> count_factors_tail x > factor_count_threshold)
triangulars
List.find_opt (fun x -> count_factors_tail x > factor_count_threshold) triangulars
;;

let result = find_first_triangular_with_factors 15000 500
13 changes: 10 additions & 3 deletions p12/lib/module.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ let triangle_number n = n * (n + 1) / 2

let count_factors_tail n =
let rec aux i count =
if i * i > n then count
else if n mod i = 0 then aux (i + 1) (count + if i * i = n then 1 else 2)
if i * i > n
then count
else if n mod i = 0
then aux (i + 1) (count + if i * i = n then 1 else 2)
else aux (i + 1) count
in
if n <= 0 then 0 else aux 1 0
;;

let triangular_numbers = List.init 15000 (fun n -> triangle_number (n + 1))

let result =
List.filter (fun x -> count_factors_tail x > 500) triangular_numbers
|> List.fold_left
(fun acc x -> match acc with Some _ -> acc | None -> Some x)
(fun acc x ->
match acc with
| Some _ -> acc
| None -> Some x)
None
;;
12 changes: 7 additions & 5 deletions p12/lib/rec.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ let triangle_number n = n * (n + 1) / 2

let count_factors n =
let rec aux i =
if i * i > n then 0
else if n mod i = 0 then
if i * i = n then 1 + aux (i + 1) else 2 + aux (i + 1)
if i * i > n
then 0
else if n mod i = 0
then if i * i = n then 1 + aux (i + 1) else 2 + aux (i + 1)
else aux (i + 1)
in
if n <= 0 then 0 else aux 1
;;

let rec find_triangular_with_divisors target n =
let tri_num = triangle_number n in
let factors_count = count_factors tri_num in
if factors_count > target then tri_num
else find_triangular_with_divisors target (n + 1)
if factors_count > target then tri_num else find_triangular_with_divisors target (n + 1)
;;

let result = find_triangular_with_divisors 500 1
8 changes: 6 additions & 2 deletions p12/lib/tailrec.ml
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
let count_factors_tail n =
let rec aux i count =
if i * i > n then count
else if n mod i = 0 then aux (i + 1) (count + if i * i = n then 1 else 2)
if i * i > n
then count
else if n mod i = 0
then aux (i + 1) (count + if i * i = n then 1 else 2)
else aux (i + 1) count
in
if n <= 0 then 0 else aux 1 0
;;

let find_triangular_with_divisors_tail target =
let rec aux n tri_num =
let factors_count = count_factors_tail tri_num in
if factors_count > target then tri_num else aux (n + 1) (tri_num + n + 1)
in
aux 1 1
;;

let result = find_triangular_with_divisors_tail 500
26 changes: 17 additions & 9 deletions p12/test/test_p12.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,62 @@ let test_tailrec_count_factors _ =
assert_equal 6 (Tailrec.count_factors_tail 28);
assert_equal 9 (Tailrec.count_factors_tail 36);
assert_equal 0 (Tailrec.count_factors_tail 0)
;;

let test_tailrec_find_triangular _ =
assert_equal 28 (Tailrec.find_triangular_with_divisors_tail 5);
assert_equal 76576500 (Tailrec.find_triangular_with_divisors_tail 500)
;;

(* Rec tests *)
let test_rec_count_factors _ =
assert_equal 6 (Rec.count_factors 28);
assert_equal 9 (Rec.count_factors 36);
assert_equal 0 (Rec.count_factors 0)
;;

let test_rec_find_triangular _ =
assert_equal 28 (Rec.find_triangular_with_divisors 5 1);
assert_equal 76576500 (Rec.find_triangular_with_divisors 500 1)
;;

(* Iterative tests *)
let test_iterative_count_divisors _ =
assert_equal 6 (Iterative.count_divisors 28);
assert_equal 9 (Iterative.count_divisors 36);
assert_equal 0 (Iterative.count_divisors 0)
;;

let test_iterative_find_triangle _ =
assert_equal 28 (Iterative.find_triangle_with_divisors 5);
assert_equal 76576500 (Iterative.find_triangle_with_divisors 500)
;;

(* Module tests *)
let test_module_result _ =
match Module.result with
| Some x -> assert_equal 76576500 x
| None -> assert_failure "Expected a result, got None"
;;

(* Map tests *)
let test_map_find_first _ =
match Map.result with
| Some x -> assert_equal 76576500 x
| None -> assert_failure "Expected a result, got None"
;;

let suite =
"Project Euler Problem 12 Tests"
>::: [
"Tailrec - count_factors" >:: test_tailrec_count_factors;
"Tailrec - find_triangular" >:: test_tailrec_find_triangular;
"Rec - count_factors" >:: test_rec_count_factors;
"Rec - find_triangular" >:: test_rec_find_triangular;
"Iterative - count_factors" >:: test_iterative_count_divisors;
"Iterative - find_triangular" >:: test_iterative_find_triangle;
"Module - result" >:: test_module_result;
"Map - result" >:: test_map_find_first;
>::: [ "Tailrec - count_factors" >:: test_tailrec_count_factors
; "Tailrec - find_triangular" >:: test_tailrec_find_triangular
; "Rec - count_factors" >:: test_rec_count_factors
; "Rec - find_triangular" >:: test_rec_find_triangular
; "Iterative - count_factors" >:: test_iterative_count_divisors
; "Iterative - find_triangular" >:: test_iterative_find_triangle
; "Module - result" >:: test_module_result
; "Map - result" >:: test_map_find_first
]
;;

let _ = run_test_tt_main suite

0 comments on commit 2892501

Please sign in to comment.