diff --git a/10/PipeMaze.Tests/GlobalUsings.cs b/10/PipeMaze.Tests/GlobalUsings.cs index 2d5b473..d6f0167 100644 --- a/10/PipeMaze.Tests/GlobalUsings.cs +++ b/10/PipeMaze.Tests/GlobalUsings.cs @@ -1,3 +1,3 @@ global using FluentAssertions; -global using Xunit; +global using Xunit; \ No newline at end of file diff --git a/10/PipeMaze.Tests/MazeTests.cs b/10/PipeMaze.Tests/MazeTests.cs index 30e6f0c..87caba6 100644 --- a/10/PipeMaze.Tests/MazeTests.cs +++ b/10/PipeMaze.Tests/MazeTests.cs @@ -8,8 +8,14 @@ public class MazeTests public void Parse_WhenGivenInput_ItShouldReturnExpectedMaze(string[] input, Maze expectedMaze, Pipe? expectedStartingPipe) { var maze = Maze.Parse(input); - maze.Should().BeEquivalentTo(expectedMaze); - maze.StartingPipe.Should().BeEquivalentTo(expectedStartingPipe); + + maze + .Should() + .BeEquivalentTo(expectedMaze); + + maze.StartingPipe + .Should() + .BeEquivalentTo(expectedStartingPipe); } [Theory] @@ -45,8 +51,9 @@ public class MazeTests [MemberData(nameof(TestData.AreaTestData), MemberType = typeof(TestData))] public void Area_WhenGivenInput_ItShouldReturnExpectedArea(string[] input, int expectedArea) { - var maze = Maze.Parse(input); - maze.GetAreaOfLoop() + Maze + .Parse(input) + .GetAreaOfLoop() .Should() .Be(expectedArea); } diff --git a/10/PipeMaze/Program.cs b/10/PipeMaze/Program.cs index 0963e43..b85b6ff 100644 --- a/10/PipeMaze/Program.cs +++ b/10/PipeMaze/Program.cs @@ -43,7 +43,13 @@ public class Program } } - +/// +/// Represents a maze of pipes. +/// +/// The width of the maze. +/// The height of the maze. +/// The pipes in the maze. +/// An instance of . public class Maze( int width, int height, @@ -61,14 +67,29 @@ public class Maze( { 'S', PipeType.Unknown }, }; - public int Width { get; init; } = width; - public int Height { get; init; } = height; + private int Width { get; init; } = width; + private int Height { get; init; } = height; + + /// + /// Gets the pipes in the maze. + /// public List Pipes { get; init; } = pipes; + /// + /// Gets the starting pipe in the maze. + /// public Pipe? StartingPipe => Pipes.FirstOrDefault(p => p.Type is PipeType.Unknown); + /// + /// Gets the farthest step from the start. + /// + /// The farthest step from the start. public int GetFarthestStepFromStart() => GetLoop().Count / 2; + /// + /// Gets the area of the loop. + /// + /// The area of the loop. public int GetAreaOfLoop() { var count = 0; @@ -81,17 +102,24 @@ public class Maze( PipeType.UpAndLeft, }; + // Loop through each row for (var row = 0; row < Height; row++) { + // Loop through each column in the row for (var column = 0; column < Width; column++) { + // Check if a pipe in loop exists at the current coordinate var pipe = loop.FirstOrDefault(p => p.Coordinate.Column == column && p.Coordinate.Row == row); + // If a pipe does not exist at the current coordinate + // and we are inside the loop, increment the count if (pipe is null && areInsideLoop is true) { count++; } + // If a pipe exists at the current coordinate and the pipe is + // representative of a vertical boundary, toggle the areInsideLoop flag if ( pipe is not null && verticalBoundaries.Contains(pipe.Type) is true @@ -105,6 +133,10 @@ public class Maze( return count; } + /// + /// Gets the loop in the maze. + /// + /// The loop in the maze. public List GetLoop() { if (StartingPipe is null) @@ -138,6 +170,10 @@ public class Maze( return loop; } + /// + /// Identifies the type of the starting pipe. + /// + /// The type of the starting pipe. public PipeType IdentifyStartPipeType() { if (StartingPipe is null) @@ -201,6 +237,11 @@ public class Maze( return PipeType.Unknown; } + /// + /// Gets the connecting pipes of the provided pipe. + /// + /// The pipe to get the connecting pipes of. + /// The connecting pipes of the provided pipe. public List GetConnectingPipes(Pipe pipe) { var connectingPipes = new List(); @@ -208,6 +249,10 @@ public class Maze( var isNotOnFirstColumn = pipe.Coordinate.Column > 0; var isNotOnLastRow = pipe.Coordinate.Row < Height - 1; var isNotOnLastColumn = pipe.Coordinate.Column < Width - 1; + var nextRow = pipe.Coordinate.Row + 1; + var nextColumn = pipe.Coordinate.Column + 1; + var previousRow = pipe.Coordinate.Row - 1; + var previousColumn = pipe.Coordinate.Column - 1; switch (pipe.Type) { @@ -216,14 +261,22 @@ public class Maze( if (isNotOnFirstRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == previousRow + ) ); } if (isNotOnLastRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row + 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == nextRow + ) ); } @@ -234,14 +287,22 @@ public class Maze( if (isNotOnFirstColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == previousColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } if (isNotOnLastColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column + 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == nextColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } @@ -252,14 +313,22 @@ public class Maze( if (isNotOnFirstRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == previousRow + ) ); } if (isNotOnLastColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column + 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == nextColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } @@ -270,14 +339,22 @@ public class Maze( if (isNotOnFirstRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == previousRow + ) ); } if (isNotOnFirstColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == previousColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } @@ -288,14 +365,22 @@ public class Maze( if (isNotOnLastRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row + 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == nextRow + ) ); } if (isNotOnLastColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column + 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == nextColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } @@ -306,14 +391,22 @@ public class Maze( if (isNotOnLastRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row + 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == nextRow + ) ); } if (isNotOnFirstColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == previousColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } @@ -324,28 +417,44 @@ public class Maze( if (isNotOnFirstRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == previousRow + ) ); } if (isNotOnLastColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column + 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == nextColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } if (isNotOnLastRow) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row + 1) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == pipe.Coordinate.Column && + p.Coordinate.Row == nextRow + ) ); } if (isNotOnFirstColumn) { connectingPipes.Add( - Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && p.Coordinate.Row == pipe.Coordinate.Row) + Pipes.FirstOrDefault( + p => + p.Coordinate.Column == previousColumn && + p.Coordinate.Row == pipe.Coordinate.Row + ) ); } @@ -358,6 +467,11 @@ public class Maze( return connectingPipes; } + /// + /// Parses the provided input into a maze. + /// + /// The input to parse. + /// An instance of . public static Maze Parse(string[] input) { var width = input[0].Length; @@ -381,6 +495,14 @@ public class Maze( } } +/// +/// Represents a pipe in a maze. +/// +/// The symbol of the pipe. +/// The type of the pipe. +/// The row of the pipe. +/// The column of the pipe. +/// An instance of . public class Pipe( char symbol, PipeType type, @@ -388,25 +510,55 @@ public class Pipe( int column ) { + /// + /// Gets the symbol of the pipe. + /// public char Symbol { get; init; } = symbol; + + /// + /// Gets the type of the pipe. + /// public PipeType Type { get; init; } = type; + + /// + /// Gets the coordinate of the pipe. + /// public PipeCoordinate Coordinate { get; init; } = new(column, row); } +/// +/// Represents a coordinate of a pipe in a maze. +/// +/// The column of the pipe. +/// The row of the pipe. +/// An instance of . public class PipeCoordinate( int column, int row ) : IEquatable { + /// + /// Gets the column of the pipe. + /// public int Column { get; init; } = column; + + /// + /// Gets the row of the pipe. + /// public int Row { get; init; } = row; + /// + /// Determines whether the provided object is equal to the current object. + /// public bool Equals(PipeCoordinate? other) => other is not null && Column == other.Column && Row == other.Row; } +/// +/// Represents the type of a pipe in a maze. +/// public enum PipeType { UpAndDown, // Vertical Pipe