Skip to content

Commit

Permalink
2023 Day 8
Browse files Browse the repository at this point in the history
  • Loading branch information
premun committed Dec 10, 2023
1 parent 05e1e6b commit 229cbfd
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 2 deletions.
49 changes: 48 additions & 1 deletion src/2023/08/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
using AdventOfCode.Common;
using System.Text.RegularExpressions;
using AdventOfCode.Common;

var lines = Resources.GetInputFileLines();
var instructionCounter = new CircularCounter(lines.First());
var instructionRegex = new Regex("[A-Z0-9]{3}");
var rawInstructions = lines
.Skip(1)
.Select(line => instructionRegex.Matches(line))
.ToDictionary(m => m[0].Value, m => (m[1].Value, m[2].Value));
var instructions = rawInstructions.Keys
.ToDictionary(name => name, name => new Instruction(name));

foreach (var instruction in instructions)
{
var i = rawInstructions[instruction.Key];
instruction.Value.Left = instructions.TryGetValue(i.Item1, out var v1) ? v1 : null!;
instruction.Value.Right = instructions.TryGetValue(i.Item2, out var v2) ? v2 : null!;
}

var part2 = instructions
.Where(p => p.Key.EndsWith('A'))
.Select(p => p.Value)
.Select(i => GetInstructionCount(i.Name))
.FindLowestCommonDenominator();

Console.WriteLine($"Part 1: {GetInstructionCount("AAA")}");
Console.WriteLine($"Part 2: {part2}");

int GetInstructionCount(string startInstruction)
{
var current = instructions[startInstruction];
var counter = instructionCounter!.GetEnumerator();
while (current.Name[2] != 'Z')
{
current = counter.Current == 'L' ? current.Left : current.Right;
counter.MoveNext();
}

var value = instructionCounter.Counter;
instructionCounter.Counter = 0;

return value;
}

file record Instruction(string Name)
{
public Instruction Left { get; set; } = null!;
public Instruction Right { get; set; } = null!;
}
39 changes: 39 additions & 0 deletions src/Common/CircularCounter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Collections;

namespace AdventOfCode.Common;

public class CircularCounter(string instructions) : IEnumerable<char>
{
public int Counter { get; set; }

public IEnumerator<char> GetEnumerator() => new InstructionEnumerator(instructions, this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

private class InstructionEnumerator(string instructions, CircularCounter parent) : IEnumerator<char>
{
private readonly string _instructions = instructions;
private readonly CircularCounter _parent = parent;
private int _index = 0;

public char Current => _instructions[_index];

object IEnumerator.Current => _instructions[_index];

public void Dispose() { }

public bool MoveNext()
{
_parent.Counter++;
_index++;
_index %= _instructions.Length;
return true;
}

public void Reset()
{
_parent.Counter = 0;
_index = 0;
}
}
}

30 changes: 29 additions & 1 deletion src/Common/Resources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,36 @@ public static int Multiply(this IEnumerable<int> values)
=> values.Aggregate(1, (acc, v) => acc * v);

public static long MultiplyAsLong(this IEnumerable<int> values)
=> values.Aggregate(1L, (acc, v) => acc * v);
=> values.Aggregate(1, (acc, v) => acc * v);

public static long Multiply(this IEnumerable<long> values)
=> values.Aggregate(1L, (acc, v) => acc * v);

public static long FindLowestCommonDenominator(this IEnumerable<int> numbers)
{
long lcm = numbers.First();
foreach (int number in numbers.Skip(1))
{
lcm = GetLeastCommonMultiple(lcm, number);
}

return lcm;
}

public static long GetGreatestCommonDivisor(long a, long b)
{
while (b != 0)
{
long temp = b;
b = a % b;
a = temp;
}

return a;
}

public static long GetLeastCommonMultiple(long a, long b)
{
return a * b / GetGreatestCommonDivisor(a, b);
}
}

0 comments on commit 229cbfd

Please sign in to comment.