Add AoC 2025 project structure and first solutions
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using AdvenOfCode.Contracts;
|
||||
|
||||
namespace AoC_2025;
|
||||
|
||||
public class Day01 : IPuzzleSolver<int>
|
||||
{
|
||||
private string[] ParsePuzzleInput(string path)
|
||||
{
|
||||
var puzzleInput = File.ReadAllLines(path)
|
||||
.Where(l => !string.IsNullOrWhiteSpace(l))
|
||||
.ToArray();
|
||||
return puzzleInput;
|
||||
}
|
||||
|
||||
public int SolvePart1(string pathToPuzzleInput)
|
||||
{
|
||||
var rotationInstructions = ParsePuzzleInput(pathToPuzzleInput);
|
||||
var dialPosition = 50;
|
||||
var timesZeroWasHit = 0;
|
||||
foreach (var rotationAmount in rotationInstructions.Select(ParseRotationAmount))
|
||||
{
|
||||
dialPosition = (dialPosition + rotationAmount) % 100;
|
||||
if (dialPosition == 0)
|
||||
timesZeroWasHit++;
|
||||
}
|
||||
return timesZeroWasHit;
|
||||
}
|
||||
|
||||
public int SolvePart2(string pathToPuzzleInput)
|
||||
{
|
||||
var rotationInstructions = ParsePuzzleInput(pathToPuzzleInput);
|
||||
var dialPosition = 50;
|
||||
var timesZeroWasHit = 0;
|
||||
foreach (var rotationAmount in rotationInstructions.Select(ParseRotationAmount))
|
||||
{
|
||||
var actualRotationAmount = 0;
|
||||
if (rotationAmount < 0)
|
||||
{
|
||||
(var fullTurns, actualRotationAmount) = DivMod(rotationAmount, -100);
|
||||
timesZeroWasHit += fullTurns;
|
||||
if (dialPosition != 0 && dialPosition + actualRotationAmount <= 0)
|
||||
timesZeroWasHit++;
|
||||
}
|
||||
else
|
||||
{
|
||||
(var fullTurns, actualRotationAmount) = DivMod(rotationAmount, 100);
|
||||
timesZeroWasHit += fullTurns;
|
||||
if (dialPosition + actualRotationAmount >= 100)
|
||||
timesZeroWasHit++;
|
||||
}
|
||||
|
||||
dialPosition = Mod(dialPosition + actualRotationAmount, 100);
|
||||
}
|
||||
return timesZeroWasHit;
|
||||
}
|
||||
|
||||
private (int div, int mod) DivMod(int number, int divisor)
|
||||
{
|
||||
return (number / divisor, Mod(number, divisor));
|
||||
}
|
||||
|
||||
private int Mod(int number, int divident)
|
||||
{
|
||||
var mod = number % divident;
|
||||
if (number < 0 && divident > 0)
|
||||
{
|
||||
mod = divident + mod;
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
private static bool HasPassedZero(bool hasOverflow, int dialPosition)
|
||||
{
|
||||
return dialPosition != 0 && hasOverflow;
|
||||
}
|
||||
|
||||
private static (int nextDialPosition, bool passedZero) GetNextDialPosition(int rotationAmount, int dialPosition)
|
||||
{
|
||||
var actualRotation = rotationAmount % 100;
|
||||
var nextDialPosition = dialPosition + actualRotation;
|
||||
var hasOverflow = nextDialPosition is > 99 or < 1;
|
||||
nextDialPosition %= 100;
|
||||
if (nextDialPosition < 0)
|
||||
{
|
||||
nextDialPosition = 100 + nextDialPosition;
|
||||
}
|
||||
return (nextDialPosition, hasOverflow);
|
||||
}
|
||||
|
||||
private static int ParseRotationAmount(string puzzleInput)
|
||||
{
|
||||
var direction = puzzleInput[..1];
|
||||
var rotationAmount = int.Parse(puzzleInput[1..]);
|
||||
if (direction == "L")
|
||||
{
|
||||
rotationAmount *= -1;
|
||||
}
|
||||
|
||||
return rotationAmount;
|
||||
}
|
||||
|
||||
private static int CountFullRotations(int rotationAmount)
|
||||
{
|
||||
var fullRotations = Math.Abs(rotationAmount / 100);
|
||||
|
||||
return fullRotations;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user