Compare commits
2 Commits
b03404fe6a
...
f0ac76df15
| Author | SHA1 | Date |
|---|---|---|
|
|
f0ac76df15 | |
|
|
6e3d180550 |
|
|
@ -0,0 +1,47 @@
|
||||||
|
using AdvenOfCode.Contracts;
|
||||||
|
|
||||||
|
namespace AoC_2025.Tests;
|
||||||
|
|
||||||
|
public class Day07Test
|
||||||
|
{
|
||||||
|
private readonly IPuzzleSolver<long> _sut;
|
||||||
|
private static readonly string rootPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
||||||
|
private readonly string TestInputPath = @$"{rootPath}\AoC-PuzzleInputs\2025\Test\day07.txt";
|
||||||
|
private readonly string ProdInputPath = @$"{rootPath}\AoC-PuzzleInputs\2025\Prod\day07.txt";
|
||||||
|
|
||||||
|
public Day07Test()
|
||||||
|
{
|
||||||
|
_sut = new Day07();
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Part01_Test_equals_21()
|
||||||
|
{
|
||||||
|
var actual = _sut.SolvePart1(TestInputPath);
|
||||||
|
|
||||||
|
Assert.Equal(21, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Part01_Prod_equals_1658()
|
||||||
|
{
|
||||||
|
var actual = _sut.SolvePart1(ProdInputPath);
|
||||||
|
|
||||||
|
Assert.Equal(1658, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Part02_Test_equals_40()
|
||||||
|
{
|
||||||
|
var actual = _sut.SolvePart2(TestInputPath);
|
||||||
|
|
||||||
|
Assert.Equal(40, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Part02_Prod_equals_53916299384254()
|
||||||
|
{
|
||||||
|
var actual = _sut.SolvePart2(ProdInputPath);
|
||||||
|
|
||||||
|
Assert.Equal(53916299384254, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,14 +38,14 @@ public class Day06 : IPuzzleSolver<long>
|
||||||
return results.Sum();
|
return results.Sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long[] CalculateResults((Func<long, long, long> operation, long opBaseValue)[] operands, long[][] numbers)
|
private static long[] CalculateResults(Func<long, long, long>[] operands, long[][] numbers)
|
||||||
{
|
{
|
||||||
return operands
|
return operands
|
||||||
.Select((op, i) => numbers[i].Aggregate(op.opBaseValue, (acc, next) => op.operation(acc, next)))
|
.Select((operand, i) => numbers[i].Aggregate((acc, next) => operand(acc, next)))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Func<long, long, long> operation, long opBaseValue)[] ParseOperands(string[] operands)
|
private Func<long, long, long>[] ParseOperands(string[] operands)
|
||||||
{
|
{
|
||||||
var parsedOperands = operands
|
var parsedOperands = operands
|
||||||
.Select(ParseOperand)
|
.Select(ParseOperand)
|
||||||
|
|
@ -55,30 +55,45 @@ public class Day06 : IPuzzleSolver<long>
|
||||||
|
|
||||||
private static long[][] ParseNumbersByWhitespace(string[] numbers)
|
private static long[][] ParseNumbersByWhitespace(string[] numbers)
|
||||||
{
|
{
|
||||||
var parsedNumbers = numbers
|
var splittedNUmbers = numbers
|
||||||
.Select(line => line.Split(' ', StringSplitOptions.RemoveEmptyEntries))
|
.Select(line => ParseLineByWhitespace(line))
|
||||||
.SelectMany(line => line.Select(long.Parse).Index())
|
.ToArray();
|
||||||
.GroupBy(indexedNumber => indexedNumber.Index)
|
var parsedNumbers = splittedNUmbers
|
||||||
.Select(group => group.Select(indexedNumber => indexedNumber.Item).ToArray())
|
.Aggregate(Enumerable.Repeat(Array.Empty<long>(), splittedNUmbers[0].Length),
|
||||||
|
(acc, line) => CombineLists(acc, line))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
return parsedNumbers;
|
return parsedNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long[] ParseLineByWhitespace(string line)
|
||||||
|
{
|
||||||
|
return line.Split(' ', StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(str => long.Parse(str))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<long[]> CombineLists(IEnumerable<IEnumerable<long>> acc, IEnumerable<long> line)
|
||||||
|
{
|
||||||
|
return acc.Zip(line, (left, right) => (long[])[..left, right]);
|
||||||
|
}
|
||||||
|
|
||||||
private static long[][] ParseNumbersByColumn(string[] numberLines)
|
private static long[][] ParseNumbersByColumn(string[] numberLines)
|
||||||
{
|
{
|
||||||
var (numberColumns, lastColumn) = Enumerable.Range(1, numberLines[0].Length)
|
var combinedNumbers = numberLines
|
||||||
.Select(i => numberLines.Aggregate("", (acc, numberLine) => acc + numberLine[^i]))
|
.Aggregate(Enumerable.Repeat(string.Empty, numberLines[0].Length),
|
||||||
.Aggregate((columns: (List<long[]>)[[]], column: (long[])[]),
|
(acc, line) => acc.Zip(line, (left, right) => left + right));
|
||||||
|
var (numberColumns, lastColumn) = combinedNumbers
|
||||||
|
.Aggregate((columns: new List<long[]>(), column: Array.Empty<long>()),
|
||||||
(acc, number) => string.IsNullOrWhiteSpace(number)
|
(acc, number) => string.IsNullOrWhiteSpace(number)
|
||||||
? ([..acc.columns, acc.column], [])
|
? ([..acc.columns, acc.column], [])
|
||||||
: (acc.columns, [..acc.column, long.Parse(number)]));
|
: (acc.columns, [..acc.column, long.Parse(number)]));
|
||||||
return [lastColumn, ..Enumerable.Reverse(numberColumns)];
|
return [..numberColumns, lastColumn];
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Func<long, long, long> operation, long opBaseValue) ParseOperand(string operand) => operand switch
|
private Func<long, long, long> ParseOperand(string operand) => operand switch
|
||||||
{
|
{
|
||||||
"+" => ((long a, long b) => a + b, 0),
|
"+" => (long a, long b) => a + b,
|
||||||
"*" => ((long a, long b) => a * b, 1),
|
"*" => (long a, long b) => a * b,
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(operand))
|
_ => throw new ArgumentOutOfRangeException(nameof(operand))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using AdvenOfCode.Contracts;
|
||||||
|
using Coordinate = (int x, int y);
|
||||||
|
|
||||||
|
namespace AoC_2025;
|
||||||
|
|
||||||
|
public class Day07 : IPuzzleSolver<long>
|
||||||
|
{
|
||||||
|
private string[] ParsePuzzleInput(string path)
|
||||||
|
{
|
||||||
|
var puzzleInput = File.ReadAllLines(path)
|
||||||
|
.Where(line => !string.IsNullOrWhiteSpace(line))
|
||||||
|
.ToArray();
|
||||||
|
return puzzleInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long SolvePart1(string pathToPuzzleInput)
|
||||||
|
{
|
||||||
|
var grid = ParsePuzzleInput(pathToPuzzleInput);
|
||||||
|
var start = GetStart(grid);
|
||||||
|
var count = TraverseGridAndCountSplitters(grid, start);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long SolvePart2(string pathToPuzzleInput)
|
||||||
|
{
|
||||||
|
var grid = ParsePuzzleInput(pathToPuzzleInput);
|
||||||
|
var start = GetStart(grid);
|
||||||
|
var count = GetNodesTraversedWitTimelineCount(grid, start, [], []);
|
||||||
|
return count[start];
|
||||||
|
}
|
||||||
|
|
||||||
|
private Coordinate GetStart(string[] grid)
|
||||||
|
{
|
||||||
|
return (0, grid[0].IndexOf('S'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private long TraverseGridAndCountSplitters(string[] grid, Coordinate start)
|
||||||
|
{
|
||||||
|
HashSet<Coordinate> visited = [start];
|
||||||
|
var seen = new Queue<Coordinate>();
|
||||||
|
seen.Enqueue(start);
|
||||||
|
var splittersHit = 0L;
|
||||||
|
while (seen.TryDequeue(out var current))
|
||||||
|
{
|
||||||
|
if (current.x >= grid.Length) continue;
|
||||||
|
if (current.y >= grid[0].Length || current.y < 0) continue;
|
||||||
|
|
||||||
|
if (grid[current.x][current.y] == '^')
|
||||||
|
{
|
||||||
|
splittersHit++;
|
||||||
|
var nextLeft = (current.x, current.y - 1);
|
||||||
|
var nextRight = (current.x, current.y + 1);
|
||||||
|
if (visited.Add(nextLeft)) seen.Enqueue(nextLeft);
|
||||||
|
if (visited.Add(nextRight)) seen.Enqueue(nextRight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var next = (current.x + 1, current.y);
|
||||||
|
if (visited.Add(next)) seen.Enqueue(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return splittersHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<Coordinate, long> GetNodesTraversedWitTimelineCount(string[] grid, Coordinate current, HashSet<Coordinate> path, Dictionary<Coordinate, long> nodeCountVisited)
|
||||||
|
{
|
||||||
|
if (current.x >= grid.Length || nodeCountVisited.ContainsKey(current))
|
||||||
|
{
|
||||||
|
var addAmount = nodeCountVisited.GetValueOrDefault(current, 1);
|
||||||
|
foreach (var node in path)
|
||||||
|
{
|
||||||
|
nodeCountVisited[node] += addAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeCountVisited;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeCountVisited[current] = 0;
|
||||||
|
path.Add(current);
|
||||||
|
|
||||||
|
if (grid[current.x][current.y] == '^')
|
||||||
|
{
|
||||||
|
var resLeft = GetNodesTraversedWitTimelineCount(grid, (current.x, current.y - 1), [..path], nodeCountVisited);
|
||||||
|
var resRight = GetNodesTraversedWitTimelineCount(grid, (current.x, current.y + 1), [..path], resLeft);
|
||||||
|
return resRight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var res = GetNodesTraversedWitTimelineCount(grid, (current.x + 1, current.y), [..path], nodeCountVisited);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue