diff --git a/2024/Advent.Tests/Commands/Day25CommandTests.cs b/2024/Advent.Tests/Commands/Day25CommandTests.cs new file mode 100644 index 0000000..e73c5f3 --- /dev/null +++ b/2024/Advent.Tests/Commands/Day25CommandTests.cs @@ -0,0 +1,34 @@ +using Advent.Common.Settings; +using Spectre.Console.Cli; + +namespace Advent.Tests.Commands; + +public class Day25CommandTests +{ + private readonly List _arguments = []; + private readonly IRemainingArguments _remaining = Substitute.For(); + private readonly TestConsole console = new(); + + public Day25CommandTests() + { + console.Profile.Capabilities.Interactive = true; + } + + [Fact] + public async Task Day25Command_Solves_Part1_Correctly() + { + var mockReader = Substitute.For(); + mockReader + .ReadInputAsync(Arg.Any()) + .Returns(Task.FromResult(TestData.Day25TestData)); + + var command = new Day25Command(mockReader, console); + var result = await command.ExecuteAsync( + new CommandContext(_arguments, _remaining, "day25", null), + new AdventSettings { Part = "Part 1" } + ); + result.Should().Be(0); + console.Output.Should().Contain("Day 25 Part 1"); + console.Output.Should().Contain("The answer is 3"); + } +} diff --git a/2024/Advent.Tests/Commands/Day4CommandTests.cs b/2024/Advent.Tests/Commands/Day4CommandTests.cs index 39bc9cb..b46333f 100644 --- a/2024/Advent.Tests/Commands/Day4CommandTests.cs +++ b/2024/Advent.Tests/Commands/Day4CommandTests.cs @@ -1,3 +1,4 @@ +using Advent.Common.Settings; using Advent.UseCases.Day4; using Spectre.Console.Cli; @@ -30,7 +31,7 @@ public async Task Day4Command_Solves_Part1_Correctly() var command = new Day4Command(mockReader, console); var result = await command.ExecuteAsync( new CommandContext(_arguments, _remaining, "day4", null), - new Day4Settings { Part = "Part 1", Word = "XMAS" } + new AdventSettings { Part = "Part 1" } ); result.Should().Be(0); console.Output.Should().Contain("Day 4 Part 1"); @@ -46,7 +47,7 @@ public async Task Day4Command_Solves_Part2_Correctly() var command = new Day4Command(mockReader, console); var result = await command.ExecuteAsync( new CommandContext(_arguments, _remaining, "day4", null), - new Day4Settings { Part = "Part 2", Word = "MAS" } + new AdventSettings { Part = "Part 2" } ); result.Should().Be(0); console.Output.Should().Contain("Day 4 Part 2"); @@ -64,7 +65,7 @@ public async Task Day4Command_Prompts_For_Part_1() var command = new Day4Command(mockReader, console); var result = await command.ExecuteAsync( new CommandContext(_arguments, _remaining, "day4", null), - new Day4Settings() { Word = "XMAS" } + new AdventSettings() { } ); result.Should().Be(0); console.Output.Should().Contain("Day 4 Part 1"); @@ -83,7 +84,7 @@ public async Task Day4Command_Prompts_For_Part_2() var command = new Day4Command(mockReader, console); var result = await command.ExecuteAsync( new CommandContext(_arguments, _remaining, "day4", null), - new Day4Settings() { Word = "MAS" } + new AdventSettings() { } ); result.Should().Be(0); console.Output.Should().Contain("Day 4 Part 2"); diff --git a/2024/Advent.Tests/Common/TestData.cs b/2024/Advent.Tests/Common/TestData.cs index 63d5e90..ccbc06d 100644 --- a/2024/Advent.Tests/Common/TestData.cs +++ b/2024/Advent.Tests/Common/TestData.cs @@ -426,4 +426,45 @@ internal static class TestData + "hwm AND bqk -> z03\n" + "tgd XOR rvg -> z12\n" + "tnw OR pbm -> gnj\n"; + + public const string Day25TestData = + "#####\n" + + ".####\n" + + ".####\n" + + ".####\n" + + ".#.#.\n" + + ".#...\n" + + ".....\n" + + "\n\n" + + "#####\n" + + "##.##\n" + + ".#.##\n" + + "...##\n" + + "...#.\n" + + "...#.\n" + + ".....\n" + + "\n" + + ".....\n" + + "#....\n" + + "#....\n" + + "#...#\n" + + "#.#.#\n" + + "#.###\n" + + "#####\n" + + "\n" + + ".....\n" + + ".....\n" + + "#.#..\n" + + "###..\n" + + "###.#\n" + + "###.#\n" + + "#####\n" + + "\n" + + ".....\n" + + ".....\n" + + ".....\n" + + "#....\n" + + "#.#..\n" + + "#.#.#\n" + + "#####\n"; } diff --git a/2024/Advent.Tests/IntegrationTests/CommandAppTests.cs b/2024/Advent.Tests/IntegrationTests/CommandAppTests.cs index 80eae24..c55f247 100644 --- a/2024/Advent.Tests/IntegrationTests/CommandAppTests.cs +++ b/2024/Advent.Tests/IntegrationTests/CommandAppTests.cs @@ -1158,7 +1158,31 @@ public async Task Day24Part2_IntegrationTest_Success() result.Output.Should().Contain("Day 24 Part 2"); result.Output.Should().Contain("The answer is cvh,dbb,hbk,kvn,tfn,z14,z18,z23"); } + #endregion + + #region Day25 + [Fact] + public async Task Day25Part1_IntegrationTest_Success() + { + // Arrange + var args = new string[] { "day25", "--part", "Part 1" }; + var app = new CommandAppTester(_registrar); + + app.Configure(config => + { + config.PropagateExceptions(); + config.ConfigureConsole(_console); + config.AddCommand("day25"); + }); + // Act + var result = await app.RunAsync(args); + + // Assert + result.ExitCode.Should().Be(0); + result.Output.Should().Contain("Day 25 Part 1"); + result.Output.Should().Contain("The answer is 2586"); + } #endregion } diff --git a/2024/Advent.Tests/UseCases/Day1/Day1ParserTests.cs b/2024/Advent.Tests/UseCases/Day1/Day1ParserTests.cs index 591f67a..627bf47 100644 --- a/2024/Advent.Tests/UseCases/Day1/Day1ParserTests.cs +++ b/2024/Advent.Tests/UseCases/Day1/Day1ParserTests.cs @@ -8,11 +8,10 @@ public class Day1ParserTests public void Parse_ShouldReturnTwoListsOfInts() { // Arrange - var parser = new Day1Parser(); var input = "17211 12345\n" + "12397 34356\n" + "36633 45832\n" + "29933 67531\n"; // Act - var result = parser.Parse(input); + var result = Day1Parser.Parse(input); // Assert result.Item1.Should().BeEquivalentTo([17211, 12397, 36633, 29933]); diff --git a/2024/Advent.Tests/UseCases/Day2/Day2ParsterTests.cs b/2024/Advent.Tests/UseCases/Day2/Day2ParsterTests.cs index a5e236c..43308ed 100644 --- a/2024/Advent.Tests/UseCases/Day2/Day2ParsterTests.cs +++ b/2024/Advent.Tests/UseCases/Day2/Day2ParsterTests.cs @@ -10,11 +10,7 @@ public class Day2ParserTests [Fact] public void Parse_ShouldReturnCorrectNumberOfLists() { - // Arrange - var parser = new Day2Parser(); - - // Act - var result = parser.Parse(TestData).ToList(); + var result = Day2Parser.Parse(TestData).ToList(); // Assert result.Count.Should().Be(6); diff --git a/2024/Advent.Tests/UseCases/Day25/Day25ParserTests.cs b/2024/Advent.Tests/UseCases/Day25/Day25ParserTests.cs new file mode 100644 index 0000000..81fcbef --- /dev/null +++ b/2024/Advent.Tests/UseCases/Day25/Day25ParserTests.cs @@ -0,0 +1,33 @@ +using Advent.UseCases.Day25; + +namespace Advent.Tests.UseCases.Day25; + +public class Day25ParserTests +{ + [Fact] + public void Parse_WhenInputIsValid_ReturnsDay25Input() + { + // Arrange + var expectedLocks = new List + { + new(["#####", ".####", ".####", ".####", ".#.#.", ".#...", "....."]), + new(["#####", "##.##", ".#.##", "...##", "...#.", "...#.", "....."]) + }; + + var expectedKeys = new List + { + new([".....", "#....", "#....", "#...#", "#.#.#", "#.###", "#####"]), + new([".....", ".....", "#.#..", "###..", "###.#", "###.#", "#####"]), + new([".....", ".....", ".....", "#....", "#.#..", "#.#.#", "#####"]) + }; + + // Act + (var locks, var keys) = Day25Parser.Parse(TestData.Day25TestData); + + // Assert + locks.Should().HaveCount(2); + locks.Should().BeEquivalentTo(expectedLocks); + keys.Should().HaveCount(3); + keys.Should().BeEquivalentTo(expectedKeys); + } +} diff --git a/2024/Advent.Tests/UseCases/Day25/Day25Part1Solver.cs b/2024/Advent.Tests/UseCases/Day25/Day25Part1Solver.cs new file mode 100644 index 0000000..c741c88 --- /dev/null +++ b/2024/Advent.Tests/UseCases/Day25/Day25Part1Solver.cs @@ -0,0 +1,20 @@ +using Advent.UseCases.Day25; + +namespace Advent.Tests.UseCases.Day25; + +public class Day25Part1SolverTests +{ + [Fact] + public void Solve_WhenInputIsValid_ReturnsCorrectResult() + { + // Arrange + var input = Day25Parser.Parse(TestData.Day25TestData); + var solver = new Day25Part1Solver(); + + // Act + var result = solver.Solve(input); + + // Assert + result.Should().Be("3"); + } +} diff --git a/2024/Advent.Tests/UseCases/Day4/Day4ParserTests.cs b/2024/Advent.Tests/UseCases/Day4/Day4ParserTests.cs index 43cbe92..7298bb1 100644 --- a/2024/Advent.Tests/UseCases/Day4/Day4ParserTests.cs +++ b/2024/Advent.Tests/UseCases/Day4/Day4ParserTests.cs @@ -20,10 +20,7 @@ public void Parse_ShouldCreateCorrectFlatCrossword() var input = "123\n456\n789"; var result = Day4Parser.Parse(input); - result - .FlatCrossword.ToArray() - .Should() - .BeEquivalentTo(['1', '2', '3', '4', '5', '6', '7', '8', '9']); + result.FlatCrossword.Should().BeEquivalentTo(['1', '2', '3', '4', '5', '6', '7', '8', '9']); } [Fact] diff --git a/2024/Advent.Tests/UseCases/Day4/Day4Part1SolverTests.cs b/2024/Advent.Tests/UseCases/Day4/Day4Part1SolverTests.cs index bf0c003..d98e300 100644 --- a/2024/Advent.Tests/UseCases/Day4/Day4Part1SolverTests.cs +++ b/2024/Advent.Tests/UseCases/Day4/Day4Part1SolverTests.cs @@ -4,31 +4,6 @@ namespace Advent.Tests.UseCases.Day4; public class Day4Part1SolverTests { - [Fact] - public void Solve_ShouldReturnCorrectCount() - { - // data that is a 10x10 crossword puzzle - var data = new Day4Data( - [ - "1234167890", - "1234267890", - "1234367890", - "1233367890", - "3321267890", - "1234167893", - "3234567831", - "1334567220", - "1224561390", - "1231563890" - ] - ); - var solver = new Day4Part1Solver("1233"); - - var result = solver.Solve(data); - - result.Should().Be(8); - } - [Fact] public void Solve_ShouldReturnCorrectCount_For_XMAS() { @@ -47,7 +22,7 @@ public void Solve_ShouldReturnCorrectCount_For_XMAS() "MXMXAXMASX" ] ); - var solver = new Day4Part1Solver("XMAS"); + var solver = new Day4Part1Solver(); var result = solver.Solve(data); diff --git a/2024/Advent.Tests/UseCases/Day4/Day4Part2SolverTests.cs b/2024/Advent.Tests/UseCases/Day4/Day4Part2SolverTests.cs index 8dcb601..85765c5 100644 --- a/2024/Advent.Tests/UseCases/Day4/Day4Part2SolverTests.cs +++ b/2024/Advent.Tests/UseCases/Day4/Day4Part2SolverTests.cs @@ -4,31 +4,6 @@ namespace Advent.Tests.UseCases.Day4; public class Day4Part2SolverTests { - [Fact] - public void Solve_ShouldReturnCorrectCount() - { - // data that is a 10x10 crossword puzzle - var data = new Day4Data( - [ - "1234167890", - "1234267890", - "1234367890", - "1233367890", - "3321267890", - "1234167893", - "3234567831", - "1334567220", - "1224561390", - "1231563890" - ] - ); - var solver = new Day4Part2Solver("123"); - - var result = solver.Solve(data); - - result.Should().Be(4); - } - [Fact] public void Solve_ShouldReturnCorrectCount_For_XMAS() { @@ -47,18 +22,10 @@ public void Solve_ShouldReturnCorrectCount_For_XMAS() "MXMXAXMASX" ] ); - var solver = new Day4Part2Solver("MAS"); + var solver = new Day4Part2Solver(); var result = solver.Solve(data); result.Should().Be(9); } - - [Fact] - public void Solve_ShouldThrowArgumentException_WhenWordLengthIsEven() - { - Action act = static () => _ = new Day4Part2Solver("1234"); - - act.Should().Throw().WithMessage("Word must have an odd length"); - } } diff --git a/2024/Advent.Tests/UseCases/Day9/Day9ParserTests.cs b/2024/Advent.Tests/UseCases/Day9/Day9ParserTests.cs index 1a79c7c..4fdc119 100644 --- a/2024/Advent.Tests/UseCases/Day9/Day9ParserTests.cs +++ b/2024/Advent.Tests/UseCases/Day9/Day9ParserTests.cs @@ -4,13 +4,6 @@ namespace Advent.Tests.UseCases.Day9; public class Day9ParserTests { - private readonly Day9Parser _parser; - - public Day9ParserTests() - { - _parser = new Day9Parser(); - } - [Fact] public void Parse_WhenInputIsEmpty_ThrowsInvalidOperationException() { @@ -18,7 +11,7 @@ public void Parse_WhenInputIsEmpty_ThrowsInvalidOperationException() var input = ""; // Act - Action act = () => _parser.Parse(input); + Action act = () => Day9Parser.Parse(input); // Assert act.Should().Throw(); @@ -31,7 +24,7 @@ public void Parse_WhenInputIsInvalid_ThrowsInvalidOperationException() var input = "0"; // Act - Action act = () => _parser.Parse(input); + Action act = () => Day9Parser.Parse(input); // Assert act.Should().Throw(); @@ -62,7 +55,7 @@ public void Parse_WhenInputIsValid_DiskMap() ]; // Act - var result = _parser.Parse(input); + var result = Day9Parser.Parse(input); // Assert result.ToArray().Should().BeEquivalentTo(expected); @@ -73,7 +66,7 @@ public void Parse_WhenInputIsValie_DiskMap2() { var data = TestData.GetDay9ParsedData(); // Act - Span result = _parser.Parse(TestData.Day9ParserInput); + Span result = Day9Parser.Parse(TestData.Day9ParserInput); var resultArray = result.ToArray(); // Assert diff --git a/2024/Advent/Commands/Day1Command.cs b/2024/Advent/Commands/Day1Command.cs index 8a86af1..d7a0b08 100644 --- a/2024/Advent/Commands/Day1Command.cs +++ b/2024/Advent/Commands/Day1Command.cs @@ -10,12 +10,10 @@ namespace Advent.Commands; public class Day1Command(IFileReader reader, IAnsiConsole console) : AdventCommand(reader, console) { - private readonly Day1Parser _parser = new(); - public override async Task ExecuteAsync(CommandContext context, AdventSettings settings) { var input = await _reader.ReadInputAsync("../input/day1input.txt"); - var data = _parser.Parse(input); + var data = Day1Parser.Parse(input); var choice = settings.Part ?? PromptForPartChoice(); IDay1Solver solver = choice switch diff --git a/2024/Advent/Commands/Day25Command.cs b/2024/Advent/Commands/Day25Command.cs new file mode 100644 index 0000000..da2d441 --- /dev/null +++ b/2024/Advent/Commands/Day25Command.cs @@ -0,0 +1,31 @@ +using Advent.Common; +using Advent.Common.Commands; +using Advent.Common.Settings; +using Advent.UseCases.Day25; +using Spectre.Console; +using Spectre.Console.Cli; + +namespace Advent.Commands; + +public class Day25Command(IFileReader reader, IAnsiConsole console) + : AdventCommand(reader, console) +{ + public override async Task ExecuteAsync(CommandContext context, AdventSettings settings) + { + var input = await _reader.ReadInputAsync("../input/day25input.txt"); + var data = Day25Parser.Parse(input); + + var choice = settings.Part ?? PromptForPartChoice(); + IDay25Solver solver = choice switch + { + "Part 1" => new Day25Part1Solver(), + "Part 2" => new Day25Part2Solver(), + _ => throw new InvalidOperationException("Invalid choice") + }; + + var result = solver.Solve(data); + _console.MarkupLine($"[bold green]Day 25 {choice} [/]"); + _console.MarkupLine($"The answer is [bold yellow]{result}[/]"); + return 0; + } +} diff --git a/2024/Advent/Commands/Day2Command.cs b/2024/Advent/Commands/Day2Command.cs index 2c05b87..684ee60 100644 --- a/2024/Advent/Commands/Day2Command.cs +++ b/2024/Advent/Commands/Day2Command.cs @@ -10,12 +10,10 @@ namespace Advent.Commands; public class Day2Command(IFileReader reader, IAnsiConsole console) : AdventCommand(reader, console) { - private readonly Day2Parser _parser = new(); - public override async Task ExecuteAsync(CommandContext context, AdventSettings settings) { var input = await _reader.ReadInputAsync("../input/day2input.txt"); - var data = _parser.Parse(input); + var data = Day2Parser.Parse(input); var choice = settings.Part ?? PromptForPartChoice(); IDay2Solver solver = choice switch diff --git a/2024/Advent/Commands/Day4Command.cs b/2024/Advent/Commands/Day4Command.cs index bad48e9..f5b9b56 100644 --- a/2024/Advent/Commands/Day4Command.cs +++ b/2024/Advent/Commands/Day4Command.cs @@ -1,5 +1,6 @@ using Advent.Common; using Advent.Common.Commands; +using Advent.Common.Settings; using Advent.UseCases.Day4; using Spectre.Console; using Spectre.Console.Cli; @@ -7,9 +8,9 @@ namespace Advent.Commands; public class Day4Command(IFileReader reader, IAnsiConsole console) - : AdventCommand(reader, console) + : AdventCommand(reader, console) { - public override async Task ExecuteAsync(CommandContext context, Day4Settings settings) + public override async Task ExecuteAsync(CommandContext context, AdventSettings settings) { var input = await _reader.ReadInputAsync("../input/day4input.txt"); var data = Day4Parser.Parse(input); @@ -17,8 +18,8 @@ public override async Task ExecuteAsync(CommandContext context, Day4Setting var choice = settings.Part ?? PromptForPartChoice(); IDay4Solver solver = choice switch { - "Part 1" => new Day4Part1Solver(settings.Word), - "Part 2" => new Day4Part2Solver(settings.Word), + "Part 1" => new Day4Part1Solver(), + "Part 2" => new Day4Part2Solver(), _ => throw new InvalidOperationException("Invalid choice") }; diff --git a/2024/Advent/Commands/Day9Command.cs b/2024/Advent/Commands/Day9Command.cs index 98d8f40..382db33 100644 --- a/2024/Advent/Commands/Day9Command.cs +++ b/2024/Advent/Commands/Day9Command.cs @@ -13,8 +13,7 @@ public class Day9Command(IFileReader reader, IAnsiConsole console) public override async Task ExecuteAsync(CommandContext context, AdventSettings settings) { var input = await _reader.ReadInputAsync("../input/day9input.txt"); - var parser = new Day9Parser(); - var data = parser.Parse(input); + var data = Day9Parser.Parse(input); var choice = settings.Part ?? PromptForPartChoice(); IDay9Solver solver = choice switch diff --git a/2024/Advent/Common/GridData.cs b/2024/Advent/Common/GridData.cs index 79c557d..e3edcae 100644 --- a/2024/Advent/Common/GridData.cs +++ b/2024/Advent/Common/GridData.cs @@ -2,9 +2,9 @@ namespace Advent.Common; -public readonly ref struct GridData +public readonly struct GridData : IEquatable { - private readonly Span _cells; + private readonly char[] _cells; public readonly int Rows; public readonly int Columns; @@ -15,7 +15,30 @@ public GridData(Span data, int rows, int columns) Columns = columns; } - public char[] ToArray() => _cells.ToArray(); + public GridData(string[] table) + { + if (table.Length == 0) + { + throw new ArgumentException("Table is empty"); + } + if (table.Any(x => x.Length != table[0].Length)) + { + throw new ArgumentException("Rows are not the same length"); + } + Rows = table.Length; + Columns = table[0].Length; + _cells = new char[Rows * Columns]; + for (int i = 0; i < Rows; i++) + { + var row = table[i]; + for (int j = 0; j < Columns; j++) + { + _cells[i * Columns + j] = row[j]; + } + } + } + + public char[] ToArray() => [.. _cells]; public readonly char this[GridCell cell] { @@ -49,9 +72,9 @@ public readonly char this[(int row, int column) position] } // return an entire row - public readonly ReadOnlySpan this[int row] => _cells.Slice(row * Columns, Columns); + public readonly ReadOnlySpan this[int row] => _cells.AsSpan(row * Columns, Columns); - public readonly int Count(char c) => _cells.Count(c); + public readonly int Count(char c) => _cells.Count(x => x == c); public readonly int Length => _cells.Length; @@ -256,4 +279,28 @@ public override string ToString() } return sb.ToString(); } + + public override int GetHashCode() => HashCode.Combine(Rows, Columns, _cells); + + public override bool Equals(object? obj) => obj is GridData data && Equals(data); + + public bool Equals(GridData other) + { + if (Rows != other.Rows || Columns != other.Columns) + { + return false; + } + for (int i = 0; i < Rows; i++) + { + if (!this[i].SequenceEqual(other[i])) + { + return false; + } + } + return true; + } + + public static bool operator ==(GridData left, GridData right) => left.Equals(right); + + public static bool operator !=(GridData left, GridData right) => !left.Equals(right); } diff --git a/2024/Advent/Program.cs b/2024/Advent/Program.cs index 30f56c2..f07dcae 100644 --- a/2024/Advent/Program.cs +++ b/2024/Advent/Program.cs @@ -36,6 +36,7 @@ config.AddCommand("day22").WithDescription("Advent of Code 2024 Day 22"); config.AddCommand("day23").WithDescription("Advent of Code 2024 Day 23"); config.AddCommand("day24").WithDescription("Advent of Code 2024 Day 24"); + config.AddCommand("day25").WithDescription("Advent of Code 2024 Day 25"); }); return await app.RunAsync(args); diff --git a/2024/Advent/UseCases/Day1/Day1Parser.cs b/2024/Advent/UseCases/Day1/Day1Parser.cs index a03acb5..5357dbe 100644 --- a/2024/Advent/UseCases/Day1/Day1Parser.cs +++ b/2024/Advent/UseCases/Day1/Day1Parser.cs @@ -1,12 +1,12 @@ namespace Advent.UseCases.Day1; -public class Day1Parser +internal static class Day1Parser { - private readonly List _firstList = []; - private readonly List _secondList = []; - - public (List, List) Parse(string input) + internal static (List, List) Parse(string input) { + List _firstList = []; + List _secondList = []; + var lines = input.Split('\n', StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { diff --git a/2024/Advent/UseCases/Day1/Day1Part1Solver.cs b/2024/Advent/UseCases/Day1/Day1Part1Solver.cs index 7130eb3..c6043bd 100644 --- a/2024/Advent/UseCases/Day1/Day1Part1Solver.cs +++ b/2024/Advent/UseCases/Day1/Day1Part1Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day1; -public class Day1Part1Solver : IDay1Solver +internal class Day1Part1Solver : IDay1Solver { public int Solve((List, List) input) { diff --git a/2024/Advent/UseCases/Day1/Day1Part2Solver.cs b/2024/Advent/UseCases/Day1/Day1Part2Solver.cs index e8c41b3..86bf583 100644 --- a/2024/Advent/UseCases/Day1/Day1Part2Solver.cs +++ b/2024/Advent/UseCases/Day1/Day1Part2Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day1; -public class Day1Part2Solver : IDay1Solver +internal class Day1Part2Solver : IDay1Solver { public int Solve((List, List) input) { diff --git a/2024/Advent/UseCases/Day1/IDay1Solver.cs b/2024/Advent/UseCases/Day1/IDay1Solver.cs index bf42aed..989f66c 100644 --- a/2024/Advent/UseCases/Day1/IDay1Solver.cs +++ b/2024/Advent/UseCases/Day1/IDay1Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day1; -public interface IDay1Solver +internal interface IDay1Solver { int Solve((List, List) input); } diff --git a/2024/Advent/UseCases/Day10/Day10Part1Solver.cs b/2024/Advent/UseCases/Day10/Day10Part1Solver.cs index 61e378b..52d86c3 100644 --- a/2024/Advent/UseCases/Day10/Day10Part1Solver.cs +++ b/2024/Advent/UseCases/Day10/Day10Part1Solver.cs @@ -12,7 +12,7 @@ internal struct Day10Node public GridCell Trailhead { get; set; } } -public class Day10Part1Solver : IDay6Solver +internal class Day10Part1Solver : IDay6Solver { // trails start at 0 and end at 9 and must be visited in order private static readonly char[] trailPath = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; diff --git a/2024/Advent/UseCases/Day10/Day10Part2Solver.cs b/2024/Advent/UseCases/Day10/Day10Part2Solver.cs index eac141c..6101e56 100644 --- a/2024/Advent/UseCases/Day10/Day10Part2Solver.cs +++ b/2024/Advent/UseCases/Day10/Day10Part2Solver.cs @@ -5,7 +5,7 @@ namespace Advent.UseCases.Day10; -public class Day10Part2Solver : IDay6Solver +internal class Day10Part2Solver : IDay6Solver { // trails start at 0 and end at 9 and must be visited in order private static readonly char[] trailPath = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; diff --git a/2024/Advent/UseCases/Day11/Day11Parser.cs b/2024/Advent/UseCases/Day11/Day11Parser.cs index 2bd383e..095dd1c 100644 --- a/2024/Advent/UseCases/Day11/Day11Parser.cs +++ b/2024/Advent/UseCases/Day11/Day11Parser.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day11; -public static class Day11Parser +internal static class Day11Parser { - public static ulong[] Parse(string input) + internal static ulong[] Parse(string input) { var lines = input.Split('\n', StringSplitOptions.RemoveEmptyEntries); var numbers = lines diff --git a/2024/Advent/UseCases/Day11/Day11Solver.cs b/2024/Advent/UseCases/Day11/Day11Solver.cs index d8ffd0e..49e80ec 100644 --- a/2024/Advent/UseCases/Day11/Day11Solver.cs +++ b/2024/Advent/UseCases/Day11/Day11Solver.cs @@ -3,7 +3,7 @@ namespace Advent.UseCases.Day11; -public class Day11Solver(int blinks = 25) : IDay11Solver +internal class Day11Solver(int blinks = 25) : IDay11Solver { private readonly int _blinks = blinks; diff --git a/2024/Advent/UseCases/Day11/IDay11Solver.cs b/2024/Advent/UseCases/Day11/IDay11Solver.cs index cadf1d5..a541d2a 100644 --- a/2024/Advent/UseCases/Day11/IDay11Solver.cs +++ b/2024/Advent/UseCases/Day11/IDay11Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day11; -public interface IDay11Solver +internal interface IDay11Solver { long Solve(ulong[] input); } diff --git a/2024/Advent/UseCases/Day12/Day12Part1Solver.cs b/2024/Advent/UseCases/Day12/Day12Part1Solver.cs index e428e1b..01838a9 100644 --- a/2024/Advent/UseCases/Day12/Day12Part1Solver.cs +++ b/2024/Advent/UseCases/Day12/Day12Part1Solver.cs @@ -7,11 +7,11 @@ namespace Advent.UseCases.Day12; internal struct Day12Node { - public GridCell Position { get; set; } - public char Region { get; set; } + internal GridCell Position { get; set; } + internal char Region { get; set; } } -public class Day12Part1Solver : IDay6Solver +internal class Day12Part1Solver : IDay6Solver { private readonly Dictionary fenceCostPerRegion = []; private readonly HashSet visited = []; diff --git a/2024/Advent/UseCases/Day12/Day12Part2Solver.cs b/2024/Advent/UseCases/Day12/Day12Part2Solver.cs index 6a90280..165953a 100644 --- a/2024/Advent/UseCases/Day12/Day12Part2Solver.cs +++ b/2024/Advent/UseCases/Day12/Day12Part2Solver.cs @@ -5,7 +5,7 @@ namespace Advent.UseCases.Day12; -public class Day12Part2Solver() : IDay6Solver +internal class Day12Part2Solver() : IDay6Solver { private readonly Dictionary fenceCostPerRegion = []; private readonly HashSet visited = []; diff --git a/2024/Advent/UseCases/Day13/Day13Data.cs b/2024/Advent/UseCases/Day13/Day13Data.cs index 1be25f5..53f9558 100644 --- a/2024/Advent/UseCases/Day13/Day13Data.cs +++ b/2024/Advent/UseCases/Day13/Day13Data.cs @@ -1,18 +1,18 @@ namespace Advent.UseCases.Day13; -public interface IPoint +internal interface IPoint { public long X { get; init; } public long Y { get; init; } } -public readonly struct Point : IPoint +internal readonly struct Point : IPoint { public long X { get; init; } public long Y { get; init; } } -public readonly struct WeightedPoint : IPoint, IComparable +internal readonly struct WeightedPoint : IPoint, IComparable { public long Weight { get; init; } public long X { get; init; } @@ -44,8 +44,8 @@ public override readonly bool Equals(object? obj) => left.Weight != right.Weight; } -public struct Day13Data +internal struct Day13Data { - public IPoint Destination { get; set; } - public WeightedPoint[] Points { get; init; } + internal IPoint Destination { get; set; } + internal WeightedPoint[] Points { get; init; } } diff --git a/2024/Advent/UseCases/Day13/Day13Parser.cs b/2024/Advent/UseCases/Day13/Day13Parser.cs index 6b3006f..73995d9 100644 --- a/2024/Advent/UseCases/Day13/Day13Parser.cs +++ b/2024/Advent/UseCases/Day13/Day13Parser.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day13; -public static class Day13Parser +internal static class Day13Parser { - public static Day13Data[] Parse(string input) + internal static Day13Data[] Parse(string input) { var groups = input.Split("\n\n", StringSplitOptions.RemoveEmptyEntries); Day13Data[] result = new Day13Data[groups.Length]; diff --git a/2024/Advent/UseCases/Day13/Day13Part1Solver.cs b/2024/Advent/UseCases/Day13/Day13Part1Solver.cs index 18bf0ca..2573568 100644 --- a/2024/Advent/UseCases/Day13/Day13Part1Solver.cs +++ b/2024/Advent/UseCases/Day13/Day13Part1Solver.cs @@ -13,7 +13,7 @@ namespace Advent.UseCases.Day13; /// A lot of help from this link: /// https://www.reddit.com/r/adventofcode/comments/1hd7irq/2024_day_13_an_explanation_of_the_mathematics/ /// -public class Day13Part1Solver(int? maxIterations = 100, long? offset = null) : IDay13Solver +internal class Day13Part1Solver(int? maxIterations = 100, long? offset = null) : IDay13Solver { private readonly int? _maxIterations = maxIterations; private readonly long _offset = offset ?? 0; diff --git a/2024/Advent/UseCases/Day13/Day13Part2Solver.cs b/2024/Advent/UseCases/Day13/Day13Part2Solver.cs index 2ca565d..7a1258b 100644 --- a/2024/Advent/UseCases/Day13/Day13Part2Solver.cs +++ b/2024/Advent/UseCases/Day13/Day13Part2Solver.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day13; -public class Day13Part2Solver(long offset = 10000000000000) : Day13Part1Solver(null, offset) +internal class Day13Part2Solver(long offset = 10000000000000) : Day13Part1Solver(null, offset) { public new BigInteger Solve(Day13Data[] data) { diff --git a/2024/Advent/UseCases/Day13/IDay13Solver.cs b/2024/Advent/UseCases/Day13/IDay13Solver.cs index d348f96..5f68230 100644 --- a/2024/Advent/UseCases/Day13/IDay13Solver.cs +++ b/2024/Advent/UseCases/Day13/IDay13Solver.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day13; -public interface IDay13Solver +internal interface IDay13Solver { public BigInteger Solve(Day13Data[] data); } diff --git a/2024/Advent/UseCases/Day14/Day14Data.cs b/2024/Advent/UseCases/Day14/Day14Data.cs index 29fedf5..5a3f4b4 100644 --- a/2024/Advent/UseCases/Day14/Day14Data.cs +++ b/2024/Advent/UseCases/Day14/Day14Data.cs @@ -3,17 +3,17 @@ namespace Advent.UseCases.Day14; -public struct RobotData +internal struct RobotData { - public GridCell CurrentCell { get; set; } - public GridCell Velocity { get; init; } + internal GridCell CurrentCell { get; set; } + internal GridCell Velocity { get; init; } } -public readonly ref struct Day14Data +internal readonly ref struct Day14Data { - public RobotData[] Robots { get; init; } + internal RobotData[] Robots { get; init; } - public GridCell[] AllRobotCells + internal GridCell[] AllRobotCells { get { @@ -26,7 +26,7 @@ public GridCell[] AllRobotCells } } - public void MoveRobots(int seconds, int maximumRows, int maximumColumns) + internal void MoveRobots(int seconds, int maximumRows, int maximumColumns) { for (int i = 0; i < Robots.Length; i++) { diff --git a/2024/Advent/UseCases/Day14/Day14Parser.cs b/2024/Advent/UseCases/Day14/Day14Parser.cs index fa964d5..44e518c 100644 --- a/2024/Advent/UseCases/Day14/Day14Parser.cs +++ b/2024/Advent/UseCases/Day14/Day14Parser.cs @@ -2,9 +2,9 @@ namespace Advent.UseCases.Day14; -public static class Day14Parser +internal static class Day14Parser { - public static Day14Data Parse(string input) + internal static Day14Data Parse(string input) { /* // Example input: diff --git a/2024/Advent/UseCases/Day14/Day14Part1Solver.cs b/2024/Advent/UseCases/Day14/Day14Part1Solver.cs index 56b7e73..62c05ab 100644 --- a/2024/Advent/UseCases/Day14/Day14Part1Solver.cs +++ b/2024/Advent/UseCases/Day14/Day14Part1Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day14; -public class Day14Part1Solver : IDay14Solver +internal class Day14Part1Solver : IDay14Solver { public (int, string[]?) Solve(Day14Data data, Day14Settings settings) { diff --git a/2024/Advent/UseCases/Day14/Day14Part2Solver.cs b/2024/Advent/UseCases/Day14/Day14Part2Solver.cs index 78146e5..d4b0d7a 100644 --- a/2024/Advent/UseCases/Day14/Day14Part2Solver.cs +++ b/2024/Advent/UseCases/Day14/Day14Part2Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day14; -public class Day14Part2Solver : IDay14Solver +internal class Day14Part2Solver : IDay14Solver { public (int, string[]?) Solve(Day14Data data, Day14Settings settings) { diff --git a/2024/Advent/UseCases/Day14/IDay14Solver.cs b/2024/Advent/UseCases/Day14/IDay14Solver.cs index f6759d5..2ac63bb 100644 --- a/2024/Advent/UseCases/Day14/IDay14Solver.cs +++ b/2024/Advent/UseCases/Day14/IDay14Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day14; -public interface IDay14Solver +internal interface IDay14Solver { (int, string[]?) Solve(Day14Data data, Day14Settings settings); } diff --git a/2024/Advent/UseCases/Day15/Day15Parser.cs b/2024/Advent/UseCases/Day15/Day15Parser.cs index f0993ca..74e2b68 100644 --- a/2024/Advent/UseCases/Day15/Day15Parser.cs +++ b/2024/Advent/UseCases/Day15/Day15Parser.cs @@ -10,7 +10,7 @@ internal readonly ref struct Day15Data internal static class Day15Parser { - public static Day15Data Parse(string input) + internal static Day15Data Parse(string input) { var gridAndMoves = input.Split("\n\n", StringSplitOptions.RemoveEmptyEntries); var gridLines = gridAndMoves[0].Split("\n", StringSplitOptions.RemoveEmptyEntries); @@ -26,7 +26,7 @@ public static Day15Data Parse(string input) return new Day15Data { Data = new GridData(grid, rows, columns), Moves = moves }; } - public static Day15Data ResizeGrid(Day15Data data) + internal static Day15Data ResizeGrid(Day15Data data) { int rows = data.Data.Rows; int columns = data.Data.Columns * 2; diff --git a/2024/Advent/UseCases/Day16/Day16Helpers.cs b/2024/Advent/UseCases/Day16/Day16Helpers.cs index 63113ba..9f70fdf 100644 --- a/2024/Advent/UseCases/Day16/Day16Helpers.cs +++ b/2024/Advent/UseCases/Day16/Day16Helpers.cs @@ -4,8 +4,8 @@ namespace Advent.UseCases.Day16; internal class SearchState { - public GridCell Position { get; set; } - public Direction Direction { get; set; } - public int Score { get; set; } - public IEnumerable Path { get; set; } = []; + internal GridCell Position { get; set; } + internal Direction Direction { get; set; } + internal int Score { get; set; } + internal IEnumerable Path { get; set; } = []; } diff --git a/2024/Advent/UseCases/Day16/Day16Part1Solver.cs b/2024/Advent/UseCases/Day16/Day16Part1Solver.cs index e0624bf..ec6f504 100644 --- a/2024/Advent/UseCases/Day16/Day16Part1Solver.cs +++ b/2024/Advent/UseCases/Day16/Day16Part1Solver.cs @@ -5,7 +5,7 @@ namespace Advent.UseCases.Day16; -public class Day16Part1Solver : IDay6Solver +internal class Day16Part1Solver : IDay6Solver { public int Solve(GridData input) { diff --git a/2024/Advent/UseCases/Day16/Day16Part2Solver.cs b/2024/Advent/UseCases/Day16/Day16Part2Solver.cs index 9718038..7f97566 100644 --- a/2024/Advent/UseCases/Day16/Day16Part2Solver.cs +++ b/2024/Advent/UseCases/Day16/Day16Part2Solver.cs @@ -5,7 +5,7 @@ namespace Advent.UseCases.Day16; -public class Day16Part2Solver : IDay6Solver +internal class Day16Part2Solver : IDay6Solver { public int Solve(GridData input) { diff --git a/2024/Advent/UseCases/Day17/Day17Data.cs b/2024/Advent/UseCases/Day17/Day17Data.cs index 9a2b0a6..16e472b 100644 --- a/2024/Advent/UseCases/Day17/Day17Data.cs +++ b/2024/Advent/UseCases/Day17/Day17Data.cs @@ -1,12 +1,12 @@ namespace Advent.UseCases.Day17 { - public struct Day17Data + internal struct Day17Data { - public long RegisterA { get; set; } - public long RegisterB { get; set; } - public long RegisterC { get; set; } - public int[] Opcode { get; init; } - public int[] Operand { get; init; } - public string OriginalProgram { get; init; } + internal long RegisterA { get; set; } + internal long RegisterB { get; set; } + internal long RegisterC { get; set; } + internal int[] Opcode { get; init; } + internal int[] Operand { get; init; } + internal string OriginalProgram { get; init; } } } diff --git a/2024/Advent/UseCases/Day17/Day17Parser.cs b/2024/Advent/UseCases/Day17/Day17Parser.cs index ce4f1c7..54f6947 100644 --- a/2024/Advent/UseCases/Day17/Day17Parser.cs +++ b/2024/Advent/UseCases/Day17/Day17Parser.cs @@ -7,7 +7,7 @@ internal static class Day17Parser /// /// /// with registers initialized and opcodes and operands ready - public static Day17Data Parse(string input) + internal static Day17Data Parse(string input) { var lines = input.Split("\n\n", StringSplitOptions.RemoveEmptyEntries); var registers = lines[0].Split("\n", StringSplitOptions.RemoveEmptyEntries); diff --git a/2024/Advent/UseCases/Day17/Day17Part1Solver.cs b/2024/Advent/UseCases/Day17/Day17Part1Solver.cs index 92acada..9c9cc41 100644 --- a/2024/Advent/UseCases/Day17/Day17Part1Solver.cs +++ b/2024/Advent/UseCases/Day17/Day17Part1Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day17; -public class Day17Part1Solver : IDay17Solver +internal class Day17Part1Solver : IDay17Solver { public string Solve(Day17Data data) { diff --git a/2024/Advent/UseCases/Day17/Day17Part2Solver.cs b/2024/Advent/UseCases/Day17/Day17Part2Solver.cs index 966ef5e..13b8af4 100644 --- a/2024/Advent/UseCases/Day17/Day17Part2Solver.cs +++ b/2024/Advent/UseCases/Day17/Day17Part2Solver.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day17; -public class Day17Part2Solver : IDay17Solver +internal class Day17Part2Solver : IDay17Solver { public string Solve(Day17Data data) { diff --git a/2024/Advent/UseCases/Day17/IDay17Solver.cs b/2024/Advent/UseCases/Day17/IDay17Solver.cs index 2947d12..b2c96be 100644 --- a/2024/Advent/UseCases/Day17/IDay17Solver.cs +++ b/2024/Advent/UseCases/Day17/IDay17Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day17; -public interface IDay17Solver +internal interface IDay17Solver { string Solve(Day17Data data); } diff --git a/2024/Advent/UseCases/Day18/Day18Helper.cs b/2024/Advent/UseCases/Day18/Day18Helper.cs index 71b01c6..c6f2fc2 100644 --- a/2024/Advent/UseCases/Day18/Day18Helper.cs +++ b/2024/Advent/UseCases/Day18/Day18Helper.cs @@ -10,15 +10,6 @@ private sealed class QueueState public int Distance { get; set; } } - /// - /// Find the path from the top left to the bottom right of the grid - /// or from the start to the end cell. - /// avoiding the '#' characters. The path must be the shortest path - /// - /// - /// - /// - /// internal static List FindPathFromTo( GridData grid, GridCell? start = null, diff --git a/2024/Advent/UseCases/Day18/Day18Parser.cs b/2024/Advent/UseCases/Day18/Day18Parser.cs index 0149c29..db7a6a5 100644 --- a/2024/Advent/UseCases/Day18/Day18Parser.cs +++ b/2024/Advent/UseCases/Day18/Day18Parser.cs @@ -2,9 +2,9 @@ namespace Advent.UseCases.Day18; -public static class Day18Parser +internal static class Day18Parser { - public static List Parse(string input) + internal static List Parse(string input) { List byteCells = [ diff --git a/2024/Advent/UseCases/Day18/Day18Part1Solver.cs b/2024/Advent/UseCases/Day18/Day18Part1Solver.cs index d42b601..90dd61b 100644 --- a/2024/Advent/UseCases/Day18/Day18Part1Solver.cs +++ b/2024/Advent/UseCases/Day18/Day18Part1Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day18; -public class Day18Part1Solver(int rows, int columns, int bytesToFall = 1024) : IDay18Solver +internal class Day18Part1Solver(int rows, int columns, int bytesToFall = 1024) : IDay18Solver { private readonly int _bytesToFall = bytesToFall; private readonly int _rows = rows; diff --git a/2024/Advent/UseCases/Day18/Day18Part2Solver.cs b/2024/Advent/UseCases/Day18/Day18Part2Solver.cs index 63cd911..684b22e 100644 --- a/2024/Advent/UseCases/Day18/Day18Part2Solver.cs +++ b/2024/Advent/UseCases/Day18/Day18Part2Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day18; -public class Day18Part2Solver(int rows, int columns) : IDay18Solver +internal class Day18Part2Solver(int rows, int columns) : IDay18Solver { private readonly int _rows = rows; private readonly int _columns = columns; diff --git a/2024/Advent/UseCases/Day18/IDay18Solver.cs b/2024/Advent/UseCases/Day18/IDay18Solver.cs index ebeb0a0..c0679d1 100644 --- a/2024/Advent/UseCases/Day18/IDay18Solver.cs +++ b/2024/Advent/UseCases/Day18/IDay18Solver.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day18; -public interface IDay18Solver +internal interface IDay18Solver { (string result, string grid) Solve(List data); } diff --git a/2024/Advent/UseCases/Day19/Day19Parser.cs b/2024/Advent/UseCases/Day19/Day19Parser.cs index af54b60..bcc2e97 100644 --- a/2024/Advent/UseCases/Day19/Day19Parser.cs +++ b/2024/Advent/UseCases/Day19/Day19Parser.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day19; -public static class Day19Parser +internal static class Day19Parser { - public static (List buildingBlocks, List targets) Parse(string input) + internal static (List buildingBlocks, List targets) Parse(string input) { var parts = input.Split("\n\n", StringSplitOptions.RemoveEmptyEntries); var buildingBlocks = parts[0] diff --git a/2024/Advent/UseCases/Day19/Day19Part1Solver.cs b/2024/Advent/UseCases/Day19/Day19Part1Solver.cs index 27c8243..7e4f96e 100644 --- a/2024/Advent/UseCases/Day19/Day19Part1Solver.cs +++ b/2024/Advent/UseCases/Day19/Day19Part1Solver.cs @@ -3,7 +3,7 @@ namespace Advent.UseCases.Day19; -public class Day19Part1Solver : IDay19Solver +internal class Day19Part1Solver : IDay19Solver { /// /// Solves the problem of constructing a list target strings using @@ -39,7 +39,7 @@ public string Solve(List buildingBlocks, List targets) /// Determines if a target string can be constructed from a list of building blocks. /// Uses dynamic programming with optimized block matching. /// - public static bool CanConstructString(string target, IList buildingBlocks) + private static bool CanConstructString(string target, IList buildingBlocks) { int n = target.Length; bool[] dpTable = new bool[n + 1]; diff --git a/2024/Advent/UseCases/Day19/Day19Part2Solver.cs b/2024/Advent/UseCases/Day19/Day19Part2Solver.cs index 1f82940..72b1877 100644 --- a/2024/Advent/UseCases/Day19/Day19Part2Solver.cs +++ b/2024/Advent/UseCases/Day19/Day19Part2Solver.cs @@ -3,7 +3,7 @@ namespace Advent.UseCases.Day19; -public class Day19Part2Solver : IDay19Solver +internal class Day19Part2Solver : IDay19Solver { /// /// Solves the problem of constructing a list target strings using @@ -39,7 +39,7 @@ public string Solve(List buildingBlocks, List targets) /// Determines if a target string can be constructed from a list of building blocks. /// Uses dynamic programming with optimized block matching. /// - public static bool CanConstructString( + private static bool CanConstructString( string target, IList buildingBlocks, out ulong possibilities diff --git a/2024/Advent/UseCases/Day19/IDay19Solver.cs b/2024/Advent/UseCases/Day19/IDay19Solver.cs index 8a91f2c..6753c1e 100644 --- a/2024/Advent/UseCases/Day19/IDay19Solver.cs +++ b/2024/Advent/UseCases/Day19/IDay19Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day19; -public interface IDay19Solver +internal interface IDay19Solver { string Solve(List buildingBlocks, List targets); } diff --git a/2024/Advent/UseCases/Day2/Day2Parser.cs b/2024/Advent/UseCases/Day2/Day2Parser.cs index d870211..2461f0f 100644 --- a/2024/Advent/UseCases/Day2/Day2Parser.cs +++ b/2024/Advent/UseCases/Day2/Day2Parser.cs @@ -1,11 +1,10 @@ namespace Advent.UseCases.Day2; -public class Day2Parser +internal static class Day2Parser { - private readonly List> reports = []; - - public IEnumerable> Parse(string input) + internal static IEnumerable> Parse(string input) { + List> reports = []; var lines = input.Split('\n', StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { diff --git a/2024/Advent/UseCases/Day2/Day2Part1Solver.cs b/2024/Advent/UseCases/Day2/Day2Part1Solver.cs index 8da7e23..b68a779 100644 --- a/2024/Advent/UseCases/Day2/Day2Part1Solver.cs +++ b/2024/Advent/UseCases/Day2/Day2Part1Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day2; -public class Day2Part1Solver : IDay2Solver +internal class Day2Part1Solver : IDay2Solver { public int Solve(IEnumerable> input) { diff --git a/2024/Advent/UseCases/Day2/Day2Part2Solver.cs b/2024/Advent/UseCases/Day2/Day2Part2Solver.cs index 8d372ae..7d1b15d 100644 --- a/2024/Advent/UseCases/Day2/Day2Part2Solver.cs +++ b/2024/Advent/UseCases/Day2/Day2Part2Solver.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day2; -public class Day2Part2Solver : IDay2Solver +internal class Day2Part2Solver : IDay2Solver { public int Solve(IEnumerable> input) { diff --git a/2024/Advent/UseCases/Day2/IDay2Solver.cs b/2024/Advent/UseCases/Day2/IDay2Solver.cs index 3edbb5f..ee94080 100644 --- a/2024/Advent/UseCases/Day2/IDay2Solver.cs +++ b/2024/Advent/UseCases/Day2/IDay2Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day2; -public interface IDay2Solver +internal interface IDay2Solver { int Solve(IEnumerable> input); } diff --git a/2024/Advent/UseCases/Day20/Day20Solver.cs b/2024/Advent/UseCases/Day20/Day20Solver.cs index 49b56b0..83b960e 100644 --- a/2024/Advent/UseCases/Day20/Day20Solver.cs +++ b/2024/Advent/UseCases/Day20/Day20Solver.cs @@ -7,7 +7,7 @@ namespace Advent.UseCases.Day20; -public class Day20Solver(int savingsThreshold, int cheatDistance) : IDay6Solver +internal class Day20Solver(int savingsThreshold, int cheatDistance) : IDay6Solver { private readonly int _savingsThreshold = savingsThreshold; private readonly HashSet<(GridCell, GridCell)> possibleCheats = []; diff --git a/2024/Advent/UseCases/Day21/Day21Parser.cs b/2024/Advent/UseCases/Day21/Day21Parser.cs index 5682f86..0a0c6b9 100644 --- a/2024/Advent/UseCases/Day21/Day21Parser.cs +++ b/2024/Advent/UseCases/Day21/Day21Parser.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day21; -public static class Day21Parser +internal static class Day21Parser { - public static string[] Parse(string input) + internal static string[] Parse(string input) { return input.Split("\n", StringSplitOptions.RemoveEmptyEntries); } diff --git a/2024/Advent/UseCases/Day21/Day21Solver.cs b/2024/Advent/UseCases/Day21/Day21Solver.cs index 7014f20..6f07026 100644 --- a/2024/Advent/UseCases/Day21/Day21Solver.cs +++ b/2024/Advent/UseCases/Day21/Day21Solver.cs @@ -9,7 +9,7 @@ namespace Advent.UseCases.Day21; -public class Day21Solver(int depth) : IDay21Solver +internal class Day21Solver(int depth) : IDay21Solver { private readonly int _depth = depth; diff --git a/2024/Advent/UseCases/Day21/IDay21Solver.cs b/2024/Advent/UseCases/Day21/IDay21Solver.cs index 70d678c..40c4408 100644 --- a/2024/Advent/UseCases/Day21/IDay21Solver.cs +++ b/2024/Advent/UseCases/Day21/IDay21Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day21; -public interface IDay21Solver +internal interface IDay21Solver { public string Solve(string[] input); } diff --git a/2024/Advent/UseCases/Day22/Day22Part1Solver.cs b/2024/Advent/UseCases/Day22/Day22Part1Solver.cs index a55268f..fad8cf1 100644 --- a/2024/Advent/UseCases/Day22/Day22Part1Solver.cs +++ b/2024/Advent/UseCases/Day22/Day22Part1Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day22; -public class Day22Part1Solver(int simulations) : IDay21Solver +internal class Day22Part1Solver(int simulations) : IDay21Solver { private readonly int _simulations = simulations; diff --git a/2024/Advent/UseCases/Day22/Day22Part2Solver.cs b/2024/Advent/UseCases/Day22/Day22Part2Solver.cs index 410207d..502556e 100644 --- a/2024/Advent/UseCases/Day22/Day22Part2Solver.cs +++ b/2024/Advent/UseCases/Day22/Day22Part2Solver.cs @@ -5,7 +5,7 @@ namespace Advent.UseCases.Day22; -public class Day22Part2Solver : IDay21Solver +internal class Day22Part2Solver : IDay21Solver { private const int SEQUENCE_LENGTH = 4; private const int MOD_VALUE = 10; @@ -14,7 +14,7 @@ public class Day22Part2Solver : IDay21Solver private readonly Dictionary _priceMap = []; private readonly HashSet _visited = []; - public Day22Part2Solver(int simulations) + internal Day22Part2Solver(int simulations) { if (simulations <= SEQUENCE_LENGTH) throw new ArgumentException( diff --git a/2024/Advent/UseCases/Day22/Day22SecrectNumber.cs b/2024/Advent/UseCases/Day22/Day22SecrectNumber.cs index 0ee2dc1..17d1b4b 100644 --- a/2024/Advent/UseCases/Day22/Day22SecrectNumber.cs +++ b/2024/Advent/UseCases/Day22/Day22SecrectNumber.cs @@ -1,10 +1,10 @@ namespace Advent.UseCases.Day22; -public static class Day22SecrectNumber +internal static class Day22SecrectNumber { private const int PRUNE = 16777216; - public static long GenerateSecretNumber(long seed) + internal static long GenerateSecretNumber(long seed) { seed = (seed << 6) ^ seed; // multiply by 64 and XOR long pruned = seed % PRUNE; diff --git a/2024/Advent/UseCases/Day23/Day23Helper.cs b/2024/Advent/UseCases/Day23/Day23Helper.cs index abe56ee..0b1e42b 100644 --- a/2024/Advent/UseCases/Day23/Day23Helper.cs +++ b/2024/Advent/UseCases/Day23/Day23Helper.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day23; internal static class Day23Helper { - public static void PopulateGraphFromInput( + internal static void PopulateGraphFromInput( List<(string, string)> edges, Dictionary> adjacencyList ) @@ -24,7 +24,7 @@ void AddEdge(string from, string to) } } - public static void ProcessGraph( + internal static void ProcessGraph( Dictionary> graph, List> cliques ) diff --git a/2024/Advent/UseCases/Day23/Day23Parser.cs b/2024/Advent/UseCases/Day23/Day23Parser.cs index 2c94607..c1c9664 100644 --- a/2024/Advent/UseCases/Day23/Day23Parser.cs +++ b/2024/Advent/UseCases/Day23/Day23Parser.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day23; -public static class Day23Parser +internal static class Day23Parser { - public static List<(string, string)> Parse(string input) + internal static List<(string, string)> Parse(string input) { return input .Split("\n", StringSplitOptions.RemoveEmptyEntries) diff --git a/2024/Advent/UseCases/Day23/Day23Part1Solver.cs b/2024/Advent/UseCases/Day23/Day23Part1Solver.cs index bb5e3b4..91dc6d0 100644 --- a/2024/Advent/UseCases/Day23/Day23Part1Solver.cs +++ b/2024/Advent/UseCases/Day23/Day23Part1Solver.cs @@ -5,8 +5,8 @@ namespace Advent.UseCases.Day23; internal class Day23Part1Solver : IDay23Solver { - public readonly Dictionary> _graph = []; - public readonly List> _cliques = []; + internal readonly Dictionary> _graph = []; + internal readonly List> _cliques = []; public string Solve(List<(string, string)> input) { diff --git a/2024/Advent/UseCases/Day23/Day23Part2Solver.cs b/2024/Advent/UseCases/Day23/Day23Part2Solver.cs index fec2a56..9ef6966 100644 --- a/2024/Advent/UseCases/Day23/Day23Part2Solver.cs +++ b/2024/Advent/UseCases/Day23/Day23Part2Solver.cs @@ -5,8 +5,8 @@ namespace Advent.UseCases.Day23; internal class Day23Part2Solver : IDay23Solver { - public readonly Dictionary> _graph = []; - public readonly List> _cliques = []; + internal readonly Dictionary> _graph = []; + internal readonly List> _cliques = []; public string Solve(List<(string, string)> input) { diff --git a/2024/Advent/UseCases/Day24/Day24Data.cs b/2024/Advent/UseCases/Day24/Day24Data.cs index a689405..27e92b5 100644 --- a/2024/Advent/UseCases/Day24/Day24Data.cs +++ b/2024/Advent/UseCases/Day24/Day24Data.cs @@ -37,10 +37,10 @@ internal class Gate internal class Day24Circuit { private bool _isSolved = false; - public HashSet Wires { get; init; } = []; - public List Gates { get; init; } = []; + internal HashSet Wires { get; init; } = []; + internal List Gates { get; init; } = []; - public Wire GetWire(string name) => Wires.First(w => w.Name == name); + internal Wire GetWire(string name) => Wires.First(w => w.Name == name); /// /// Get the signal of the output wire with the given name. @@ -48,7 +48,7 @@ internal class Day24Circuit /// /// /// - public bool? GetOutputSignal(string outputWireName) + internal bool? GetOutputSignal(string outputWireName) { Solve(); // // Return the signal of the requested output wire @@ -81,27 +81,6 @@ private void Solve() _isSolved = true; } - /// - /// Reset the circuit by setting all wire signals to their original values. - /// - public void Reset() - { - foreach (var wire in Wires) - { - wire.Reset(); - } - _isSolved = false; - } - - public void SwapOutputWires(string outputWireName1, string outputWireName2) - { - Reset(); - var gate1 = Gates.First(g => g.OutputWireName == outputWireName1); - var gate2 = Gates.First(g => g.OutputWireName == outputWireName2); - gate1.OutputWireName = outputWireName2; - gate2.OutputWireName = outputWireName1; - } - private long GetNumber(char startsWith = 'z') { var outputWires = Wires @@ -121,17 +100,7 @@ private long GetNumber(char startsWith = 'z') return signals.Select((b, i) => b ? 1L << i : 0).Aggregate((a, b) => a | b); } - public long GetInput1Number() - { - return GetNumber('x'); - } - - public long GetInput2Number() - { - return GetNumber('y'); - } - - public long GetOutputNumber() + internal long GetOutputNumber() { return GetNumber(); } diff --git a/2024/Advent/UseCases/Day24/Day24Part2Solver.cs b/2024/Advent/UseCases/Day24/Day24Part2Solver.cs index 63e147c..f5a56fa 100644 --- a/2024/Advent/UseCases/Day24/Day24Part2Solver.cs +++ b/2024/Advent/UseCases/Day24/Day24Part2Solver.cs @@ -20,6 +20,7 @@ public string Solve(Day24Circuit input) a.Sort(); var result = string.Join(',', a); sw.Stop(); + AnsiConsole.WriteLine($"Execution time: {sw.Elapsed.TotalMilliseconds} ms"); return result; } diff --git a/2024/Advent/UseCases/Day25/Day25Parser.cs b/2024/Advent/UseCases/Day25/Day25Parser.cs new file mode 100644 index 0000000..73e42d6 --- /dev/null +++ b/2024/Advent/UseCases/Day25/Day25Parser.cs @@ -0,0 +1,30 @@ +using Advent.Common; + +namespace Advent.UseCases.Day25; + +internal static class Day25Parser +{ + internal static (List locks, List keys) Parse(string input) + { + var locksAndKeys = input.Split("\n\n", StringSplitOptions.RemoveEmptyEntries); + List locks = []; + List keys = []; + foreach (var lockOrKey in locksAndKeys) + { + var lines = lockOrKey.Split("\n", StringSplitOptions.RemoveEmptyEntries); + if (lines[0] == "#####") + { + locks.Add(new GridData(lines)); + continue; + } + else if (lines[0] == ".....") + { + // keys + keys.Add(new GridData(lines)); + continue; + } + throw new InvalidOperationException("Invalid input"); + } + return (locks, keys); + } +} diff --git a/2024/Advent/UseCases/Day25/Day25Part1Solver.cs b/2024/Advent/UseCases/Day25/Day25Part1Solver.cs new file mode 100644 index 0000000..71693d9 --- /dev/null +++ b/2024/Advent/UseCases/Day25/Day25Part1Solver.cs @@ -0,0 +1,56 @@ +using System.Diagnostics; +using Advent.Common; +using Spectre.Console; + +namespace Advent.UseCases.Day25; + +internal class Day25Part1Solver : IDay25Solver +{ + public string Solve((List locks, List keys) input) + { + Stopwatch sw = new(); + sw.Start(); + int uniqueKeyLockCombinations = FindAllUniqueKeyLockCombinations(input.locks, input.keys); + sw.Stop(); + AnsiConsole.WriteLine($"Execution time: {sw.Elapsed.TotalMilliseconds} ms"); + return uniqueKeyLockCombinations.ToString(); + } + + private static int FindAllUniqueKeyLockCombinations(List locks, List keys) + { + int uniqueKeyLockCombinations = 0; + + keys.ForEach(key => + { + locks.ForEach(theLock => + { + if (CanUnlock(theLock, key)) + { + uniqueKeyLockCombinations++; + } + }); + }); + return uniqueKeyLockCombinations; + } + + private static bool CanUnlock(GridData theLock, GridData key) + { + if (theLock.Rows != key.Rows || theLock.Columns != key.Columns) + { + return false; + } + for (int i = 0; i < theLock.Rows; i++) + { + var lockRow = theLock[i]; + var keyRow = key[i]; + for (int j = 0; j < theLock.Columns; j++) + { + if (lockRow[j] == '#' && keyRow[j] == '#') + { + return false; + } + } + } + return true; + } +} diff --git a/2024/Advent/UseCases/Day25/Day25Part2Solver.cs b/2024/Advent/UseCases/Day25/Day25Part2Solver.cs new file mode 100644 index 0000000..575efba --- /dev/null +++ b/2024/Advent/UseCases/Day25/Day25Part2Solver.cs @@ -0,0 +1,11 @@ +using Advent.Common; + +namespace Advent.UseCases.Day25; + +public class Day25Part2Solver : IDay25Solver +{ + public string Solve((List locks, List keys) input) + { + return "There was no part 2 for day 25, Don't worry, you solved it!"; + } +} diff --git a/2024/Advent/UseCases/Day25/IDay25Solver.cs b/2024/Advent/UseCases/Day25/IDay25Solver.cs new file mode 100644 index 0000000..dc74938 --- /dev/null +++ b/2024/Advent/UseCases/Day25/IDay25Solver.cs @@ -0,0 +1,8 @@ +using Advent.Common; + +namespace Advent.UseCases.Day25; + +internal interface IDay25Solver +{ + public string Solve((List locks, List keys) input); +} diff --git a/2024/Advent/UseCases/Day3/Day3Parser.cs b/2024/Advent/UseCases/Day3/Day3Parser.cs index c6ec12c..2cad14c 100644 --- a/2024/Advent/UseCases/Day3/Day3Parser.cs +++ b/2024/Advent/UseCases/Day3/Day3Parser.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day3; -public static class Day3Parser +internal static class Day3Parser { - public static string Parse(string input) + internal static string Parse(string input) { // remove \n and replace with "" var lines = input.Split('\n', StringSplitOptions.RemoveEmptyEntries); diff --git a/2024/Advent/UseCases/Day3/Day3Part1Solver.cs b/2024/Advent/UseCases/Day3/Day3Part1Solver.cs index da0010b..552ae5b 100644 --- a/2024/Advent/UseCases/Day3/Day3Part1Solver.cs +++ b/2024/Advent/UseCases/Day3/Day3Part1Solver.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day3; -public partial class Day3Part1Solver : IDay3Solver +internal partial class Day3Part1Solver : IDay3Solver { [GeneratedRegex(@"mul\((?\d{1,3}),(?\d{1,3})\)")] private static partial Regex MultiplicationPattern(); diff --git a/2024/Advent/UseCases/Day3/Day3Part2Solver.cs b/2024/Advent/UseCases/Day3/Day3Part2Solver.cs index 0deacc2..224f586 100644 --- a/2024/Advent/UseCases/Day3/Day3Part2Solver.cs +++ b/2024/Advent/UseCases/Day3/Day3Part2Solver.cs @@ -2,7 +2,7 @@ namespace Advent.UseCases.Day3; -public partial class Day3Part2Solver : IDay3Solver +internal partial class Day3Part2Solver : IDay3Solver { [GeneratedRegex(@"do\(\)|don't\(\)|mul\((?\d{1,3}),(?\d{1,3})\)")] private static partial Regex MultiplicationPattern2(); diff --git a/2024/Advent/UseCases/Day3/IDay3Solver.cs b/2024/Advent/UseCases/Day3/IDay3Solver.cs index 6592737..7c4ad19 100644 --- a/2024/Advent/UseCases/Day3/IDay3Solver.cs +++ b/2024/Advent/UseCases/Day3/IDay3Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day3; -public interface IDay3Solver +internal interface IDay3Solver { int Solve(string input); } diff --git a/2024/Advent/UseCases/Day4/Day4Helpers.cs b/2024/Advent/UseCases/Day4/Day4Helpers.cs index 85feacc..c5d422a 100644 --- a/2024/Advent/UseCases/Day4/Day4Helpers.cs +++ b/2024/Advent/UseCases/Day4/Day4Helpers.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day4; -public static class Day4Helpers +internal static class Day4Helpers { - public static int[] ComputeDiagDecIndexes(int i, int length, int columns) + internal static int[] ComputeDiagDecIndexes(int i, int length, int columns) { int[] indexes = new int[length]; for (int j = 0; j < length; j++) @@ -12,7 +12,7 @@ public static int[] ComputeDiagDecIndexes(int i, int length, int columns) return indexes; } - public static int[] ComputeDiagIncIndexes(int i, int length, int columns) + internal static int[] ComputeDiagIncIndexes(int i, int length, int columns) { int[] indexes = new int[length]; for (int j = 0; j < length; j++) @@ -22,7 +22,7 @@ public static int[] ComputeDiagIncIndexes(int i, int length, int columns) return indexes; } - public static int[] ComputeHorizontalIndexes(int i, int length) + internal static int[] ComputeHorizontalIndexes(int i, int length) { int[] indexes = new int[length]; for (int j = 0; j < length; j++) @@ -32,7 +32,7 @@ public static int[] ComputeHorizontalIndexes(int i, int length) return indexes; } - public static int[] ComputeVerticalIndexes(int i, int length, int columns) + internal static int[] ComputeVerticalIndexes(int i, int length, int columns) { int[] indexes = new int[length]; for (int j = 0; j < length; j++) diff --git a/2024/Advent/UseCases/Day4/Day4Parser.cs b/2024/Advent/UseCases/Day4/Day4Parser.cs index 75c7963..81bde4b 100644 --- a/2024/Advent/UseCases/Day4/Day4Parser.cs +++ b/2024/Advent/UseCases/Day4/Day4Parser.cs @@ -1,13 +1,13 @@ namespace Advent.UseCases.Day4; -public readonly ref struct Day4Data(string[] input) +internal readonly ref struct Day4Data(string[] input) { public readonly char[] FlatCrossword { get; } = input.SelectMany(x => x).ToArray(); public readonly int Rows { get; } = input.Length; public readonly int Columns { get; } = input[0].Length; } -public static class Day4Parser +internal static class Day4Parser { public static Day4Data Parse(string input) { diff --git a/2024/Advent/UseCases/Day4/Day4Part1Solver.cs b/2024/Advent/UseCases/Day4/Day4Part1Solver.cs index 39d1fb0..1a16585 100644 --- a/2024/Advent/UseCases/Day4/Day4Part1Solver.cs +++ b/2024/Advent/UseCases/Day4/Day4Part1Solver.cs @@ -4,16 +4,13 @@ namespace Advent.UseCases.Day4; -public class Day4Part1Solver : IDay4Solver +internal class Day4Part1Solver : IDay4Solver { - private readonly char[] _word; - private readonly int _wordLength; + private readonly char[] _word = ['X', 'M', 'A', 'S']; private readonly char[] _reversedWord; - public Day4Part1Solver(string word) + internal Day4Part1Solver() { - _word = [.. word]; - _wordLength = _word.Length; _reversedWord = _word.Reverse().ToArray(); } @@ -36,17 +33,17 @@ private int FindDiagonalInc(Span data, int rows, int cols) { int count = 0; IEnumerable diagonalRangeInc = Enumerable - .Range(0, rows - _wordLength + 1) + .Range(0, rows - _word.Length + 1) .Select(x => new Range( - (cols * x) + _wordLength - 1, - (cols * x) + _wordLength - 1 + (cols - _wordLength) + (cols * x) + _word.Length - 1, + (cols * x) + _word.Length - 1 + (cols - _word.Length) )) .ToArray(); foreach (var range in diagonalRangeInc) { for (int i = range.Start.Value; i <= range.End.Value; i++) { - int[] letterIndexes = Day4Helpers.ComputeDiagIncIndexes(i, _wordLength, cols); + int[] letterIndexes = Day4Helpers.ComputeDiagIncIndexes(i, _word.Length, cols); count += LookForWord(data, letterIndexes); } } @@ -57,17 +54,17 @@ private int FindDiagonalDec(Span data, int rows, int cols) { int count = 0; IEnumerable diagonalRangeDec = Enumerable - .Range(0, rows - _wordLength + 1) + .Range(0, rows - _word.Length + 1) .Select(x => new Range( x + ((cols - 1) * x), - x + ((cols - 1) * x) + (cols - _wordLength) + x + ((cols - 1) * x) + (cols - _word.Length) )) .ToArray(); foreach (var range in diagonalRangeDec) { for (int i = range.Start.Value; i <= range.End.Value; i++) { - int[] letterIndexes = Day4Helpers.ComputeDiagDecIndexes(i, _wordLength, cols); + int[] letterIndexes = Day4Helpers.ComputeDiagDecIndexes(i, _word.Length, cols); count += LookForWord(data, letterIndexes); } } @@ -82,14 +79,14 @@ private int FindHorizontal(Span data, int rows, int cols) .Range(0, rows) .Select(x => new Range( x + ((cols - 1) * x), - x + ((cols - 1) * x) + (cols - _wordLength) + x + ((cols - 1) * x) + (cols - _word.Length) )) .ToArray(); foreach (var range in horizontalRange) { for (int i = range.Start.Value; i <= range.End.Value; i++) { - int[] letterIndexes = Day4Helpers.ComputeHorizontalIndexes(i, _wordLength); + int[] letterIndexes = Day4Helpers.ComputeHorizontalIndexes(i, _word.Length); count += LookForWord(data, letterIndexes); } } @@ -100,14 +97,14 @@ private int FindVertical(Span data, int rows, int cols) { int count = 0; IEnumerable verticalRange = Enumerable - .Range(0, rows - _wordLength + 1) + .Range(0, rows - _word.Length + 1) .Select(x => new Range(x + ((cols - 1) * x), x + ((cols - 1) * x) + cols - 1)) .ToArray(); foreach (var range in verticalRange) { for (int i = range.Start.Value; i <= range.End.Value; i++) { - int[] letterIndexes = Day4Helpers.ComputeVerticalIndexes(i, _wordLength, cols); + int[] letterIndexes = Day4Helpers.ComputeVerticalIndexes(i, _word.Length, cols); count += LookForWord(data, letterIndexes); } } @@ -121,8 +118,8 @@ private int LookForWord(Span data, int[] letterIndexes) return 0; // Use stackalloc for small arrays - Span chars = stackalloc char[_wordLength]; - for (int x = 0; x < _wordLength; x++) + Span chars = stackalloc char[_word.Length]; + for (int x = 0; x < _word.Length; x++) { chars[x] = data[letterIndexes[x]]; } diff --git a/2024/Advent/UseCases/Day4/Day4Part2Solver.cs b/2024/Advent/UseCases/Day4/Day4Part2Solver.cs index 95f7862..b4c482f 100644 --- a/2024/Advent/UseCases/Day4/Day4Part2Solver.cs +++ b/2024/Advent/UseCases/Day4/Day4Part2Solver.cs @@ -4,23 +4,15 @@ namespace Advent.UseCases.Day4; -public class Day4Part2Solver : IDay4Solver +internal class Day4Part2Solver : IDay4Solver { - private readonly char[] _word; - private readonly int _wordLength; + private readonly char[] _word = ['M', 'A', 'S']; + private readonly char[] _reversedWord = ['S', 'A', 'M']; private readonly int _halfWordLength; - private readonly char[] _reversedWord; - public Day4Part2Solver(string word) + internal Day4Part2Solver() { - if (word.Length % 2 == 0) - { - throw new ArgumentException("Word must have an odd length"); - } - _word = [.. word]; - _wordLength = _word.Length; - _halfWordLength = (_wordLength + 1) / 2; - _reversedWord = _word.Reverse().ToArray(); + _halfWordLength = (_word.Length + 1) / 2; } public int Solve(Day4Data data) @@ -51,12 +43,12 @@ private int FindWordInXShape(Span data, int rows, int cols) { int[] x1 = Day4Helpers.ComputeDiagDecIndexes( i - (cols * (_halfWordLength - 1)) - (_halfWordLength - 1), - _wordLength, + _word.Length, cols ); int[] x2 = Day4Helpers.ComputeDiagIncIndexes( i - (cols * (_halfWordLength - 1)) + (_halfWordLength - 1), - _wordLength, + _word.Length, cols ); count += (LookForWord(data, x1) && LookForWord(data, x2)) ? 1 : 0; @@ -72,8 +64,8 @@ private bool LookForWord(Span data, int[] letterIndexes) return false; // Use stackalloc for small arrays - Span chars = stackalloc char[_wordLength]; - for (int x = 0; x < _wordLength; x++) + Span chars = stackalloc char[_word.Length]; + for (int x = 0; x < _word.Length; x++) { chars[x] = data[letterIndexes[x]]; } diff --git a/2024/Advent/UseCases/Day4/Day4Settings.cs b/2024/Advent/UseCases/Day4/Day4Settings.cs deleted file mode 100644 index 0ccdc3c..0000000 --- a/2024/Advent/UseCases/Day4/Day4Settings.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.ComponentModel; -using Advent.Common.Settings; -using Spectre.Console; -using Spectre.Console.Cli; - -namespace Advent.UseCases.Day4; - -public sealed class Day4Settings : AdventSettings -{ - [CommandOption("-w|--word")] - [Description("The word to search for in the crossword puzzle")] - public required string Word { get; init; } - - public override ValidationResult Validate() - { - base.Validate(); - if (string.IsNullOrWhiteSpace(Word)) - return ValidationResult.Error("Word must be provided using the -w|--word option"); - if (Part == "Part 2" && Word?.Length % 2 == 0) - return ValidationResult.Error("Word must have an odd length for Part 2"); - return ValidationResult.Success(); - } -} diff --git a/2024/Advent/UseCases/Day4/IDay4Solver.cs b/2024/Advent/UseCases/Day4/IDay4Solver.cs index a9e79b4..b077495 100644 --- a/2024/Advent/UseCases/Day4/IDay4Solver.cs +++ b/2024/Advent/UseCases/Day4/IDay4Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day4; -public interface IDay4Solver +internal interface IDay4Solver { /// /// Solve the crossword puzzle @@ -8,5 +8,5 @@ public interface IDay4Solver /// /// /// number of instances that word occurrs in any - | / \ forwards or backwards - public int Solve(Day4Data data); + int Solve(Day4Data data); } diff --git a/2024/Advent/UseCases/Day5/Day5Helper.cs b/2024/Advent/UseCases/Day5/Day5Helper.cs deleted file mode 100644 index 32a4118..0000000 --- a/2024/Advent/UseCases/Day5/Day5Helper.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Advent.UseCases.Day5; - -#pragma warning disable S3267 // "IEnumerable" LINQs should be simplified -public static class Day5Helper -{ - public static bool AlreadyFollowingRules(HashSet previousPages, List rules) - { - foreach (int rule in rules) - { - if (previousPages.Contains(rule)) - { - return false; - } - } - return true; - } -} -#pragma warning restore S3267 diff --git a/2024/Advent/UseCases/Day5/Day5Parser.cs b/2024/Advent/UseCases/Day5/Day5Parser.cs index 7201625..834f576 100644 --- a/2024/Advent/UseCases/Day5/Day5Parser.cs +++ b/2024/Advent/UseCases/Day5/Day5Parser.cs @@ -3,15 +3,15 @@ namespace Advent.UseCases.Day5; -public class Day5Data() +internal class Day5Data() { public required ReadOnlyDictionary> PrintRules { get; init; } public required IEnumerable> PagesToPrint { get; init; } } -public static class Day5Parser +internal static class Day5Parser { - public static Day5Data Parse(string? input) + internal static Day5Data Parse(string? input) { ArgumentNullException.ThrowIfNull(input); diff --git a/2024/Advent/UseCases/Day5/Day5Part1Solver.cs b/2024/Advent/UseCases/Day5/Day5Part1Solver.cs index 4e54dd0..6fecb89 100644 --- a/2024/Advent/UseCases/Day5/Day5Part1Solver.cs +++ b/2024/Advent/UseCases/Day5/Day5Part1Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day5; -public class Day5Part1Solver : IDay5Solver +internal class Day5Part1Solver : IDay5Solver { public int Solve(Day5Data data) { @@ -33,7 +33,7 @@ ReadOnlyDictionary> printRules HashSet previousPages = pages[..j].ToArray().ToHashSet(); if (printRules.TryGetValue(pages[j], out List? rules)) { - if (Day5Helper.AlreadyFollowingRules(previousPages, rules)) + if (!rules.Any(previousPages.Contains)) continue; return 0; } diff --git a/2024/Advent/UseCases/Day5/Day5Part2Solver.cs b/2024/Advent/UseCases/Day5/Day5Part2Solver.cs index f0961e5..81709ea 100644 --- a/2024/Advent/UseCases/Day5/Day5Part2Solver.cs +++ b/2024/Advent/UseCases/Day5/Day5Part2Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day5; -public class Day5Part2Solver : IDay5Solver +internal class Day5Part2Solver : IDay5Solver { public int Solve(Day5Data data) { @@ -122,7 +122,7 @@ ReadOnlyDictionary> printRules HashSet previousPages = pages[..j].ToArray().ToHashSet(); if ( printRules.TryGetValue(pages[j], out List? rules) - && !Day5Helper.AlreadyFollowingRules(previousPages, rules) + && rules.Any(previousPages.Contains) ) { return false; diff --git a/2024/Advent/UseCases/Day5/IDay5Solver.cs b/2024/Advent/UseCases/Day5/IDay5Solver.cs index 2f74c7f..f1120b1 100644 --- a/2024/Advent/UseCases/Day5/IDay5Solver.cs +++ b/2024/Advent/UseCases/Day5/IDay5Solver.cs @@ -1,11 +1,11 @@ namespace Advent.UseCases.Day5; -public interface IDay5Solver +internal interface IDay5Solver { /// /// Solve the printing problem /// /// /// the correct solution - public int Solve(Day5Data data); + int Solve(Day5Data data); } diff --git a/2024/Advent/UseCases/Day6/Day6Helpers.cs b/2024/Advent/UseCases/Day6/Day6Helpers.cs index af0ebe4..219b9dc 100644 --- a/2024/Advent/UseCases/Day6/Day6Helpers.cs +++ b/2024/Advent/UseCases/Day6/Day6Helpers.cs @@ -2,9 +2,9 @@ namespace Advent.UseCases.Day6; -public static class Day6Helpers +internal static class Day6Helpers { - public static Direction TurnRight(Direction direction) + internal static Direction TurnRight(Direction direction) { return direction switch { @@ -16,7 +16,7 @@ public static Direction TurnRight(Direction direction) }; } - public static GridCell GoBackOne(GridCell currentPosition, Direction currentDirection) + internal static GridCell GoBackOne(GridCell currentPosition, Direction currentDirection) { return currentDirection switch { @@ -28,7 +28,7 @@ public static GridCell GoBackOne(GridCell currentPosition, Direction currentDire }; } - public static GridCell GoForwardOne(GridCell currentPosition, Direction currentDirection) + internal static GridCell GoForwardOne(GridCell currentPosition, Direction currentDirection) { return currentDirection switch { diff --git a/2024/Advent/UseCases/Day6/Day6Parser.cs b/2024/Advent/UseCases/Day6/Day6Parser.cs index e59f17c..78da152 100644 --- a/2024/Advent/UseCases/Day6/Day6Parser.cs +++ b/2024/Advent/UseCases/Day6/Day6Parser.cs @@ -2,9 +2,9 @@ namespace Advent.UseCases.Day6; -public static class Day6Parser +internal static class Day6Parser { - public static GridData Parse(string input) + internal static GridData Parse(string input) { var lines = input.Split('\n', StringSplitOptions.RemoveEmptyEntries); var rows = lines.Length; diff --git a/2024/Advent/UseCases/Day6/Day6Part1Solver.cs b/2024/Advent/UseCases/Day6/Day6Part1Solver.cs index 21fa288..6e5d305 100644 --- a/2024/Advent/UseCases/Day6/Day6Part1Solver.cs +++ b/2024/Advent/UseCases/Day6/Day6Part1Solver.cs @@ -4,11 +4,25 @@ namespace Advent.UseCases.Day6; -public class Day6Part1Solver : IDay6Solver +internal class Day6Part1Solver : IDay6Solver { private GridCell _currentPosition; private Direction _currentDirection; + public int Solve(GridData input) + { + Stopwatch sw = new(); + sw.Start(); + _currentPosition = input.Find('^'); + _currentDirection = Direction.North; + MarkAsVisited(input); + Move(input); + var count = input.Count('X'); + sw.Stop(); // Average 2.75 ms + AnsiConsole.WriteLine($"Elapsed time: {sw.Elapsed.TotalMilliseconds} ms"); + return count; + } + private void MarkAsVisited(GridData data) { data[_currentPosition.Row, _currentPosition.Column] = 'X'; @@ -28,18 +42,4 @@ private void Move(GridData data) MarkAsVisited(data); } } - - public int Solve(GridData input) - { - Stopwatch sw = new(); - sw.Start(); - _currentPosition = input.Find('^'); - _currentDirection = Direction.North; - MarkAsVisited(input); - Move(input); - var count = input.Count('X'); - sw.Stop(); // Average 2.75 ms - AnsiConsole.WriteLine($"Elapsed time: {sw.Elapsed.TotalMilliseconds} ms"); - return count; - } } diff --git a/2024/Advent/UseCases/Day6/Day6Part2Solver.cs b/2024/Advent/UseCases/Day6/Day6Part2Solver.cs index 966c6f6..0040e2c 100644 --- a/2024/Advent/UseCases/Day6/Day6Part2Solver.cs +++ b/2024/Advent/UseCases/Day6/Day6Part2Solver.cs @@ -4,13 +4,25 @@ namespace Advent.UseCases.Day6; -public class Day6Part2Solver : IDay6Solver +internal class Day6Part2Solver : IDay6Solver { private GridCell _startingPosition; private Direction _startingDirection; private int _infiniteLoopCount; private readonly HashSet<(GridCell, Direction)> _turnHistory = []; + public int Solve(GridData input) + { + Stopwatch sw = new(); + sw.Start(); + _startingPosition = input.Find('^'); + _startingDirection = Direction.North; + Move(input); + sw.Stop(); + AnsiConsole.WriteLine($"Elapsed time: {sw.Elapsed.TotalMilliseconds} ms"); + return _infiniteLoopCount; + } + private void Move(GridData data) { // Start at the beginning mark the valid path taken with X's @@ -52,16 +64,4 @@ Direction currentDirection } } } - - public int Solve(GridData input) - { - Stopwatch sw = new(); - sw.Start(); - _startingPosition = input.Find('^'); - _startingDirection = Direction.North; - Move(input); - sw.Stop(); - AnsiConsole.WriteLine($"Elapsed time: {sw.Elapsed.TotalMilliseconds} ms"); - return _infiniteLoopCount; - } } diff --git a/2024/Advent/UseCases/Day6/IDay6Solver.cs b/2024/Advent/UseCases/Day6/IDay6Solver.cs index 24d4925..1c5f40f 100644 --- a/2024/Advent/UseCases/Day6/IDay6Solver.cs +++ b/2024/Advent/UseCases/Day6/IDay6Solver.cs @@ -1,9 +1,8 @@ using Advent.Common; -namespace Advent.UseCases.Day6 +namespace Advent.UseCases.Day6; + +internal interface IDay6Solver { - public interface IDay6Solver - { - int Solve(GridData input); - } + int Solve(GridData input); } diff --git a/2024/Advent/UseCases/Day7/Day7Parser.cs b/2024/Advent/UseCases/Day7/Day7Parser.cs index 60a2f1a..06ed9e9 100644 --- a/2024/Advent/UseCases/Day7/Day7Parser.cs +++ b/2024/Advent/UseCases/Day7/Day7Parser.cs @@ -1,8 +1,8 @@ namespace Advent.UseCases.Day7; -public static class Day7Parser +internal static class Day7Parser { - public static (ulong, uint[])[] Parse(string input) + internal static (ulong, uint[])[] Parse(string input) { var lines = input.Split('\n', StringSplitOptions.RemoveEmptyEntries); (ulong, uint[])[] result = new (ulong, uint[])[lines.Length]; diff --git a/2024/Advent/UseCases/Day7/Day7Part1Solver.cs b/2024/Advent/UseCases/Day7/Day7Part1Solver.cs index 5428ca6..9f9175f 100644 --- a/2024/Advent/UseCases/Day7/Day7Part1Solver.cs +++ b/2024/Advent/UseCases/Day7/Day7Part1Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day7; -public class Day7Part1Solver : IDay7Solver +internal class Day7Part1Solver : IDay7Solver { /// /// Solve the equations and return the sum of the valid results diff --git a/2024/Advent/UseCases/Day7/Day7Part2Solver.cs b/2024/Advent/UseCases/Day7/Day7Part2Solver.cs index 40f6161..22687df 100644 --- a/2024/Advent/UseCases/Day7/Day7Part2Solver.cs +++ b/2024/Advent/UseCases/Day7/Day7Part2Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day7; -public class Day7Part2Solver : IDay7Solver +internal class Day7Part2Solver : IDay7Solver { public ulong Solve((ulong, uint[])[] input) { diff --git a/2024/Advent/UseCases/Day7/IDay7Solver.cs b/2024/Advent/UseCases/Day7/IDay7Solver.cs index 76a8032..a4142b9 100644 --- a/2024/Advent/UseCases/Day7/IDay7Solver.cs +++ b/2024/Advent/UseCases/Day7/IDay7Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day7; -public interface IDay7Solver +internal interface IDay7Solver { ulong Solve((ulong, uint[])[] input); } diff --git a/2024/Advent/UseCases/Day8/Day8Part1Solver.cs b/2024/Advent/UseCases/Day8/Day8Part1Solver.cs index 50a1663..418e851 100644 --- a/2024/Advent/UseCases/Day8/Day8Part1Solver.cs +++ b/2024/Advent/UseCases/Day8/Day8Part1Solver.cs @@ -1,77 +1,76 @@ using Advent.Common; using Advent.UseCases.Day6; -namespace Advent.UseCases.Day8 +namespace Advent.UseCases.Day8; + +internal class Day8Part1Solver : IDay6Solver { - public class Day8Part1Solver : IDay6Solver + public int Solve(GridData input) { - public int Solve(GridData input) + var copyOfGrid = input; + var uniqueSignals = input.GetUniqueChars(['.']); + HashSet overlapNodes = []; + foreach (var signal in uniqueSignals) { - var copyOfGrid = input; - var uniqueSignals = input.GetUniqueChars(['.']); - HashSet overlapNodes = []; - foreach (var signal in uniqueSignals) - { - var antennaLocations = input.FindAll(signal); - PlaceAntiNodes(copyOfGrid, antennaLocations, overlapNodes); - } - var count = copyOfGrid.Count('#'); - count += overlapNodes.Count; - return count; + var antennaLocations = input.FindAll(signal); + PlaceAntiNodes(copyOfGrid, antennaLocations, overlapNodes); } + var count = copyOfGrid.Count('#'); + count += overlapNodes.Count; + return count; + } - private static void PlaceAntiNodes( - GridData copyOfGrid, - IEnumerable antennaLocations, - HashSet overlapNodes - ) + private static void PlaceAntiNodes( + GridData copyOfGrid, + IEnumerable antennaLocations, + HashSet overlapNodes + ) + { + for (var i = 0; i < antennaLocations.Count(); i++) { - for (var i = 0; i < antennaLocations.Count(); i++) + var location = antennaLocations.ElementAt(i); + for (var j = 0; j < antennaLocations.Count(); j++) { - var location = antennaLocations.ElementAt(i); - for (var j = 0; j < antennaLocations.Count(); j++) - { - var otherLocation = antennaLocations.ElementAt(j); + var otherLocation = antennaLocations.ElementAt(j); - if (location == otherLocation) - continue; + if (location == otherLocation) + continue; - var nodes = GetAntennasDifference(location, otherLocation); - var node1 = GetNewLocation(location, nodes[1]); - var node2 = GetNewLocation(otherLocation, nodes[0]); - ReplaceWithAnitNode(copyOfGrid, overlapNodes, node1); - ReplaceWithAnitNode(copyOfGrid, overlapNodes, node2); - } + var nodes = GetAntennasDifference(location, otherLocation); + var node1 = GetNewLocation(location, nodes[1]); + var node2 = GetNewLocation(otherLocation, nodes[0]); + ReplaceWithAnitNode(copyOfGrid, overlapNodes, node1); + ReplaceWithAnitNode(copyOfGrid, overlapNodes, node2); } } + } - private static GridCell GetNewLocation(GridCell location, GridCell node) - { - return new(location.Row + node.Row, location.Column + node.Column); - } + private static GridCell GetNewLocation(GridCell location, GridCell node) + { + return new(location.Row + node.Row, location.Column + node.Column); + } - private static void ReplaceWithAnitNode( - GridData copyOfGrid, - HashSet overlapNodes, - GridCell node1 - ) + private static void ReplaceWithAnitNode( + GridData copyOfGrid, + HashSet overlapNodes, + GridCell node1 + ) + { + if (copyOfGrid.IsValid(node1)) { - if (copyOfGrid.IsValid(node1)) - { - if (copyOfGrid[node1] == '.' || copyOfGrid[node1] == '#') - copyOfGrid[node1] = '#'; - else - overlapNodes.Add(node1); - } + if (copyOfGrid[node1] == '.' || copyOfGrid[node1] == '#') + copyOfGrid[node1] = '#'; + else + overlapNodes.Add(node1); } + } - private static GridCell[] GetAntennasDifference(GridCell antenna1, GridCell antenna2) - { - return - [ - new GridCell(antenna2.Row - antenna1.Row, antenna2.Column - antenna1.Column), - new GridCell(antenna1.Row - antenna2.Row, antenna1.Column - antenna2.Column) - ]; - } + private static GridCell[] GetAntennasDifference(GridCell antenna1, GridCell antenna2) + { + return + [ + new GridCell(antenna2.Row - antenna1.Row, antenna2.Column - antenna1.Column), + new GridCell(antenna1.Row - antenna2.Row, antenna1.Column - antenna2.Column) + ]; } } diff --git a/2024/Advent/UseCases/Day8/Day8Part2Solver.cs b/2024/Advent/UseCases/Day8/Day8Part2Solver.cs index 6336fac..06f479d 100644 --- a/2024/Advent/UseCases/Day8/Day8Part2Solver.cs +++ b/2024/Advent/UseCases/Day8/Day8Part2Solver.cs @@ -1,88 +1,87 @@ using Advent.Common; using Advent.UseCases.Day6; -namespace Advent.UseCases.Day8 +namespace Advent.UseCases.Day8; + +internal class Day8Part2Solver : IDay6Solver { - public class Day8Part2Solver : IDay6Solver + public int Solve(GridData input) { - public int Solve(GridData input) + var copyOfGrid = input; + var uniqueSignals = input.GetUniqueChars(['.']); + HashSet overlapNodes = []; + foreach (var signal in uniqueSignals) { - var copyOfGrid = input; - var uniqueSignals = input.GetUniqueChars(['.']); - HashSet overlapNodes = []; - foreach (var signal in uniqueSignals) - { - var antennaLocations = input.FindAll(signal); - PlaceAntiNodes(copyOfGrid, antennaLocations, overlapNodes); - } - var count = copyOfGrid.Count('#'); - count += overlapNodes.Count; - return count; + var antennaLocations = input.FindAll(signal); + PlaceAntiNodes(copyOfGrid, antennaLocations, overlapNodes); } + var count = copyOfGrid.Count('#'); + count += overlapNodes.Count; + return count; + } - private static void PlaceAntiNodes( - GridData copyOfGrid, - IEnumerable antennaLocations, - HashSet overlapNodes - ) + private static void PlaceAntiNodes( + GridData copyOfGrid, + IEnumerable antennaLocations, + HashSet overlapNodes + ) + { + for (var i = 0; i < antennaLocations.Count(); i++) { - for (var i = 0; i < antennaLocations.Count(); i++) + var location = antennaLocations.ElementAt(i); + for (var j = 0; j < antennaLocations.Count(); j++) { - var location = antennaLocations.ElementAt(i); - for (var j = 0; j < antennaLocations.Count(); j++) - { - var otherLocation = antennaLocations.ElementAt(j); + var otherLocation = antennaLocations.ElementAt(j); - if (location == otherLocation) - continue; + if (location == otherLocation) + continue; - overlapNodes.Add(location); - overlapNodes.Add(otherLocation); - var nodes = GetAntennasDifference(location, otherLocation); - var node1 = GetNewLocation(location, nodes[1]); - while (copyOfGrid.IsValid(node1)) - { - ReplaceWithAnitNode(copyOfGrid, overlapNodes, node1); - node1 = GetNewLocation(node1, nodes[1]); - } + overlapNodes.Add(location); + overlapNodes.Add(otherLocation); + var nodes = GetAntennasDifference(location, otherLocation); + var node1 = GetNewLocation(location, nodes[1]); + while (copyOfGrid.IsValid(node1)) + { + ReplaceWithAnitNode(copyOfGrid, overlapNodes, node1); + node1 = GetNewLocation(node1, nodes[1]); + } - var node2 = GetNewLocation(otherLocation, nodes[0]); - while (copyOfGrid.IsValid(node2)) - { - ReplaceWithAnitNode(copyOfGrid, overlapNodes, node2); - node2 = GetNewLocation(node2, nodes[0]); - } + var node2 = GetNewLocation(otherLocation, nodes[0]); + while (copyOfGrid.IsValid(node2)) + { + ReplaceWithAnitNode(copyOfGrid, overlapNodes, node2); + node2 = GetNewLocation(node2, nodes[0]); } } } + } - private static GridCell GetNewLocation(GridCell location, GridCell node) - { - return new(location.Row + node.Row, location.Column + node.Column); - } + private static GridCell GetNewLocation(GridCell location, GridCell node) + { + return new(location.Row + node.Row, location.Column + node.Column); + } - private static void ReplaceWithAnitNode( - GridData copyOfGrid, - HashSet overlapNodes, - GridCell node1 - ) + private static void ReplaceWithAnitNode( + GridData copyOfGrid, + HashSet overlapNodes, + GridCell node1 + ) + { + if (copyOfGrid.IsValid(node1)) { - if (copyOfGrid.IsValid(node1)) - { - if (copyOfGrid[node1] == '.' || copyOfGrid[node1] == '#') - copyOfGrid[node1] = '#'; - else - overlapNodes.Add(node1); - } + if (copyOfGrid[node1] == '.' || copyOfGrid[node1] == '#') + copyOfGrid[node1] = '#'; + else + overlapNodes.Add(node1); } + } - private static GridCell[] GetAntennasDifference(GridCell antenna1, GridCell antenna2) - { - return - [ - new GridCell(antenna2.Row - antenna1.Row, antenna2.Column - antenna1.Column), - new GridCell(antenna1.Row - antenna2.Row, antenna1.Column - antenna2.Column) - ]; - } + private static GridCell[] GetAntennasDifference(GridCell antenna1, GridCell antenna2) + { + return + [ + new GridCell(antenna2.Row - antenna1.Row, antenna2.Column - antenna1.Column), + new GridCell(antenna1.Row - antenna2.Row, antenna1.Column - antenna2.Column) + ]; } } diff --git a/2024/Advent/UseCases/Day9/Day9Parser.cs b/2024/Advent/UseCases/Day9/Day9Parser.cs index fa7bab0..f518df1 100644 --- a/2024/Advent/UseCases/Day9/Day9Parser.cs +++ b/2024/Advent/UseCases/Day9/Day9Parser.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day9; -public class Day9Parser +internal static class Day9Parser { enum State { @@ -8,12 +8,11 @@ enum State FreeSpace, } - private State _state = State.FileLength; - private uint _fileId = 0; - private readonly List _result = []; - - public Span Parse(string input) + internal static Span Parse(string input) { + State _state = State.FileLength; + uint _fileId = 0; + List _result = []; if (string.IsNullOrWhiteSpace(input)) { throw new InvalidOperationException("Invalid input"); @@ -23,47 +22,62 @@ public Span Parse(string input) foreach (var line in lines) { - ProcessLine(line); + ProcessLine(line, ref _state, ref _fileId, ref _result); } return _result.ToArray(); } - private void ProcessLine(string line) + private static void ProcessLine( + string line, + ref State _state, + ref uint _fileId, + ref List _result + ) { foreach (var c in line) { - ProcessCharacter(c); + ProcessCharacter(c, ref _state, ref _fileId, ref _result); } } - private void ProcessCharacter(char c) + private static void ProcessCharacter( + char c, + ref State _state, + ref uint _fileId, + ref List _result + ) { var digit = int.Parse(c.ToString()); switch (_state) { case State.FileLength: { - HandleFile(digit); + HandleFile(digit, ref _state, ref _fileId, ref _result); return; } case State.FreeSpace: { - HandleFreeSpace(digit); + HandleFreeSpace(digit, ref _state, ref _result); return; } } } - private void HandleFreeSpace(int digit) + private static void HandleFreeSpace(int digit, ref State _state, ref List _result) { if (digit != 0) { - AddPositionsForFileId(digit, uint.MaxValue); + AddPositionsForFileId(digit, uint.MaxValue, ref _result); } _state = State.FileLength; } - private void HandleFile(int digit) + private static void HandleFile( + int digit, + ref State _state, + ref uint _fileId, + ref List _result + ) { if (digit == 0) { @@ -71,13 +85,13 @@ private void HandleFile(int digit) } else { - AddPositionsForFileId(digit, _fileId); + AddPositionsForFileId(digit, _fileId, ref _result); } _fileId++; _state = State.FreeSpace; } - private void AddPositionsForFileId(int digit, uint fileId) + private static void AddPositionsForFileId(int digit, uint fileId, ref List _result) { for (int i = 0; i < digit; i++) { diff --git a/2024/Advent/UseCases/Day9/Day9Part1Solver.cs b/2024/Advent/UseCases/Day9/Day9Part1Solver.cs index 92fb8e8..3c853c2 100644 --- a/2024/Advent/UseCases/Day9/Day9Part1Solver.cs +++ b/2024/Advent/UseCases/Day9/Day9Part1Solver.cs @@ -4,7 +4,7 @@ namespace Advent.UseCases.Day9; -public class Day9Part1Solver : IDay9Solver +internal class Day9Part1Solver : IDay9Solver { public ulong Solve(Span input) { diff --git a/2024/Advent/UseCases/Day9/Day9Part2Solver.cs b/2024/Advent/UseCases/Day9/Day9Part2Solver.cs index b212e37..7b354c1 100644 --- a/2024/Advent/UseCases/Day9/Day9Part2Solver.cs +++ b/2024/Advent/UseCases/Day9/Day9Part2Solver.cs @@ -3,7 +3,7 @@ namespace Advent.UseCases.Day9; -public class Day9Part2Solver : IDay9Solver +internal class Day9Part2Solver : IDay9Solver { /// /// This is a bit slower than the first part, but still performs well ~700ms diff --git a/2024/Advent/UseCases/Day9/IDay9Solver.cs b/2024/Advent/UseCases/Day9/IDay9Solver.cs index b1f03f9..348f198 100644 --- a/2024/Advent/UseCases/Day9/IDay9Solver.cs +++ b/2024/Advent/UseCases/Day9/IDay9Solver.cs @@ -1,6 +1,6 @@ namespace Advent.UseCases.Day9; -public interface IDay9Solver +internal interface IDay9Solver { ulong Solve(Span input); } diff --git a/2024/input/day25input.txt b/2024/input/day25input.txt new file mode 100644 index 0000000..eb1ad77 --- /dev/null +++ b/2024/input/day25input.txt @@ -0,0 +1,3999 @@ +##### +#.### +..### +...#. +..... +..... +..... + +..... +..... +..#.. +..#.. +..##. +#.### +##### + +..... +..... +..... +...#. +.#.#. +.###. +##### + +..... +.#... +.#... +.#... +.#.#. +####. +##### + +..... +#.... +#.... +#.... +#...# +#.#.# +##### + +..... +...#. +#.##. +#.### +##### +##### +##### + +##### +##.## +#..## +#...# +#...# +#.... +..... + +..... +...#. +..##. +..##. +#.##. +####. +##### + +..... +#.... +#.... +#.... +#..#. +##.#. +##### + +..... +.#... +.#... +.#.#. +.#### +##### +##### + +..... +..... +....# +....# +.#..# +.#.## +##### + +..... +.#..# +.#..# +.#..# +.##.# +.##.# +##### + +##### +##### +###.# +#.#.# +..... +..... +..... + +##### +##### +.###. +..##. +...#. +..... +..... + +..... +..#.. +#.#.# +#.#.# +#.#.# +#.### +##### + +##### +##.## +##.## +##..# +##..# +#...# +..... + +##### +###.# +###.# +#.#.. +..... +..... +..... + +..... +....# +...## +..### +#.### +#.### +##### + +##### +##### +#.#.# +#.#.# +..#.# +..... +..... + +##### +##.#. +##.#. +#.... +#.... +#.... +..... + +##### +###.# +##..# +##... +.#... +..... +..... + +..... +#.... +#.... +##.#. +##.#. +##.#. +##### + +##### +##### +#.### +#.### +..### +..#.# +..... + +..... +...#. +..##. +..##. +#.##. +#.### +##### + +..... +#..#. +#.### +#.### +##### +##### +##### + +##### +##.## +##.## +#..## +....# +....# +..... + +##### +.#### +.#### +.#### +.#### +..#.# +..... + +..... +#.... +#.#.. +#.#.. +#.##. +#.##. +##### + +..... +..... +..... +#.... +#..#. +#.### +##### + +..... +#...# +#.#.# +#.#.# +#.#.# +#.#.# +##### + +##### +##### +####. +####. +.#.#. +.#.#. +..... + +..... +..... +#..#. +#.##. +#.##. +#.### +##### + +##### +###.# +.##.# +.##.. +.##.. +..#.. +..... + +..... +.#... +.#.#. +####. +##### +##### +##### + +##### +##.## +##.## +#..#. +#..#. +...#. +..... + +##### +####. +###.. +###.. +.#... +.#... +..... + +..... +....# +#...# +#...# +##.## +##### +##### + +..... +#...# +#.#.# +###.# +##### +##### +##### + +##### +####. +.#.#. +.#.#. +.#.#. +...#. +..... + +..... +..#.. +..#.. +#.#.# +#.#.# +#.#.# +##### + +..... +..... +#..#. +#..#. +#.##. +#.### +##### + +##### +###.# +###.. +.##.. +.#... +.#... +..... + +..... +....# +..#.# +..### +.#### +##### +##### + +..... +..#.. +#.#.. +#.#.# +#.#.# +#.#.# +##### + +..... +..#.# +..#.# +..#.# +#.### +##### +##### + +..... +..#.. +..#.# +#.#.# +##### +##### +##### + +##### +##.## +##..# +##..# +.#..# +.#... +..... + +##### +####. +.###. +.#.#. +.#.#. +..... +..... + +..... +..... +..#.# +.##.# +.#### +##### +##### + +..... +..#.. +..##. +.###. +####. +##### +##### + +..... +#.#.. +###.# +###.# +##### +##### +##### + +##### +##.## +##.## +.#.#. +.#.#. +...#. +..... + +##### +##### +###.# +###.# +###.# +#.#.. +..... + +##### +##### +.#.## +...## +...#. +..... +..... + +##### +####. +.###. +..#.. +..... +..... +..... + +..... +....# +#...# +#..## +##.## +##.## +##### + +##### +.##.# +.##.# +..#.. +..... +..... +..... + +##### +##### +##.## +##..# +.#..# +....# +..... + +##### +##### +##.## +##..# +##..# +#.... +..... + +..... +..... +.#... +.#.#. +##.#. +####. +##### + +..... +..... +#.... +##..# +##.## +##### +##### + +##### +##### +###.# +.#..# +.#..# +.#... +..... + +..... +..... +....# +..#.# +#.#.# +#.#.# +##### + +..... +..... +.#... +.##.. +###.. +####. +##### + +##### +##.## +##.## +#...# +....# +..... +..... + +..... +...#. +...#. +..##. +..### +.#### +##### + +..... +..#.. +..#.. +..#.# +.##.# +##### +##### + +##### +##### +#.### +..### +...#. +..... +..... + +##### +##### +#.### +#.### +#..## +....# +..... + +..... +#.... +#.... +#...# +#.#.# +##### +##### + +..... +...#. +...#. +.#.#. +.#### +.#### +##### + +..... +#...# +#..## +#..## +#..## +#.### +##### + +..... +..... +..#.. +..#.. +..#.# +.##.# +##### + +##### +#.### +#.#.# +#...# +#.... +..... +..... + +##### +##### +##### +#.##. +#.#.. +#.... +..... + +##### +##.## +.#.## +...## +....# +....# +..... + +..... +..... +..#.. +#.##. +#.##. +####. +##### + +##### +.#### +..### +..#.# +..... +..... +..... + +##### +##.## +##.#. +##.#. +#..#. +#.... +..... + +##### +##### +##### +.##.# +..#.# +..... +..... + +..... +..... +...#. +#.##. +#.### +##### +##### + +##### +##### +##### +.#.## +...## +...#. +..... + +..... +..#.. +..##. +..##. +.#### +.#### +##### + +..... +..... +...#. +...#. +...#. +.#.#. +##### + +##### +##### +.#.## +.#.## +...#. +...#. +..... + +##### +##### +##.## +##.#. +##.#. +#..#. +..... + +##### +##### +###.# +.##.# +.##.# +..#.. +..... + +##### +.#### +.#.## +...## +....# +..... +..... + +##### +#.### +#.### +#.### +..#.# +....# +..... + +..... +#..#. +#..#. +##.## +##.## +##### +##### + +##### +##.## +.#.## +....# +..... +..... +..... + +..... +..... +....# +.#..# +.#..# +###.# +##### + +##### +##### +.##.# +.#..# +.#..# +.#... +..... + +..... +....# +#.#.# +#.#.# +#.#.# +#.### +##### + +..... +.#.#. +.#.#. +.#.#. +####. +##### +##### + +..... +..#.# +.##.# +.#### +.#### +.#### +##### + +..... +.#..# +.#..# +##..# +##.## +##.## +##### + +##### +.#.## +.#.#. +...#. +..... +..... +..... + +##### +.##.# +.##.# +.##.# +..#.. +..#.. +..... + +##### +##### +###.# +##..# +##... +#.... +..... + +..... +..... +.#... +.#... +##..# +##.## +##### + +..... +..... +...#. +..##. +..##. +.#### +##### + +..... +....# +....# +.#..# +.#.## +##### +##### + +##### +#.### +..### +..### +...#. +..... +..... + +..... +.#... +.#... +.##.# +###.# +##### +##### + +##### +##### +##### +#.### +#.##. +..#.. +..... + +##### +##### +.#.#. +.#... +.#... +..... +..... + +##### +##### +##.## +##..# +##..# +#...# +..... + +..... +.#..# +.#.## +.#### +.#### +##### +##### + +##### +####. +####. +#.##. +..#.. +..... +..... + +##### +###.# +.#..# +.#..# +..... +..... +..... + +##### +####. +.###. +.##.. +.##.. +..#.. +..... + +..... +....# +....# +...## +.#.## +.#.## +##### + +..... +..... +..#.# +.##.# +.##.# +###.# +##### + +##### +#.### +#..#. +#..#. +...#. +...#. +..... + +..... +.#..# +.#.## +##.## +##.## +##.## +##### + +##### +##### +####. +##.#. +#..#. +#..#. +..... + +..... +.#... +.#.#. +.###. +.###. +####. +##### + +..... +..... +#.... +#.#.# +#.#.# +#.### +##### + +..... +....# +....# +#...# +#.#.# +#.### +##### + +##### +####. +#.#.. +#.#.. +#.#.. +..#.. +..... + +..... +..#.. +#.#.# +#.#.# +#.#.# +##### +##### + +..... +..... +...#. +#..#. +##.#. +####. +##### + +..... +.#.#. +.#.#. +.#.#. +.###. +.###. +##### + +..... +..#.. +..#.# +..#.# +..#.# +.##.# +##### + +##### +##### +##### +##.## +##..# +#.... +..... + +..... +..#.. +..#.. +#.##. +####. +####. +##### + +##### +.##.# +.##.# +..#.# +..#.. +..#.. +..... + +##### +####. +##.#. +##.#. +.#... +..... +..... + +..... +...#. +..##. +#.##. +#.### +#.### +##### + +..... +#...# +#..## +#..## +##.## +##### +##### + +##### +#.### +#.### +#..## +...#. +..... +..... + +##### +.#### +..### +..### +...## +...#. +..... + +##### +#.#.# +#.#.# +#...# +#...# +#...# +..... + +##### +.###. +.##.. +..#.. +..... +..... +..... + +##### +#.### +#..## +...## +....# +..... +..... + +##### +#.#.# +#.#.# +#.#.# +..... +..... +..... + +##### +#.### +#.### +#.#.# +..#.. +..#.. +..... + +..... +...#. +#..#. +##.## +##.## +##.## +##### + +##### +#.### +#.### +#.### +..##. +..#.. +..... + +..... +...#. +..### +..### +.#### +.#### +##### + +##### +##### +##.#. +##.#. +#..#. +...#. +..... + +..... +.#... +##... +##..# +###.# +##### +##### + +..... +..#.. +..#.. +..##. +#.##. +#.### +##### + +##### +##### +.#.## +.#..# +.#... +..... +..... + +##### +.#.## +.#..# +.#... +.#... +.#... +..... + +##### +.##.# +.##.# +.#..# +.#..# +..... +..... + +##### +#.### +#.### +#.### +#.##. +#..#. +..... + +..... +..... +..#.. +..#.. +..##. +.#### +##### + +..... +..#.. +.##.. +.###. +.###. +.###. +##### + +..... +..... +.#.#. +.###. +##### +##### +##### + +..... +..#.. +#.#.. +####. +####. +####. +##### + +##### +####. +#.#.. +#.... +#.... +#.... +..... + +..... +#.... +##... +##... +##.#. +####. +##### + +..... +.#... +.#.#. +.#.#. +##.## +##.## +##### + +..... +..#.. +..#.# +..### +#.### +#.### +##### + +##### +##### +##### +#.#.# +#.... +..... +..... + +..... +..... +#.#.. +#.##. +#.### +#.### +##### + +##### +###.# +###.. +###.. +###.. +.#... +..... + +##### +##.## +##.## +#..## +#...# +....# +..... + +##### +.#### +.#.## +.#..# +.#..# +.#..# +..... + +..... +..... +.#..# +.#..# +.##.# +.#### +##### + +##### +####. +##.#. +#..#. +#.... +#.... +..... + +##### +##.## +##.#. +.#.#. +.#... +..... +..... + +##### +#.#.# +..#.# +..#.# +..#.# +..... +..... + +##### +#.### +#.#.# +#.#.. +#.#.. +#.... +..... + +..... +.#... +.#... +.#... +.##.. +####. +##### + +##### +.#### +.###. +..##. +..#.. +..#.. +..... + +..... +..... +....# +.#.## +##.## +##.## +##### + +##### +##### +####. +#.##. +..#.. +..#.. +..... + +..... +..... +..#.. +.##.# +.#### +.#### +##### + +##### +#.### +#.##. +#.##. +#..#. +..... +..... + +..... +#.... +#.... +##.#. +##.#. +####. +##### + +##### +#.### +#..#. +#..#. +#.... +..... +..... + +##### +###.# +.##.# +..#.. +..#.. +..#.. +..... + +##### +##### +##.## +##..# +#...# +#...# +..... + +..... +.#... +.#..# +.##.# +.#### +##### +##### + +..... +....# +#...# +#..## +#..## +##.## +##### + +##### +##### +##.## +##..# +.#..# +..... +..... + +..... +#..#. +##.#. +##.#. +##.## +##.## +##### + +##### +###.# +###.. +.##.. +..#.. +..#.. +..... + +##### +##### +##.## +.#..# +.#... +..... +..... + +..... +..#.. +..#.. +.##.. +###.. +####. +##### + +..... +#.#.. +#.#.. +#.#.. +###.# +###.# +##### + +..... +#.... +#.... +#.#.. +#.#.# +#.### +##### + +..... +#.... +#..#. +##.## +##### +##### +##### + +..... +.#..# +.#..# +.#..# +.##.# +##### +##### + +..... +.#.#. +##.## +##.## +##### +##### +##### + +..... +....# +.#.## +.#.## +.#### +.#### +##### + +..... +....# +....# +.#..# +.##.# +###.# +##### + +##### +##### +##### +.##.# +.#..# +.#..# +..... + +..... +..... +..#.. +#.#.. +###.# +###.# +##### + +##### +####. +.#.#. +...#. +..... +..... +..... + +##### +#.#.# +#.#.# +..#.. +..... +..... +..... + +..... +.#... +.##.. +.###. +.###. +####. +##### + +..... +..... +..#.. +..##. +.###. +.#### +##### + +##### +#.#.# +....# +....# +....# +..... +..... + +..... +..... +..... +#..#. +#..#. +#.##. +##### + +##### +#.#.# +#.#.# +#.#.# +#.#.. +#.#.. +..... + +##### +.##.# +.##.. +.##.. +.##.. +.#... +..... + +..... +.#... +.#... +.#... +###.. +####. +##### + +..... +...#. +...#. +.#.#. +##### +##### +##### + +##### +###.# +###.# +###.# +##... +#.... +..... + +##### +####. +.##.. +.##.. +..#.. +..... +..... + +..... +..... +.#... +##... +##... +##.#. +##### + +..... +..#.. +..#.. +..##. +..##. +.#### +##### + +##### +#.### +#.### +#.##. +#.##. +#..#. +..... + +##### +#.### +#.##. +#..#. +#..#. +#.... +..... + +##### +###.# +##..# +#.... +..... +..... +..... + +..... +..... +..... +....# +..#.# +#.### +##### + +##### +##.## +##.## +.#..# +....# +..... +..... + +##### +##### +##### +#.### +#..## +...#. +..... + +##### +.##.# +..#.# +..#.# +..#.. +..#.. +..... + +##### +###.# +#.#.# +#.#.# +#.#.# +....# +..... + +..... +.#.#. +.#.#. +####. +##### +##### +##### + +..... +..... +..... +..... +.#..# +##.## +##### + +##### +##.## +##.#. +.#... +.#... +.#... +..... + +..... +#.#.. +#.#.. +#.#.. +####. +##### +##### + +##### +##### +.#### +..#.# +..#.# +....# +..... + +##### +##.## +#...# +#...# +#...# +#.... +..... + +..... +..... +....# +....# +#..## +##.## +##### + +..... +..... +.#... +.#.#. +##.#. +##### +##### + +##### +#.### +#.### +#.#.# +#.#.. +..... +..... + +##### +##.## +##.## +#...# +..... +..... +..... + +##### +.#### +..### +..### +..#.# +..... +..... + +..... +..#.. +..#.. +..#.# +.##.# +.#### +##### + +##### +.#.## +.#.#. +.#.#. +.#.#. +..... +..... + +..... +#.... +#.... +#.#.. +#.#.# +##### +##### + +##### +#.### +#.#.# +#.#.# +#.#.# +....# +..... + +##### +#.### +#.#.# +#.#.# +#.#.# +#.#.. +..... + +..... +.#... +.#... +.#... +.#.#. +.#.## +##### + +..... +...#. +...#. +#..## +##.## +##### +##### + +..... +#.... +#.... +#...# +#...# +##.## +##### + +##### +##### +####. +####. +.#.#. +..... +..... + +..... +..... +#...# +#...# +#..## +##.## +##### + +..... +..#.. +#.#.. +#.#.. +####. +####. +##### + +..... +#.... +##... +###.. +###.. +###.# +##### + +..... +...#. +.#.#. +.#.## +.#.## +.#.## +##### + +##### +###.# +###.# +#.#.# +#.... +..... +..... + +##### +##### +##### +##### +.##.# +.#... +..... + +..... +..... +#.#.. +#.##. +#.### +##### +##### + +..... +..... +..... +.#... +.#.#. +####. +##### + +..... +..... +...#. +...#. +...#. +.#.## +##### + +..... +.#.#. +.#.#. +.#.#. +.###. +####. +##### + +..... +..... +...#. +#.##. +#.##. +##### +##### + +##### +.#### +.#### +.#.## +....# +....# +..... + +##### +##### +#.### +#.#.# +..#.. +..#.. +..... + +##### +####. +#.##. +#.#.. +#.... +..... +..... + +..... +....# +#.#.# +#.#.# +###.# +###.# +##### + +..... +..#.. +..#.. +.###. +####. +####. +##### + +..... +....# +#.#.# +#.#.# +#.#.# +#.#.# +##### + +..... +..... +..#.. +..#.. +..##. +.###. +##### + +##### +####. +##.#. +.#... +.#... +..... +..... + +##### +##.## +.#.#. +...#. +...#. +...#. +..... + +..... +..... +..... +#.... +##.#. +##### +##### + +..... +...#. +..### +#.### +#.### +##### +##### + +##### +##.## +##..# +##..# +##... +#.... +..... + +##### +###.# +###.# +###.# +.#..# +.#... +..... + +##### +#.### +#.#.# +#...# +#...# +..... +..... + +..... +.#... +.#..# +.#..# +.#..# +.##.# +##### + +##### +##### +##### +##### +#.#.# +#...# +..... + +##### +##.## +.#.## +.#.#. +.#... +.#... +..... + +##### +##### +##.## +#..## +#..## +...#. +..... + +##### +##.## +##.## +#..#. +#.... +#.... +..... + +##### +##### +.#### +.###. +.###. +..#.. +..... + +##### +##.## +##..# +##..# +.#..# +.#..# +..... + +##### +##### +##### +#.#.# +#.#.# +#.... +..... + +##### +.#### +.#### +.#### +.##.# +.#... +..... + +..... +..#.. +.###. +.###. +.###. +.###. +##### + +..... +..... +#.#.. +###.. +####. +##### +##### + +..... +.#.#. +.#.#. +.#.#. +.#.#. +.#.## +##### + +..... +...#. +..### +.#### +##### +##### +##### + +##### +##.#. +##.#. +##.#. +#.... +#.... +..... + +..... +.#... +.#... +.#... +.#... +.##.# +##### + +..... +..... +....# +..#.# +#.#.# +##### +##### + +..... +#.... +##... +##.#. +##.## +##### +##### + +..... +..... +#...# +##..# +##.## +##### +##### + +##### +.#### +.#### +.#.## +.#.#. +.#.#. +..... + +..... +.#.#. +.#.#. +##.#. +##### +##### +##### + +##### +##### +##### +#.##. +..#.. +..... +..... + +##### +####. +.###. +.###. +.#.#. +.#... +..... + +##### +##.## +##.#. +##.#. +#..#. +..... +..... + +##### +.#### +.##.# +..#.# +..#.# +..#.. +..... + +##### +#.#.# +#.#.# +#.#.# +#...# +#...# +..... + +##### +##### +.#### +.#.## +.#.#. +..... +..... + +..... +.#.#. +.#.## +##.## +##### +##### +##### + +##### +##### +.#.## +.#.## +...## +....# +..... + +..... +..#.. +..#.. +.###. +####. +##### +##### + +..... +..#.. +..##. +..##. +#.##. +#.### +##### + +..... +..#.. +..#.. +..#.. +#.#.# +###.# +##### + +##### +####. +#.##. +#..#. +#.... +..... +..... + +##### +##### +###.# +.#..# +....# +..... +..... + +..... +..... +#.... +##..# +###.# +###.# +##### + +##### +#.### +#.##. +#..#. +...#. +...#. +..... + +##### +####. +#.#.. +..#.. +..#.. +..#.. +..... + +##### +.#### +.#### +.###. +.#.#. +...#. +..... + +##### +#.### +#..## +#...# +#...# +..... +..... + +..... +..... +....# +..#.# +.##.# +###.# +##### + +##### +##### +##### +.##.# +..#.# +....# +..... + +..... +..... +..... +.#.#. +.#.## +##### +##### + +##### +##### +#.##. +#.##. +#..#. +#..#. +..... + +..... +..... +....# +....# +.#.## +##.## +##### + +..... +..#.. +.##.. +.##.. +.##.# +###.# +##### + +..... +..... +..... +..#.. +#.#.# +##### +##### + +..... +...#. +...## +...## +#..## +#.### +##### + +..... +...#. +...#. +...#. +..##. +#.### +##### + +..... +..... +...#. +#..#. +##.#. +##.## +##### + +..... +#.... +#.... +##..# +##.## +##.## +##### + +##### +.#### +.#### +.##.# +.#..# +.#... +..... + +..... +#.... +##.#. +##.#. +##.#. +##.## +##### + +..... +.#... +.#... +.#... +###.# +###.# +##### + +##### +.#### +.#.## +.#..# +....# +....# +..... + +##### +.##.# +..#.# +..#.. +..#.. +..... +..... + +..... +#.#.. +#.#.. +#.##. +#.##. +#.##. +##### + +..... +..... +#...# +##.## +##### +##### +##### + +##### +##### +#.### +#.### +...## +....# +..... + +##### +##### +##### +##### +.#.#. +..... +..... + +..... +#.... +#.... +#.#.. +#.##. +####. +##### + +##### +##### +.#### +.#### +.#.## +.#..# +..... + +##### +#.### +#.##. +#.##. +#.#.. +#.... +..... + +..... +....# +.#..# +.#.## +.#### +.#### +##### + +##### +##### +#.### +#.### +..#.# +....# +..... + +..... +..#.# +..#.# +.##.# +.#### +.#### +##### + +..... +..... +..#.. +..#.. +.##.# +###.# +##### + +##### +###.# +##... +##... +##... +#.... +..... + +..... +..#.. +#.#.# +#.### +#.### +##### +##### + +..... +..... +..... +.#.#. +.#.## +.#### +##### + +..... +..... +..#.. +..#.. +#.#.# +#.### +##### + +##### +##### +##.## +.#.## +.#.#. +.#... +..... + +##### +##.## +##.#. +##... +.#... +..... +..... + +##### +#.### +#.#.# +....# +..... +..... +..... + +##### +###.# +##..# +##..# +##..# +.#... +..... + +..... +..#.. +..#.. +..#.# +..### +#.### +##### + +##### +##### +#.### +#..## +#..## +....# +..... + +..... +..... +.#... +.#..# +.#.## +.#### +##### + +##### +#.### +#.### +#.### +#.#.# +..#.. +..... + +..... +.#... +.#.#. +.#.#. +.#.#. +.###. +##### + +..... +...#. +#..## +#..## +#..## +##.## +##### + +..... +..... +#.#.. +####. +##### +##### +##### + +..... +..... +..#.. +..##. +.###. +####. +##### + +..... +..... +.#... +.#.#. +.#.#. +####. +##### + +##### +###.# +###.# +.##.. +.##.. +..#.. +..... + +..... +#...# +#...# +#.#.# +#.#.# +##### +##### + +##### +.#### +.#### +..##. +..#.. +..... +..... + +##### +##.#. +.#.#. +.#.#. +...#. +..... +..... + +..... +..... +#.... +##..# +###.# +##### +##### + +##### +##### +#.##. +#.#.. +..#.. +..... +..... + +..... +..#.. +..#.# +.##.# +.##.# +.#### +##### + +##### +##### +.#.## +.#.## +.#.#. +.#... +..... + +##### +###.# +##... +.#... +..... +..... +..... + +..... +#.... +#.#.. +###.. +###.# +##### +##### + +##### +##.## +#..## +#..## +#..## +...#. +..... + +##### +####. +##.#. +#..#. +#.... +..... +..... + +##### +##### +##### +##### +#.#.# +....# +..... + +..... +..#.. +#.#.# +#.#.# +#.### +#.### +##### + +##### +###.# +###.# +###.# +##..# +#.... +..... + +..... +#.... +#.... +#.#.. +###.# +##### +##### + +..... +.#..# +.#..# +.##.# +.#### +##### +##### + +##### +##### +#.### +#.### +#..#. +..... +..... + +..... +....# +..#.# +.##.# +###.# +##### +##### + +##### +#.##. +#.#.. +#.... +#.... +#.... +..... + +##### +###.# +#.#.# +..#.# +..... +..... +..... + +..... +#.... +##... +##... +##... +###.# +##### + +##### +###.# +###.# +#.#.# +..#.. +..... +..... + +##### +#.#.# +..#.# +..#.. +..... +..... +..... + +##### +####. +####. +###.. +###.. +#.#.. +..... + +..... +..... +..#.. +#.#.. +###.. +####. +##### + +..... +..... +..... +.#.#. +##.## +##.## +##### + +##### +##### +##### +#.#.# +..#.# +....# +..... + +##### +##.## +.#.#. +.#.#. +.#.#. +.#... +..... + +##### +##.## +.#.## +.#..# +.#..# +....# +..... + +..... +..... +#.... +#.#.. +###.. +###.# +##### + +##### +##### +.#.#. +.#.#. +...#. +...#. +..... + +##### +##### +####. +####. +##.#. +.#... +..... + +..... +..... +...#. +.#.#. +.#.#. +.###. +##### + +..... +..#.. +..#.. +.##.# +.##.# +.##.# +##### + +##### +###.# +.##.# +..#.# +..#.. +..#.. +..... + +..... +#.#.. +#.##. +#.### +#.### +##### +##### + +##### +#.##. +#.##. +#.##. +#..#. +...#. +..... + +##### +####. +.##.. +.##.. +.##.. +.#... +..... + +##### +##### +.###. +..##. +...#. +...#. +..... + +##### +##.## +##.## +#..#. +#..#. +#.... +..... + +..... +..... +..#.. +..#.. +#.##. +##### +##### + +..... +..... +...#. +#..## +#..## +##.## +##### + +##### +####. +##.#. +#..#. +...#. +...#. +..... + +##### +##### +.#### +.#.#. +.#... +.#... +..... + +##### +####. +##.#. +##... +#.... +#.... +..... + +##### +##### +###.# +###.# +###.. +#.#.. +..... + +..... +...#. +#..#. +##.## +##.## +##### +##### + +##### +##### +###.# +.#..# +..... +..... +..... + +##### +####. +.###. +..##. +..#.. +..... +..... + +##### +.#### +.#.## +.#.## +...#. +...#. +..... + +##### +.#### +.#.## +.#.## +.#..# +.#... +..... + +..... +.#... +.#..# +.##.# +###.# +###.# +##### + +##### +##### +##### +##.## +#..#. +...#. +..... + +##### +#.### +#.### +#.### +..##. +...#. +..... + +##### +###.# +.#... +.#... +..... +..... +..... + +##### +.#### +.#.## +.#.## +....# +..... +..... + +##### +##### +#.### +#.### +#.##. +..#.. +..... + +##### +##### +##### +##### +#.#.# +#.#.. +..... + +##### +####. +.#.#. +.#.#. +.#... +.#... +..... + +..... +..... +.#... +###.. +###.# +##### +##### + +##### +#.### +#.### +#.#.# +#.#.# +....# +..... + +..... +...#. +...#. +..##. +..##. +.#### +##### + +..... +..... +#...# +#...# +#...# +##.## +##### + +..... +..#.. +#.#.. +#.##. +#.##. +##### +##### + +..... +.#... +.#.#. +.#.#. +.#.## +.#.## +##### + +..... +.#... +.#... +###.. +###.# +##### +##### + +##### +##### +.##.# +.##.. +.##.. +..#.. +..... + +##### +##### +#.### +#..## +#..#. +#.... +..... + +..... +#.#.. +#.#.. +#.##. +####. +####. +##### + +..... +..... +.#... +.#..# +.#..# +##.## +##### + +##### +####. +####. +#.##. +#..#. +#..#. +..... + +##### +##.## +##.## +##.## +.#.#. +.#.#. +..... + +##### +.###. +.###. +.###. +..#.. +..... +..... + +..... +...#. +...## +#..## +#.### +##### +##### + +..... +..#.# +.##.# +.##.# +###.# +###.# +##### + +##### +##### +###.# +#.#.# +#.#.# +#.... +..... + +..... +.#..# +.#..# +.#..# +.#.## +.#### +##### + +##### +##### +####. +.###. +.##.. +..#.. +..... + +..... +..... +#.... +#.#.. +#.#.. +#.##. +##### + +..... +..... +..... +.#... +.##.. +.##.# +##### + +..... +..... +.#..# +.#.## +##### +##### +##### + +..... +#..#. +##.#. +##.#. +##.#. +##.## +##### + +..... +....# +..#.# +#.### +##### +##### +##### + +..... +.#... +.#..# +###.# +###.# +###.# +##### + +..... +...#. +...#. +.#.#. +##.#. +##### +##### + +##### +##.## +##.## +##.#. +##.#. +.#... +..... + +..... +..... +..... +.#.#. +##.#. +##.#. +##### + +##### +###.# +.#..# +....# +....# +..... +..... + +##### +##### +.###. +.##.. +.##.. +..#.. +..... + +..... +.#... +.#.#. +.#.#. +.#### +##### +##### + +..... +#.... +#.... +#...# +##.## +##.## +##### + +##### +##.## +.#.## +.#.## +.#.#. +.#.#. +..... + +..... +#.#.. +#.#.# +#.#.# +#.### +##### +##### + +##### +##### +#.#.# +....# +..... +..... +..... + +..... +..... +#.... +#..#. +#.##. +#.### +##### + +..... +.#... +##..# +###.# +##### +##### +##### + +##### +.#### +.#### +.###. +.##.. +..#.. +..... + +..... +...#. +#.##. +####. +##### +##### +##### + +##### +##### +##### +####. +#.#.. +..#.. +..... + +##### +##### +.#.## +.#.## +....# +....# +..... + +##### +##### +#.### +..### +..#.# +..#.# +..... + +..... +#..#. +#..#. +#.##. +#.##. +####. +##### + +..... +..... +..#.. +.##.. +.##.# +###.# +##### + +##### +##.## +##.## +##.## +##..# +.#... +..... + +##### +.#### +.#### +.###. +.###. +.#.#. +..... + +..... +..#.# +..#.# +..#.# +..### +.#### +##### + +..... +..#.# +..#.# +#.### +#.### +#.### +##### + +##### +##.## +.#.## +.#..# +.#... +..... +..... + +##### +##### +####. +#.##. +#..#. +...#. +..... + +##### +###.# +##..# +##..# +.#..# +.#..# +..... + +##### +##.## +#..## +#...# +....# +....# +..... + +##### +.#.## +.#..# +.#..# +....# +..... +..... + +..... +#..#. +#..#. +#..#. +##.#. +##.## +##### + +..... +.#... +.#.#. +.#.## +.#### +.#### +##### + +##### +##### +####. +.###. +.###. +..#.. +..... + +##### +####. +####. +####. +#.##. +#.#.. +..... + +##### +##### +##.#. +##.#. +##.#. +#..#. +..... + +##### +.#.## +.#.#. +.#.#. +.#.#. +.#... +..... + +##### +####. +.#.#. +.#.#. +.#.#. +.#.#. +..... + +..... +..... +..#.. +#.#.. +#.#.# +#.### +##### + +..... +#..#. +#..## +#..## +#.### +#.### +##### + +##### +#.### +#.### +..### +...#. +..... +..... + +..... +.#... +.##.. +####. +####. +##### +##### + +..... +#.#.. +#.##. +####. +####. +##### +##### + +..... +..... +...#. +.#.## +##### +##### +##### + +..... +#.#.. +#.#.# +###.# +###.# +###.# +##### + +##### +.#### +.#### +..### +..### +...#. +..... + +..... +..... +..... +.#..# +##.## +##.## +##### + +..... +..#.# +#.#.# +#.#.# +#.#.# +##### +##### + +##### +#.### +..##. +..##. +..##. +...#. +..... + +..... +#.... +#.... +#.... +#..#. +#.##. +##### + +..... +...#. +...#. +.#.#. +.#.#. +####. +##### + +..... +..... +.#... +.#... +.##.# +.#### +##### + +..... +.#.#. +##.#. +####. +####. +##### +##### + +..... +.#.#. +.#.#. +##.#. +##.#. +##### +##### + +##### +##### +####. +####. +.###. +..#.. +..... + +..... +..... +.#... +.#..# +.##.# +##### +##### + +..... +...#. +...## +#..## +#..## +##.## +##### + +..... +.#..# +.#..# +.#.## +.#.## +##.## +##### + +..... +...#. +...#. +#..## +##.## +##.## +##### + +##### +#.### +#.#.# +#...# +..... +..... +..... + +..... +.#... +.#..# +.##.# +.#### +.#### +##### + +..... +..#.. +..#.. +.##.. +.###. +.###. +##### + +..... +.#... +.#... +.#... +##... +##.#. +##### + +##### +#.##. +#.#.. +#.#.. +#.#.. +..#.. +..... + +..... +..... +..#.. +#.##. +#.### +#.### +##### + +##### +##.#. +#..#. +#..#. +#..#. +...#. +..... + +##### +###.# +##..# +.#..# +.#... +..... +..... + +##### +#.##. +#.##. +..#.. +..#.. +..#.. +..... + +##### +.#### +.#### +.#.## +.#.#. +..... +..... + +..... +#...# +#..## +##.## +##.## +##### +##### + +..... +..... +..... +...#. +.#.#. +.#.## +##### + +##### +#.#.# +#.#.# +#.#.. +#.#.. +#.#.. +..... + +##### +.#### +.#### +..### +..#.# +..#.# +..... + +..... +...#. +...#. +..### +#.### +##### +##### + +..... +....# +.#.## +.#.## +.#.## +##### +##### + +..... +.#... +##... +##..# +##..# +###.# +##### + +##### +###.# +###.. +.##.. +..#.. +..... +.....