#import "Basic";
#import "File";
#import "String";
#import "Hash_Table";
solve_day8 :: (test: bool) {
contents := read_entire_file("inputs/day8.txt");
lines := split(contents, "\n");
instructions: [..]u8;
node_to_id_table: Table(string, u32);
node_list: [..]Walk_Node;
node_links: [..]Node_Link;
for char_it: 0..lines[0].count - 1{
c := lines[0][char_it];
if c == {
case #char "R";
array_add(*instructions, 1);
case #char "L";
array_add(*instructions, 0);
case;
print("Unknown instruction: %\n", c);
}
}
for line: array_view(lines, 1, lines.count) {
if line.count == 0 continue;
node_name := slice(line, 0, 3);
left_node_name := slice(line, 7, 3);
right_node_name := slice(line, 12, 3);
table_add(*node_to_id_table, node_name, xx node_list.count);
array_add(*node_links, .{
name = node_name,
left = left_node_name,
right = right_node_name,
});
array_add(*node_list, .{
name = node_name,
left = 0,
right = 0,
});
}
for 0..node_links.count - 1 {
node_list[it].left = table_find_pointer(*node_to_id_table, node_links[it].left).*;
node_list[it].right = table_find_pointer(*node_to_id_table, node_links[it].right).*;
}
part1 := 0;
start_node_i,_ := table_find(*node_to_id_table, "AAA");
end_node_i,_ := table_find(*node_to_id_table, "ZZZ");
current_node := node_list[start_node_i];
while outer:= part1 < 1_000_000 {
for instruction: instructions {
part1 += 1;
if instruction == 0 {
if current_node.left == end_node_i break outer;
current_node = node_list[current_node.left];
} else {
if current_node.right == end_node_i break outer;
current_node = node_list[current_node.right];
}
}
}
part2 := 0;
nodes_to_walk: [..]u64;
for node_list {
if it.name[2] == #char "A" {
node := it;
steps: u64 = 0;
while outer:= steps < 1_000_000 {
for instruction: instructions {
steps += 1;
if instruction == 0 {
if node_list[node.left].name[2] == #char "Z" {
break outer;
}
node = node_list[node.left];
} else {
if node_list[node.right].name[2] == #char "Z" {
break outer;
}
node = node_list[node.right];
}
}
}
array_add(*nodes_to_walk, steps);
}
}
part2 = 1;
for nodes_to_walk {
part2 = lcm(part2, xx it);
}
print("Part 1: %\n", part1);
print("Part 2: %\n", part2);
}
Walk_Node :: struct {
name: string;
left: u64;
right: u64;
}
Node_Link :: struct {
name: string;
left: string;
right: string;
}