Skip to content

Commit 897e367

Browse files
committed
Solution for day 7.
1 parent fba2095 commit 897e367

File tree

5 files changed

+411
-0
lines changed

5 files changed

+411
-0
lines changed

day07/day07.adb

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
with Ada.Containers.Hashed_Sets,
2+
Ada.Containers.Ordered_Sets,
3+
Ada.Containers.Ordered_Maps,
4+
Ada.Containers.Vectors; use Ada.Containers;
5+
with Ada.Text_IO; use Ada.Text_IO;
6+
with Input; use Input;
7+
8+
procedure Day07 is
9+
10+
function Edge_Hash (Edge : Edge_Record) return Hash_Type
11+
is (Character'Pos (Edge.From) + Character'Pos (Edge.To));
12+
13+
function Edge_Equal (X, Y : Edge_Record) return Boolean
14+
is (X.From = Y.From and X.To = Y.To);
15+
16+
package Edge_Sets is new Hashed_Sets
17+
(Element_Type => Edge_Record,
18+
Hash => Edge_Hash,
19+
Equivalent_Elements => Edge_Equal);
20+
21+
package Node_Sets is new Ordered_Sets (Element_Type => Character);
22+
23+
package Node_Maps is new Ordered_Maps
24+
(Key_Type => Character,
25+
Element_Type => Natural);
26+
27+
package Node_Vectors is new Vectors
28+
(Index_Type => Natural,
29+
Element_Type => Character);
30+
31+
procedure Topological_Sort
32+
(Incoming_Edges : in Node_Maps.Map;
33+
No_Incoming_Edges : in Node_Sets.Set;
34+
All_Edges : in Edge_Sets.Set)
35+
is
36+
Incoming : Node_Maps.Map := Incoming_Edges;
37+
None_Incoming : Node_Sets.Set := No_Incoming_Edges;
38+
Graph_Edges : Edge_Sets.Set := All_Edges;
39+
Node : Character;
40+
Result : Node_Vectors.Vector;
41+
begin
42+
while not None_Incoming.Is_Empty loop
43+
Node := None_Incoming.First_Element;
44+
None_Incoming.Delete (Node);
45+
Result.Append (Node);
46+
for M in Incoming.Iterate loop
47+
if Graph_Edges.Contains ((Node, Node_Maps.Key (M))) then
48+
Graph_Edges.Delete ((Node, Node_Maps.Key (M)));
49+
if Node_Maps.Element (M) = 1 then
50+
None_Incoming.Insert (Node_Maps.Key (M));
51+
else
52+
Incoming.Replace_Element (M, Node_Maps.Element (M) - 1);
53+
end if;
54+
end if;
55+
end loop;
56+
end loop;
57+
Put ("Part 1 = ");
58+
for C of Result loop
59+
Put ("" & C);
60+
end loop;
61+
Put_Line ("");
62+
end Topological_Sort;
63+
64+
Incoming_Edges : Node_Maps.Map;
65+
No_Incoming_Edges : Node_Sets.Set;
66+
All_Edges : Edge_Sets.Set;
67+
68+
begin
69+
70+
-- Input Setup
71+
for Input of Inputs loop
72+
All_Edges.Insert (Input);
73+
if not Incoming_Edges.Contains (Input.To) then
74+
Incoming_Edges.Insert (Input.To, 1);
75+
else
76+
Incoming_Edges.Replace
77+
(Input.To, Incoming_Edges.Element (Input.To) + 1);
78+
end if;
79+
end loop;
80+
81+
for I in Character'Pos ('A') .. Character'Pos ('Z') loop
82+
if not Incoming_Edges.Contains (Character'Val (I)) then
83+
No_Incoming_Edges.Insert (Character'Val (I));
84+
end if;
85+
end loop;
86+
87+
-- Part 1 (TopoSort)
88+
Topological_Sort (Incoming_Edges, No_Incoming_Edges, All_Edges);
89+
90+
-- Part 2
91+
declare
92+
function Task_Time (Node : Character) return Natural
93+
is (60 + Character'Pos (Node) - Character'Pos ('A') + 1);
94+
95+
type Worker_Type is record
96+
Remaining_Time : Natural;
97+
Current_Task : Character;
98+
end record;
99+
100+
Workers : array (Positive range 1 .. 5) of Worker_Type :=
101+
(others => (0, '_'));
102+
103+
Total_Time : Natural := 0;
104+
Work_In_Progress : Boolean := True;
105+
Node : Character;
106+
begin
107+
while not No_Incoming_Edges.Is_Empty or Work_In_Progress loop
108+
for Worker of Workers loop
109+
if Worker.Remaining_Time = 0 and not No_Incoming_Edges.Is_Empty
110+
then
111+
Node := No_Incoming_Edges.First_Element;
112+
No_Incoming_Edges.Delete (Node);
113+
Worker.Remaining_Time := Task_Time (Node);
114+
Worker.Current_Task := Node;
115+
end if;
116+
end loop;
117+
118+
Work_In_Progress := False;
119+
120+
for Worker of Workers loop
121+
if Worker.Remaining_Time = 1 then
122+
for Dst in Incoming_Edges.Iterate loop
123+
if All_Edges.Contains ((Worker.Current_Task,
124+
Node_Maps.Key (Dst)))
125+
then
126+
All_Edges.Delete ((Worker.Current_Task,
127+
Node_Maps.Key (Dst)));
128+
if Node_Maps.Element (Dst) = 1 then
129+
No_Incoming_Edges.Insert (Node_Maps.Key (Dst));
130+
else
131+
Incoming_Edges.Replace_Element
132+
(Dst, Node_Maps.Element (Dst) - 1);
133+
end if;
134+
end if;
135+
end loop;
136+
end if;
137+
138+
if Worker.Remaining_Time > 0 then
139+
Worker.Remaining_Time := Worker.Remaining_Time - 1;
140+
end if;
141+
142+
if Worker.Remaining_Time > 0 then
143+
Work_In_Progress := True;
144+
end if;
145+
end loop;
146+
147+
Total_Time := Total_Time + 1;
148+
end loop;
149+
150+
Put_Line ("Part 2 =" & Natural'Image (Total_Time));
151+
end;
152+
end Day07;

day07/day07.gpr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
project day07 is
2+
for Object_Dir use "obj";
3+
for Main use ("day07.adb");
4+
for Exec_Dir use ".";
5+
package Compiler is
6+
for Switches ("Ada") use ("-g", "-O2");
7+
end Compiler;
8+
end day07;

day07/input.ads

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package Input is
2+
3+
type Edge_Record is record
4+
From : Character;
5+
To : Character;
6+
end record;
7+
8+
Inputs : constant array (Positive range <>) of Edge_Record :=
9+
(('Y', 'A'), ('O', 'C'), ('P', 'A'), ('D', 'N'), ('T', 'G'), ('L', 'M'),
10+
('X', 'V'), ('C', 'R'), ('G', 'E'), ('H', 'N'), ('Q', 'B'), ('S', 'R'),
11+
('M', 'F'), ('N', 'Z'), ('E', 'I'), ('A', 'R'), ('Z', 'F'), ('K', 'V'),
12+
('I', 'J'), ('R', 'W'), ('B', 'J'), ('W', 'V'), ('V', 'F'), ('U', 'F'),
13+
('F', 'J'), ('X', 'C'), ('T', 'Q'), ('B', 'F'), ('Y', 'L'), ('P', 'E'),
14+
('A', 'J'), ('S', 'I'), ('S', 'A'), ('K', 'R'), ('D', 'C'), ('R', 'U'),
15+
('K', 'U'), ('D', 'K'), ('S', 'M'), ('D', 'E'), ('A', 'K'), ('G', 'I'),
16+
('O', 'M'), ('U', 'J'), ('T', 'S'), ('C', 'M'), ('S', 'J'), ('N', 'V'),
17+
('P', 'N'), ('D', 'M'), ('A', 'B'), ('Z', 'R'), ('T', 'N'), ('K', 'J'),
18+
('N', 'A'), ('M', 'R'), ('E', 'A'), ('Y', 'O'), ('O', 'B'), ('O', 'A'),
19+
('I', 'V'), ('M', 'Z'), ('D', 'U'), ('O', 'S'), ('Z', 'W'), ('M', 'A'),
20+
('N', 'E'), ('M', 'U'), ('R', 'J'), ('W', 'F'), ('I', 'U'), ('E', 'U'),
21+
('Y', 'R'), ('Z', 'K'), ('C', 'F'), ('B', 'V'), ('G', 'B'), ('O', 'G'),
22+
('E', 'Z'), ('A', 'V'), ('Y', 'Q'), ('P', 'D'), ('X', 'G'), ('I', 'W'),
23+
('M', 'V'), ('T', 'M'), ('G', 'J'), ('T', 'I'), ('H', 'B'), ('C', 'E'),
24+
('Q', 'V'), ('H', 'U'), ('X', 'K'), ('D', 'T'), ('X', 'W'), ('P', 'Z'),
25+
('C', 'U'), ('Y', 'Z'), ('L', 'F'), ('C', 'J'), ('T', 'W'));
26+
27+
end Input;

day07/input.txt

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
Step Y must be finished before step A can begin.
2+
Step O must be finished before step C can begin.
3+
Step P must be finished before step A can begin.
4+
Step D must be finished before step N can begin.
5+
Step T must be finished before step G can begin.
6+
Step L must be finished before step M can begin.
7+
Step X must be finished before step V can begin.
8+
Step C must be finished before step R can begin.
9+
Step G must be finished before step E can begin.
10+
Step H must be finished before step N can begin.
11+
Step Q must be finished before step B can begin.
12+
Step S must be finished before step R can begin.
13+
Step M must be finished before step F can begin.
14+
Step N must be finished before step Z can begin.
15+
Step E must be finished before step I can begin.
16+
Step A must be finished before step R can begin.
17+
Step Z must be finished before step F can begin.
18+
Step K must be finished before step V can begin.
19+
Step I must be finished before step J can begin.
20+
Step R must be finished before step W can begin.
21+
Step B must be finished before step J can begin.
22+
Step W must be finished before step V can begin.
23+
Step V must be finished before step F can begin.
24+
Step U must be finished before step F can begin.
25+
Step F must be finished before step J can begin.
26+
Step X must be finished before step C can begin.
27+
Step T must be finished before step Q can begin.
28+
Step B must be finished before step F can begin.
29+
Step Y must be finished before step L can begin.
30+
Step P must be finished before step E can begin.
31+
Step A must be finished before step J can begin.
32+
Step S must be finished before step I can begin.
33+
Step S must be finished before step A can begin.
34+
Step K must be finished before step R can begin.
35+
Step D must be finished before step C can begin.
36+
Step R must be finished before step U can begin.
37+
Step K must be finished before step U can begin.
38+
Step D must be finished before step K can begin.
39+
Step S must be finished before step M can begin.
40+
Step D must be finished before step E can begin.
41+
Step A must be finished before step K can begin.
42+
Step G must be finished before step I can begin.
43+
Step O must be finished before step M can begin.
44+
Step U must be finished before step J can begin.
45+
Step T must be finished before step S can begin.
46+
Step C must be finished before step M can begin.
47+
Step S must be finished before step J can begin.
48+
Step N must be finished before step V can begin.
49+
Step P must be finished before step N can begin.
50+
Step D must be finished before step M can begin.
51+
Step A must be finished before step B can begin.
52+
Step Z must be finished before step R can begin.
53+
Step T must be finished before step N can begin.
54+
Step K must be finished before step J can begin.
55+
Step N must be finished before step A can begin.
56+
Step M must be finished before step R can begin.
57+
Step E must be finished before step A can begin.
58+
Step Y must be finished before step O can begin.
59+
Step O must be finished before step B can begin.
60+
Step O must be finished before step A can begin.
61+
Step I must be finished before step V can begin.
62+
Step M must be finished before step Z can begin.
63+
Step D must be finished before step U can begin.
64+
Step O must be finished before step S can begin.
65+
Step Z must be finished before step W can begin.
66+
Step M must be finished before step A can begin.
67+
Step N must be finished before step E can begin.
68+
Step M must be finished before step U can begin.
69+
Step R must be finished before step J can begin.
70+
Step W must be finished before step F can begin.
71+
Step I must be finished before step U can begin.
72+
Step E must be finished before step U can begin.
73+
Step Y must be finished before step R can begin.
74+
Step Z must be finished before step K can begin.
75+
Step C must be finished before step F can begin.
76+
Step B must be finished before step V can begin.
77+
Step G must be finished before step B can begin.
78+
Step O must be finished before step G can begin.
79+
Step E must be finished before step Z can begin.
80+
Step A must be finished before step V can begin.
81+
Step Y must be finished before step Q can begin.
82+
Step P must be finished before step D can begin.
83+
Step X must be finished before step G can begin.
84+
Step I must be finished before step W can begin.
85+
Step M must be finished before step V can begin.
86+
Step T must be finished before step M can begin.
87+
Step G must be finished before step J can begin.
88+
Step T must be finished before step I can begin.
89+
Step H must be finished before step B can begin.
90+
Step C must be finished before step E can begin.
91+
Step Q must be finished before step V can begin.
92+
Step H must be finished before step U can begin.
93+
Step X must be finished before step K can begin.
94+
Step D must be finished before step T can begin.
95+
Step X must be finished before step W can begin.
96+
Step P must be finished before step Z can begin.
97+
Step C must be finished before step U can begin.
98+
Step Y must be finished before step Z can begin.
99+
Step L must be finished before step F can begin.
100+
Step C must be finished before step J can begin.
101+
Step T must be finished before step W can begin.

0 commit comments

Comments
 (0)