aboutsummaryrefslogtreecommitdiff
path: root/0016/main.adb
blob: 43a9c0d2571d9ba22eeae402bbeaabaff4d0286c (plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
with ada.text_io; use ada.text_io;
with ada.integer_text_io; use ada.integer_text_io;
with ada.containers.vectors;

procedure main is
    package int_vector is new ada.containers.vectors (
        index_type => natural,
        element_type => integer
    );
    use int_vector;
    
    function add(a: vector; b: vector) return vector is
        ret: vector;
        len: integer;
        na, nb: integer;
        carry: integer := 0;
    begin
        len := integer(length(a));
        if integer(length(b)) > len then
            len := integer(length(b));
        end if;
        for i in 0..len-1 loop
            na := 0;
            nb := 0;
            if i < integer(length(a)) then
                na := element(a, i);
            end if;
            if i < integer(length(b)) then
                nb := element(b, i);
            end if;
            append(ret, (na + nb + carry) mod 10);
            carry := (na + nb + carry) / 10;
        end loop;
        if carry > 0 then
            ret.append(1);
        end if;
        return ret;
    end add;

    function mul(a: vector; b: integer) return vector is
        ret: vector;
        len: integer;
        carry: integer := 0;
    begin
        len := integer(length(a));
        if b = 10 then
            append(ret, 0);
            for i in 0..len-1 loop
                append(ret, a.element(i));
            end loop;
            return ret;
        end if;
        
        if b = 0 then
            append(ret, 0);
            return ret;
        end if;
        
        for i in 0..len-1 loop
            append(ret, (a.element(i) * b + carry) mod 10);
            carry := (a.element(i) * b + carry) / 10;
        end loop;
        if carry > 0 then
            ret.append(carry);
        end if;
        return ret;
    end mul;

    procedure printnum(a: vector);

    function mul(a: vector; b: vector) return vector is
        ret: vector;
        t1: vector;
        t2: vector;
        len: integer;
    begin
        len := integer(length(b));
        for i in 0..len-1 loop
            clear(t1);
            clear(t2);
            for j in 1..i loop
                append(t1, 0);
            end loop;
            t2 := mul(a, b.element(i));
            for j in 0..integer(length(t2))-1 loop
                append(t1, t2.element(j));
            end loop;
            ret := add(ret, t1);
        end loop;
        return ret;
    end mul;

    procedure printnum(a: vector) is
    begin
        for i in reverse 0..integer(length(a))-1 loop
            put(a.element(i), 0);
        end loop;
        new_line;
    end printnum;

    function pow2(n: integer) return vector is
        t: vector;
    begin
        if n = 0 then
            append(t, 1);
            return t;
        end if;
        if n mod 2 = 1 then
            return mul(pow2(n-1), 2);
        else
            t := pow2(n / 2);
            return mul(t, t);
        end if;
    end pow2;

v: vector;
res: integer := 0;
begin
    v := pow2(1000);
    for i in 0..integer(length(v)) - 1 loop
        res := res + v.element(i);
    end loop;
    put(res);
end main;