-
Notifications
You must be signed in to change notification settings - Fork 0
/
digits.erl
56 lines (47 loc) · 1.77 KB
/
digits.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-module(digits).
-compile(export_all).
add(NumberA, NumberB) ->
add(lists:reverse(NumberA), lists:reverse(NumberB), [], 0).
add([], [], Result, 0) ->
Result;
add([], [], Result, 1) ->
[1|Result];
add([], [H|T], Result, Remainder) ->
add([], T, [(H+Remainder) rem 10|Result], (H+Remainder) div 10);
add([H|T], [], Result, Remainder) ->
add(T, [], [(H+Remainder) rem 10|Result], (H+Remainder) div 10);
add([HA|TA], [HB|TB], Result, Remainder) ->
add(TA, TB, [(HA+HB+Remainder) rem 10|Result], (HA+HB+Remainder) div 10).
%% OK : digits:mul([2,1], [1,4]).
%% KO : digits:mul([2,1], [1,5]).
mul(NumberA, NumberB) when length(NumberA) > length(NumberB) ->
mul(NumberB, NumberA);
mul(NumberA, NumberB) ->
mul(lists:reverse(NumberB), lists:reverse(NumberA), [], 0).
mul(_, [], Result, _) ->
Result;
mul(NumberA, [H|T], Result, Indice) ->
mul(NumberA, T, add(Result, mul_by_digit(lists:reverse(NumberA), H)++padd_zero(Indice)), Indice+1).
mul_by_digit(Number, Digit) ->
mul_by_digit(lists:reverse(Number), Digit, [], 0, 0).
mul_by_digit([], _, Result, _, Remainder) ->
integer_to_digits(Remainder)++Result;
mul_by_digit([H|T], Digit, Result, Indice, Remainder) ->
New = Remainder+H*Digit,
mul_by_digit(T, Digit, [New rem 10|Result], Indice+1, New div 10).
padd_zero(0) ->
[];
padd_zero(N) ->
[0|padd_zero(N-1)].
integer_to_digits(Number) ->
integer_to_digits(Number, []).
integer_to_digits(0, List) ->
List;
integer_to_digits(Number, List) ->
integer_to_digits(Number div 10, [Number rem 10] ++ List).
digits_to_integer(Digits) ->
digits_to_integer(Digits, 0).
digits_to_integer([], Integer) ->
round(Integer);
digits_to_integer([H|T], Integer) ->
digits_to_integer(T, Integer + H * math:pow(10, length(T))).