Skip to content

Commit b0b854d

Browse files
committed
big numbers fix
1 parent 098a581 commit b0b854d

File tree

4 files changed

+63
-34
lines changed

4 files changed

+63
-34
lines changed

task20/lib/iterative.ml

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
1+
let scale digits factor =
2+
let acc = ref [] in
3+
let carry = ref 0 in
4+
List.iter (fun hd ->
5+
let prod = hd * factor + !carry in
6+
acc := (prod mod 10) :: !acc;
7+
carry := prod / 10
8+
) digits;
9+
while !carry > 0 do
10+
acc := (!carry mod 10) :: !acc;
11+
carry := !carry / 10
12+
done;
13+
List.rev !acc
14+
115
let factorial n =
2-
let res = ref 1 in
16+
let result = ref [1] in
317
for i = 2 to n do
4-
res := !res * i
18+
result := scale !result i
519
done;
6-
!res;;
20+
!result
721

8-
let sum_of_digits n =
9-
let res = ref 1 in
10-
let temp_n = ref n in
11-
while !temp_n > 0 do
12-
res := !res * (!temp_n mod 10);
13-
temp_n := !temp_n / 10
14-
done;
15-
!res;;
22+
let sum_of_digits digits =
23+
let sum = ref 0 in
24+
List.iter (fun d -> sum := !sum + d) digits;
25+
!sum
1626

1727
let solve n = sum_of_digits (factorial n)
1828

task20/lib/recursion.ml

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
let rec factorial n = if n = 0 then 1 else n * factorial (n - 1)
1+
let rec scale digits factor carry =
2+
match digits with
3+
| [] -> if carry > 0 then (carry mod 10) :: scale [] factor (carry / 10) else []
4+
| hd :: tl ->
5+
let prod = hd * factor + carry in
6+
(prod mod 10) :: scale tl factor (prod / 10)
27

3-
let rec sum_of_digits n =
4-
if n = 0 then 0 else (n mod 10) + sum_of_digits (n / 10)
8+
let rec multiply acc i n =
9+
if i > n then acc
10+
else multiply (scale acc i 0) (i + 1) n
511

6-
let solve n = sum_of_digits (factorial n)
12+
let rec sum_of_digits = function
13+
| [] -> 0
14+
| hd :: tl -> hd + sum_of_digits tl
15+
16+
let solve n =
17+
sum_of_digits (multiply [1] 2 n)
718

819
(* Пример использования *)
920
let result = solve 100;;

task20/lib/tail_recursion.ml

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
let factorial n =
2-
let rec aux acc n =
3-
if n = 0 then acc else aux (acc * n) (n - 1)
4-
in
5-
aux 1 n
1+
let rec scale digits factor carry acc =
2+
match digits with
3+
| [] -> if carry > 0 then scale digits factor (carry / 10) ((carry mod 10) :: acc) else acc
4+
| hd :: tl ->
5+
let prod = hd * factor + carry in
6+
scale tl factor (prod / 10) ((prod mod 10) :: acc)
67

7-
let sum_of_digits n =
8-
let rec aux acc n =
9-
if n = 0 then acc else aux (acc + (n mod 10)) (n / 10)
10-
in
11-
aux 0 n
8+
let scale_tail digits factor =
9+
List.rev (scale digits factor 0 [])
10+
11+
let rec multiply acc i n =
12+
if i > n then acc
13+
else multiply (scale_tail acc i) (i + 1) n
14+
15+
let rec sum_of_digits digits acc =
16+
match digits with
17+
| [] -> acc
18+
| hd :: tl -> sum_of_digits tl (hd + acc)
1219

1320
let solve n =
14-
let fact = factorial n in
15-
sum_of_digits fact
21+
sum_of_digits (multiply [1] 2 n) 0
1622

1723
(* Пример использования *)
1824
let result = solve 100;;

task20/test/test_task20.ml

+9-7
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,34 @@ open Task20_lib
33

44
(* Tailrec tests *)
55
let test_tailrec _ =
6-
assert_equal 3 (Tail_recursion.solve 5)
6+
assert_equal 3 (Tail_recursion.solve 5);;
7+
assert_equal 648 (Tail_recursion.solve 100);;
78
;;
89

910
(* Rec tests *)
1011
let test_rec _ =
11-
assert_equal 3 (Recursion.solve 5)
12+
assert_equal 3 (Recursion.solve 5);;
13+
assert_equal 648 (Recursion.solve 100);;
1214
;;
1315

1416
(* Module tests *)
1517
let test_moduled _ =
16-
assert_equal 3 (Moduled.solve 5)
17-
;;
18+
assert_equal 3 (Moduled.solve 5);;
1819

1920
(* Iterative tests*)
2021
let test_iterative _ =
21-
assert_equal 3 (Iterative.solve 5)
22+
assert_equal 3 (Iterative.solve 5);;
23+
assert_equal 648 (Iterative.solve 100);;
2224
;;
2325

2426
(* Map tests *)
2527
let test_mapped _ =
26-
assert_equal 3 (Mapped.solve 5)
28+
assert_equal 3 (Mapped.solve 5);;
2729
;;
2830

2931
(* Lazy collections tests *)
3032
let test_lazy _ =
31-
assert_equal 3 (Lazy.solve 5)
33+
assert_equal 3 (Lazy.solve 5);;
3234
;;
3335

3436
let suite =

0 commit comments

Comments
 (0)