AdventOfCode2023/day_8/solution.d

82 lines
2.2 KiB
D
Raw Permalink Normal View History

2023-12-08 13:06:44 +00:00
import std.stdio;
import std.algorithm;
import std.string;
import std.array;
import std.math;
struct Node {
string name, left, right;
}
struct Puzzle {
string instructions;
Node[string] nodes;
}
Puzzle parsePuzzle(string filename) {
Puzzle p;
string[] lines = File(filename).byLineCopy.array;
p.instructions = lines[0].strip;
foreach (string line; lines[2..$]) {
string[] nameAndBranches = line.split("=");
string name = nameAndBranches[0].strip;
string[] branches = nameAndBranches[1].strip[1..$-1].split(",").map!strip.array;
p.nodes[name] = Node(name, branches[0], branches[1]);
}
return p;
}
void part1() {
Puzzle p = parsePuzzle("input.txt");
Node currentNode = p.nodes["AAA"];
size_t instructionIdx = 0;
ulong steps = 0;
while (currentNode.name != "ZZZ") {
char instruction = p.instructions[instructionIdx++];
if (instructionIdx >= p.instructions.length) instructionIdx = 0;
if (instruction == 'L') {
currentNode = p.nodes[currentNode.left];
} else if (instruction == 'R') {
currentNode = p.nodes[currentNode.right];
}
steps++;
}
writeln(steps);
}
void part2() {
ulong gcd(ulong a, ulong b) {
if (a < b) swap(a, b);
while (b != 0) {
a = a % b;
swap(a, b);
}
return a;
}
ulong lcm(ulong a, ulong b) {
return a / gcd(a, b) * b;
}
Puzzle p = parsePuzzle("input.txt");
Node[] startNodes = p.nodes.values.filter!(n => n.name[$-1] == 'A').array;
ulong lcmSteps = 1;
foreach (size_t i, Node startNode; startNodes) {
Node currentNode = startNode;
ulong cycleLength = 0;
size_t instructionIdx = 0;
while (currentNode.name[$-1] != 'Z') {
char instruction = p.instructions[instructionIdx++];
if (instructionIdx >= p.instructions.length) instructionIdx = 0;
currentNode = instruction == 'L' ? p.nodes[currentNode.left] : p.nodes[currentNode.right];
cycleLength++;
}
lcmSteps = lcm(lcmSteps, cycleLength);
}
writeln(lcmSteps);
}
void main() {
part1();
part2();
}