-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_02.adb
136 lines (119 loc) · 4.29 KB
/
day_02.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
with Ada.Text_IO; use Ada.Text_IO;
with AdventLib; use AdventLib;
procedure Day_02 is
type Move is (Rock, Paper, Scissors, Invalid);
type Intended_Outcome is (Win, Lose, Draw, Invalid);
function Parse_Outcome (Input : Character) return Intended_Outcome is
begin
return
(case Input is when 'X' => Lose, when 'Y' => Draw, when 'Z' => Win,
when others => Invalid);
end Parse_Outcome;
function Parse_Move (Input : Character) return Move is
begin
return
(case Input is when 'A' | 'X' => Rock, when 'B' | 'Y' => Paper,
when 'C' | 'Z' => Scissors, when others => Invalid);
end Parse_Move;
function Score_Round (My_Move : Move; Their_Move : Move) return Natural is
Win_Lose_Points : Integer := 0;
Move_Points : Integer := 0;
begin
if (My_Move = Rock and then Their_Move = Scissors)
or else (My_Move = Paper and then Their_Move = Rock)
or else (My_Move = Scissors and then Their_Move = Paper)
then
-- I win
Win_Lose_Points := 6;
elsif (Their_Move = Rock and then My_Move = Scissors)
or else (Their_Move = Paper and then My_Move = Rock)
or else (Their_Move = Scissors and then My_Move = Paper)
then
-- I lose
Win_Lose_Points := 0;
else
-- We draw
Win_Lose_Points := 3;
end if;
Move_Points :=
(case My_Move is when Rock => 1, when Paper => 2, when Scissors => 3,
when others => 0);
return Win_Lose_Points + Move_Points;
end Score_Round;
procedure Part_1 (Input_Name : String) is
F : File_Type;
Total_Score : Integer := 0;
begin
Open_Data_File (F, 2, Input_Name);
while not End_Of_File (F) loop
declare
Line : String (1 .. 5) := " ";
Last : Natural := 0;
Their_Move : Move := Invalid;
My_Move : Move := Invalid;
begin
Get_Line (F, Line, Last);
if Last < 3 then
Put_Line
("Invalid input. Line is " & Integer'Image (Last) &
" characters long");
return;
end if;
Their_Move := Parse_Move (Line (1));
My_Move := Parse_Move (Line (3));
Total_Score := Total_Score + Score_Round (My_Move, Their_Move);
end;
end loop;
Put_Line
("Part 1 " & Input_Name & " result: " & Integer'Image (Total_Score));
Close (F);
end Part_1;
procedure Part_2 (Input_Name : String) is
F : File_Type;
Total_Score : Integer := 0;
begin
Open_Data_File (F, 2, Input_Name);
while not End_Of_File (F) loop
declare
Line : String (1 .. 5) := " ";
Last : Natural := 0;
Their_Move : Move := Invalid;
My_Move : Move := Invalid;
Outcome : Intended_Outcome := Invalid;
begin
Get_Line (F, Line, Last);
if Last < 3 then
Put_Line
("Invalid input. Line is " & Integer'Image (Last) &
" characters long");
return;
end if;
Their_Move := Parse_Move (Line (1));
Outcome := Parse_Outcome (Line (3));
-- Determine my move based on intended outcome
if Outcome = Win then
My_Move :=
(case Their_Move is when Rock => Paper,
when Paper => Scissors, when Scissors => Rock,
when others => Invalid);
elsif Outcome = Lose then
My_Move :=
(case Their_Move is when Rock => Scissors, when Paper => Rock,
when Scissors => Paper, when others => Invalid);
else
My_Move := Their_Move;
end if;
Total_Score := Total_Score + Score_Round (My_Move, Their_Move);
end;
end loop;
Put_Line
("Part 2 " & Input_Name & " result: " & Integer'Image (Total_Score));
Close (F);
end Part_2;
begin
Put_Line ("Advent of Code Day 02");
Part_1 ("test");
Part_1 ("input");
Part_2 ("test");
Part_2 ("input");
end Day_02;