-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecember_22a.adb
139 lines (122 loc) · 4.64 KB
/
december_22a.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
137
138
139
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure December_22a is
Maximum_Coordinate : constant Integer := 1000;
subtype Coordinates is integer range -Maximum_Coordinate ..
Maximum_Coordinate;
Infected_Ch : constant Character := '#';
Clean_Ch : constant Character := '.';
type Infections is (Clean, Weakened, Infected, Flagged);
type Grids is array (Coordinates, Coordinates) of Infections;
Grid : Grids := (others => (others => Clean));
Type Directions is (Up, Down, Left, Right);
type Carrier_States is record
X : Coordinates := 0;
Y : Coordinates := 0;
Direction : Directions := Up;
Infection_Count : Natural := 0;
end record;
Carrier_State : Carrier_States;
procedure Read_Grid (Grid : out Grids) is
Input_File : File_Type;
Text : Unbounded_String;
Offset : Integer;
begin -- Read_Grid
Open (Input_File, In_File, "20171222.txt");
Text := To_Unbounded_String (Get_Line (Input_File));
Offset := Length (Text) / 2;
Reset (Input_File);
for Row in reverse Coordinates range -Offset .. Offset loop
Text := To_Unbounded_String (Get_Line (Input_File));
for Column in Coordinates range -Offset .. Offset loop
if Element (Text, Column + Offset + 1) = Infected_Ch then
Grid (Column, Row) := Infected;
else
Grid (Column, Row) := Clean;
end if; -- Element (Text, Column + Offset + 1) = Infected_Ch
end loop; -- Column
end loop; -- Row
Close (Input_File);
end Read_Grid;
procedure Next_State (Carrier_State : in out Carrier_States;
Grid : in out Grids) is
begin -- Next_State
case Grid (Carrier_State.X, Carrier_State.Y) is
when Infected =>
-- Infected turn Right
case Carrier_State.Direction is
when Up =>
Carrier_State.Direction := Right;
when Right =>
Carrier_State.Direction := Down;
when Down =>
Carrier_State.Direction := Left;
when Left =>
Carrier_State.Direction := Up;
end case; -- Carrier_State.Direction
Grid (Carrier_State.X, Carrier_State.Y) := Flagged;
when Clean =>
-- Clean turn Left
case Carrier_State.Direction is
when Up =>
Carrier_State.Direction := Left;
when Right =>
Carrier_State.Direction := Up;
when Down =>
Carrier_State.Direction := Right;
when Left =>
Carrier_State.Direction := Down;
end case; -- Carrier_State.Direction
Grid (Carrier_State.X, Carrier_State.Y) := Weakened;
when Weakened =>
-- Weakened no change in direction
Grid (Carrier_State.X, Carrier_State.Y) := Infected;
Carrier_State.Infection_Count := Carrier_State.Infection_Count + 1;
when Flagged =>
-- flagged reverse
case Carrier_State.Direction is
when Up =>
Carrier_State.Direction := Down;
when Right =>
Carrier_State.Direction := Left;
when Down =>
Carrier_State.Direction := Up;
when Left =>
Carrier_State.Direction := Right;
end case; -- Carrier_State.Direction
Grid (Carrier_State.X, Carrier_State.Y) := Clean;
end case; -- Grid (Carrier_State.X; Carrier_State.Y)
-- update position
case Carrier_State.Direction is
when Up =>
Carrier_State.Y := Carrier_State.Y + 1;
when Right =>
Carrier_State.X := Carrier_State.X + 1;
when Down =>
Carrier_State.Y := Carrier_State.Y - 1;
when Left =>
Carrier_State.X := Carrier_State.X - 1;
end case; -- Carrier_State.Direction
end Next_State;
procedure Put_Grid (Grid : in Grids; Limit : in Integer) is
begin -- Put Grid
for Y in reverse Coordinates range -Limit .. Limit loop
for X in Coordinates range -Limit .. Limit loop
If Grid (X, Y) = Infected then
Put (Infected_Ch);
else
Put (Clean_Ch);
end if; -- Grid (X, Y)
end loop; -- X
New_Line;
end loop; -- Y
end Put_Grid;
begin -- December_22a
Read_Grid (Grid);
Put_Grid (Grid, 12);
for I in Positive range 1 .. 10000000 loop
Next_State (Carrier_State, Grid);
end loop;
Put_Line ("Infected Count:" &
Natural'Image (Carrier_State.Infection_Count));
end December_22a;