forked from rej696/altran-rednoseday-2021-challenge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
code.adb
118 lines (95 loc) · 3.15 KB
/
code.adb
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
-- Altran Red Nose Day 2021 Challenge
-- A SPARK2014 solution by Anthony Williams
--
-- Reads puzzle input from stdin.
-- e.g. $ ./code < puzzle.txt
with Ada.Text_IO;
procedure Code is
type Move_T is (U, D, L, R, Invalid);
type Char_To_Move_T is Array (Character) of Move_T;
Char_To_Move : constant Char_To_Move_T := Char_To_Move_T'
('U' => U,
'D' => D,
'L' => L,
'R' => R,
others => Invalid);
type Code_T is new Long_Long_Integer range 0 .. Long_Long_Integer'Last;
subtype Grid_Row is Code_T range 1 .. 3;
subtype Grid_Col is Code_T range 0 .. 2;
type Keypad_T is record
Row : Grid_Row;
Col : Grid_Col;
end record;
Move : Move_T;
Move_Char : Character;
Position_P1 : Keypad_T := (2, 1);
Position_P2 : Keypad_T := (2, 1);
Result_Part1 : Code_T := 0;
Result_Part2 : Code_T := 0;
procedure Add_Digit
(Keypad : in Keypad_T;
Result : in out Code_T)
is
-- Convert keypad position to a value.
This_Number : Code_T := Keypad.Row + (Keypad.Col * 3);
begin
if Code_T'Last / 10 - This_Number > Result then
Result := Result * 10;
Result := Result + This_Number;
else
Ada.Text_IO.Put_Line ("Overflow!");
end if;
end Add_Digit;
begin
loop
Ada.Text_IO.Get (Move_Char);
Move := Char_To_Move (Move_Char);
case Move is
when L =>
if Position_P1.Row > Grid_Row'First then
Position_P1.Row := Position_P1.Row - 1;
end if;
if Position_P2.Row = Grid_Row'First then
Position_P2.Row := Position_P2.Row + 1;
else
Position_P2.Row := Position_P2.Row - 1;
end if;
when R =>
if Position_P1.Row < Grid_Row'Last then
Position_P1.Row := Position_P1.Row + 1;
end if;
if Position_P2.Row = Grid_Row'Last then
Position_P2.Row := Position_P2.Row - 1;
else
Position_P2.Row := Position_P2.Row + 1;
end if;
when U =>
if Position_P1.Col > Grid_Col'First then
Position_P1.Col := Position_P1.Col - 1;
end if;
if Position_P2.Col = Grid_Col'First then
Position_P2.Col := Position_P2.Col + 1;
else
Position_P2.Col := Position_P2.Col - 1;
end if;
when D =>
if Position_P1.Col < Grid_Col'Last then
Position_P1.Col := Position_P1.Col + 1;
end if;
if Position_P2.Col = Grid_Col'Last then
Position_P2.Col := Position_P2.Col - 1;
else
Position_P2.Col := Position_P2.Col + 1;
end if;
when Invalid =>
Ada.Text_IO.Put_Line ("Invalid input!");
end case;
if Ada.Text_IO.End_Of_Line then
Add_Digit (Position_P1, Result_Part1);
Add_Digit (Position_P2, Result_Part2);
end if;
exit when Ada.Text_IO.End_Of_File;
end loop;
Ada.Text_IO.Put_Line ("Part 1:" & Result_Part1'Img);
Ada.Text_IO.Put_Line ("Part 2:" & Result_Part2'Img);
end Code;