feat: solve part 1
This commit is contained in:
@@ -0,0 +1,358 @@
|
|||||||
|
namespace PipeMaze.Tests;
|
||||||
|
|
||||||
|
public class MazeTests
|
||||||
|
{
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(TestData.ParseTestData), MemberType = typeof(TestData))]
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(TestData.IdentifyPipeTypeTestData), MemberType = typeof(TestData))]
|
||||||
|
public void IdentifyPipeType_WhenGivenInput_ItShouldReturnExpectedPipeType(Maze maze, PipeType expectedPipeType)
|
||||||
|
{
|
||||||
|
maze
|
||||||
|
.IdentifyStartPipeType()
|
||||||
|
.Should()
|
||||||
|
.Be(expectedPipeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(TestData.GetLoopTestData), MemberType = typeof(TestData))]
|
||||||
|
public void GetLoop_WhenGivenInput_ItShouldReturnExpectedLoop(Maze maze, List<Pipe> expectedLoop)
|
||||||
|
{
|
||||||
|
maze
|
||||||
|
.GetLoop()
|
||||||
|
.Should()
|
||||||
|
.BeEquivalentTo(expectedLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(TestData.FurthestStepFromStartTestData), MemberType = typeof(TestData))]
|
||||||
|
public void FurthestStepFromStart_WhenGivenInput_ItShouldReturnExpectedFurthestStepFromStart(Maze maze, int expectedFurthestStepFromStart)
|
||||||
|
{
|
||||||
|
maze.FarthestStepFromStart
|
||||||
|
.Should()
|
||||||
|
.Be(expectedFurthestStepFromStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestData
|
||||||
|
{
|
||||||
|
private static readonly string[] TestMazeInput =
|
||||||
|
{
|
||||||
|
".....",
|
||||||
|
".S-7.",
|
||||||
|
".|.|.",
|
||||||
|
".L-J.",
|
||||||
|
".....",
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Maze TestMaze =
|
||||||
|
new(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
new('S', PipeType.Unknown, 1, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 1, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 1),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 3),
|
||||||
|
new('L', PipeType.UpAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 3),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> FurthestStepFromStartTestData =>
|
||||||
|
new List<object[]>
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
TestMaze,
|
||||||
|
4
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Maze(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 0),
|
||||||
|
new('-', PipeType.UpAndRight, 0, 1),
|
||||||
|
new('F', PipeType.DownAndRight, 0, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 3),
|
||||||
|
new('-', PipeType.LeftAndRight, 0, 4),
|
||||||
|
|
||||||
|
new('F', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('J', PipeType.UpAndLeft, 1, 2),
|
||||||
|
new('|', PipeType.UpAndDown, 1, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 4),
|
||||||
|
|
||||||
|
new('S', PipeType.Unknown, 2, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 2, 1),
|
||||||
|
new('L', PipeType.UpAndRight, 2, 2),
|
||||||
|
new('L', PipeType.UpAndRight, 2, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 2, 4),
|
||||||
|
|
||||||
|
new('|', PipeType.UpAndDown, 3, 0),
|
||||||
|
new('F', PipeType.DownAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 3),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 4),
|
||||||
|
|
||||||
|
new('L', PipeType.UpAndRight, 4, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 1),
|
||||||
|
new('L', PipeType.UpAndRight, 4, 3),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 4),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
8,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> GetLoopTestData =>
|
||||||
|
new List<object[]>
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
TestMaze,
|
||||||
|
new List<Pipe>
|
||||||
|
{
|
||||||
|
new('S', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 1, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 1),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 3),
|
||||||
|
new('L', PipeType.UpAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 3),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Maze(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
new('-', PipeType.LeftAndRight, 0, 0),
|
||||||
|
new('L', PipeType.UpAndRight, 0, 1),
|
||||||
|
new('|', PipeType.UpAndDown, 0, 2),
|
||||||
|
new('F', PipeType.DownAndRight, 0, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 4),
|
||||||
|
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 0),
|
||||||
|
new('S', PipeType.Unknown, 1, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 1, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 1, 4),
|
||||||
|
|
||||||
|
new('L', PipeType.UpAndRight, 2, 0),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 1),
|
||||||
|
new('7', PipeType.DownAndLeft, 2, 2),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 4),
|
||||||
|
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 0),
|
||||||
|
new('L', PipeType.UpAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 3, 4),
|
||||||
|
|
||||||
|
new('L', PipeType.UpAndRight, 4, 0),
|
||||||
|
new('|', PipeType.UpAndDown, 4, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 4, 2),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 3),
|
||||||
|
new('F', PipeType.DownAndRight, 4, 4),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
new List<Pipe>
|
||||||
|
{
|
||||||
|
new('S', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 1, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 1),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 3),
|
||||||
|
new('L', PipeType.UpAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 3),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Maze(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
new('F', PipeType.DownAndRight, 0, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 3),
|
||||||
|
|
||||||
|
new('F', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('J', PipeType.UpAndLeft, 1, 2),
|
||||||
|
new('|', PipeType.UpAndDown, 1, 3),
|
||||||
|
|
||||||
|
new('S', PipeType.Unknown, 2, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 2, 1),
|
||||||
|
new('L', PipeType.UpAndRight, 2, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 2, 4),
|
||||||
|
|
||||||
|
new('|', PipeType.UpAndDown, 3, 0),
|
||||||
|
new('F', PipeType.DownAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 3),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 4),
|
||||||
|
|
||||||
|
new('L', PipeType.UpAndRight, 4, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 1),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
new List<Pipe>
|
||||||
|
{
|
||||||
|
new('F', PipeType.DownAndRight, 0, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 3),
|
||||||
|
|
||||||
|
new('F', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('J', PipeType.UpAndLeft, 1, 2),
|
||||||
|
new('|', PipeType.UpAndDown, 1, 3),
|
||||||
|
|
||||||
|
new('S', PipeType.DownAndRight, 2, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 2, 1),
|
||||||
|
new('L', PipeType.UpAndRight, 2, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 2, 4),
|
||||||
|
|
||||||
|
new('|', PipeType.UpAndDown, 3, 0),
|
||||||
|
new('F', PipeType.DownAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 3),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 4),
|
||||||
|
|
||||||
|
new('L', PipeType.UpAndRight, 4, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 1),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new Maze(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 0),
|
||||||
|
new('-', PipeType.UpAndRight, 0, 1),
|
||||||
|
new('F', PipeType.DownAndRight, 0, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 3),
|
||||||
|
new('-', PipeType.LeftAndRight, 0, 4),
|
||||||
|
|
||||||
|
new('F', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('J', PipeType.UpAndLeft, 1, 2),
|
||||||
|
new('|', PipeType.UpAndDown, 1, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 4),
|
||||||
|
|
||||||
|
new('S', PipeType.Unknown, 2, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 2, 1),
|
||||||
|
new('L', PipeType.UpAndRight, 2, 2),
|
||||||
|
new('L', PipeType.UpAndRight, 2, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 2, 4),
|
||||||
|
|
||||||
|
new('|', PipeType.UpAndDown, 3, 0),
|
||||||
|
new('F', PipeType.DownAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 3),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 4),
|
||||||
|
|
||||||
|
new('L', PipeType.UpAndRight, 4, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 1),
|
||||||
|
new('L', PipeType.UpAndRight, 4, 3),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 4),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
new List<Pipe>
|
||||||
|
{
|
||||||
|
new('F', PipeType.DownAndRight, 0, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 0, 3),
|
||||||
|
|
||||||
|
new('F', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('J', PipeType.UpAndLeft, 1, 2),
|
||||||
|
new('|', PipeType.UpAndDown, 1, 3),
|
||||||
|
|
||||||
|
new('S', PipeType.DownAndRight, 2, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 2, 1),
|
||||||
|
new('L', PipeType.UpAndRight, 2, 3),
|
||||||
|
new('7', PipeType.DownAndLeft, 2, 4),
|
||||||
|
|
||||||
|
new('|', PipeType.UpAndDown, 3, 0),
|
||||||
|
new('F', PipeType.DownAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 3),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 4),
|
||||||
|
|
||||||
|
new('L', PipeType.UpAndRight, 4, 0),
|
||||||
|
new('J', PipeType.UpAndLeft, 4, 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> IdentifyPipeTypeTestData =>
|
||||||
|
new List<object[]>
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
TestMaze,
|
||||||
|
PipeType.DownAndRight,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static IEnumerable<object?[]> ParseTestData =>
|
||||||
|
new List<object?[]>
|
||||||
|
{
|
||||||
|
new object?[]
|
||||||
|
{
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
".....",
|
||||||
|
".F-7.",
|
||||||
|
".|.|.",
|
||||||
|
".L-J.",
|
||||||
|
".....",
|
||||||
|
},
|
||||||
|
new Maze(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
new('F', PipeType.DownAndRight, 1, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 1, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 1),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 3),
|
||||||
|
new('L', PipeType.UpAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 3),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
null
|
||||||
|
},
|
||||||
|
new object?[]
|
||||||
|
{
|
||||||
|
TestMazeInput,
|
||||||
|
new Maze(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
[
|
||||||
|
new('S', PipeType.Unknown, 1, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 1, 2),
|
||||||
|
new('7', PipeType.DownAndLeft, 1, 3),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 1),
|
||||||
|
new('|', PipeType.UpAndDown, 2, 3),
|
||||||
|
new('L', PipeType.UpAndRight, 3, 1),
|
||||||
|
new('-', PipeType.LeftAndRight, 3, 2),
|
||||||
|
new('J', PipeType.UpAndLeft, 3, 3),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
new Pipe('S', PipeType.Unknown, 1, 1)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace PipeMaze.Tests;
|
|
||||||
|
|
||||||
public class UnitTest1
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void Test1()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+372
-2
@@ -1,2 +1,372 @@
|
|||||||
// See https://aka.ms/new-console-template for more information
|
using System.Diagnostics;
|
||||||
Console.WriteLine("Hello, World!");
|
|
||||||
|
namespace PipeMaze;
|
||||||
|
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static async Task<int> Main(string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length is 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Please provide a path to the input file.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(args[0]) is false)
|
||||||
|
{
|
||||||
|
Console.WriteLine("The provided file does not exist.");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
var input = await File.ReadAllLinesAsync(args[0]);
|
||||||
|
|
||||||
|
var stopwatch = new Stopwatch();
|
||||||
|
stopwatch.Start();
|
||||||
|
|
||||||
|
var result = Maze.Parse(input).FarthestStepFromStart;
|
||||||
|
|
||||||
|
stopwatch.Stop();
|
||||||
|
|
||||||
|
Console.WriteLine($"The farthest step from the starting pipe is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Maze(
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
List<Pipe> pipes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<char, PipeType> _pipes = new()
|
||||||
|
{
|
||||||
|
{ '|', PipeType.UpAndDown },
|
||||||
|
{ '-', PipeType.LeftAndRight },
|
||||||
|
{ 'L', PipeType.UpAndRight },
|
||||||
|
{ 'J', PipeType.UpAndLeft },
|
||||||
|
{ '7', PipeType.DownAndLeft },
|
||||||
|
{ 'F', PipeType.DownAndRight },
|
||||||
|
{ 'S', PipeType.Unknown },
|
||||||
|
};
|
||||||
|
|
||||||
|
public int Width { get; init; } = width;
|
||||||
|
public int Height { get; init; } = height;
|
||||||
|
public List<Pipe> Pipes { get; init; } = pipes;
|
||||||
|
|
||||||
|
public Pipe? StartingPipe => Pipes.FirstOrDefault(p => p.Type is PipeType.Unknown);
|
||||||
|
|
||||||
|
public int FarthestStepFromStart => GetLoop().Count / 2;
|
||||||
|
|
||||||
|
public List<Pipe> GetLoop()
|
||||||
|
{
|
||||||
|
if (StartingPipe is null)
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var loop = new List<Pipe>();
|
||||||
|
var startingPipeType = IdentifyStartPipeType();
|
||||||
|
var currentPipe = new Pipe(
|
||||||
|
StartingPipe.Symbol,
|
||||||
|
startingPipeType,
|
||||||
|
StartingPipe.Coordinate.Row,
|
||||||
|
StartingPipe.Coordinate.Column
|
||||||
|
);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
loop.Add(currentPipe);
|
||||||
|
|
||||||
|
var connectingPipes = GetConnectingPipes(currentPipe);
|
||||||
|
currentPipe = connectingPipes
|
||||||
|
.FirstOrDefault(
|
||||||
|
p =>
|
||||||
|
p is not null &&
|
||||||
|
loop.Any(pipe => pipe.Coordinate.Equals(p.Coordinate)) is false
|
||||||
|
);
|
||||||
|
|
||||||
|
} while (currentPipe?.Equals(StartingPipe) is false);
|
||||||
|
|
||||||
|
return loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PipeType IdentifyStartPipeType()
|
||||||
|
{
|
||||||
|
if (StartingPipe is null)
|
||||||
|
{
|
||||||
|
return PipeType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
var connectingPipes = GetConnectingPipes(StartingPipe);
|
||||||
|
var pipeAbove = connectingPipes.FirstOrDefault(p => p?.Coordinate.Row < StartingPipe.Coordinate.Row);
|
||||||
|
var pipeBelow = connectingPipes.FirstOrDefault(p => p?.Coordinate.Row > StartingPipe.Coordinate.Row);
|
||||||
|
var pipeToTheLeft = connectingPipes.FirstOrDefault(p => p?.Coordinate.Column < StartingPipe.Coordinate.Column);
|
||||||
|
var pipeToTheRight = connectingPipes.FirstOrDefault(p => p?.Coordinate.Column > StartingPipe.Coordinate.Column);
|
||||||
|
|
||||||
|
var isPipeAboveConnected = pipeAbove is not null &&
|
||||||
|
pipeAbove.Type is PipeType.UpAndDown or PipeType.DownAndRight or PipeType.DownAndLeft;
|
||||||
|
|
||||||
|
var isPipeBelowConnected = pipeBelow is not null &&
|
||||||
|
pipeBelow.Type is PipeType.UpAndDown or PipeType.UpAndRight or PipeType.UpAndLeft;
|
||||||
|
|
||||||
|
var isPipeToTheLeftConnected = pipeToTheLeft is not null &&
|
||||||
|
pipeToTheLeft.Type is PipeType.LeftAndRight or PipeType.DownAndRight or PipeType.UpAndRight;
|
||||||
|
|
||||||
|
var isPipeToTheRightConnected = pipeToTheRight is not null &&
|
||||||
|
pipeToTheRight.Type is PipeType.LeftAndRight or PipeType.DownAndLeft or PipeType.UpAndLeft;
|
||||||
|
|
||||||
|
if (isPipeAboveConnected && isPipeBelowConnected && isPipeToTheLeftConnected && isPipeToTheRightConnected)
|
||||||
|
{
|
||||||
|
return PipeType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPipeAboveConnected && isPipeBelowConnected)
|
||||||
|
{
|
||||||
|
return PipeType.UpAndDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPipeToTheLeftConnected && isPipeToTheRightConnected)
|
||||||
|
{
|
||||||
|
return PipeType.LeftAndRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPipeAboveConnected && isPipeToTheRightConnected)
|
||||||
|
{
|
||||||
|
return PipeType.UpAndRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPipeAboveConnected && isPipeToTheLeftConnected)
|
||||||
|
{
|
||||||
|
return PipeType.UpAndLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPipeBelowConnected && isPipeToTheRightConnected)
|
||||||
|
{
|
||||||
|
return PipeType.DownAndRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPipeBelowConnected && isPipeToTheLeftConnected)
|
||||||
|
{
|
||||||
|
return PipeType.DownAndLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PipeType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Pipe?> GetConnectingPipes(Pipe pipe)
|
||||||
|
{
|
||||||
|
var connectingPipes = new List<Pipe?>();
|
||||||
|
var isNotOnFirstRow = pipe.Coordinate.Row > 0;
|
||||||
|
var isNotOnFirstColumn = pipe.Coordinate.Column > 0;
|
||||||
|
var isNotOnLastRow = pipe.Coordinate.Row < Height - 1;
|
||||||
|
var isNotOnLastColumn = pipe.Coordinate.Column < Width - 1;
|
||||||
|
|
||||||
|
switch (pipe.Type)
|
||||||
|
{
|
||||||
|
case PipeType.UpAndDown:
|
||||||
|
{
|
||||||
|
if (isNotOnFirstRow)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotOnLastRow)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PipeType.LeftAndRight:
|
||||||
|
{
|
||||||
|
if (isNotOnFirstColumn)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PipeType.UpAndRight:
|
||||||
|
{
|
||||||
|
if (isNotOnFirstRow)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotOnLastColumn)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column + 1 && p.Coordinate.Row == pipe.Coordinate.Row)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PipeType.UpAndLeft:
|
||||||
|
{
|
||||||
|
if (isNotOnFirstRow)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotOnFirstColumn)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && p.Coordinate.Row == pipe.Coordinate.Row)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PipeType.DownAndRight:
|
||||||
|
{
|
||||||
|
if (isNotOnLastRow)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotOnLastColumn)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column + 1 && p.Coordinate.Row == pipe.Coordinate.Row)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PipeType.DownAndLeft:
|
||||||
|
{
|
||||||
|
if (isNotOnLastRow)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotOnFirstColumn)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && p.Coordinate.Row == pipe.Coordinate.Row)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PipeType.Unknown:
|
||||||
|
{
|
||||||
|
if (isNotOnFirstRow)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column && p.Coordinate.Row == pipe.Coordinate.Row - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotOnLastColumn)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column + 1 && 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotOnFirstColumn)
|
||||||
|
{
|
||||||
|
connectingPipes.Add(
|
||||||
|
Pipes.FirstOrDefault(p => p.Coordinate.Column == pipe.Coordinate.Column - 1 && p.Coordinate.Row == pipe.Coordinate.Row)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectingPipes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Maze Parse(string[] input)
|
||||||
|
{
|
||||||
|
var width = input[0].Length;
|
||||||
|
var height = input.Length;
|
||||||
|
var pipes = new List<Pipe>();
|
||||||
|
|
||||||
|
for (var row = 0; row < height; row++)
|
||||||
|
{
|
||||||
|
for (var column = 0; column < width; column++)
|
||||||
|
{
|
||||||
|
var symbol = input[row][column];
|
||||||
|
|
||||||
|
if (_pipes.TryGetValue(symbol, out PipeType value))
|
||||||
|
{
|
||||||
|
pipes.Add(new(symbol, value, row, column));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Maze(width, height, pipes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Pipe(
|
||||||
|
char symbol,
|
||||||
|
PipeType type,
|
||||||
|
int row,
|
||||||
|
int column
|
||||||
|
)
|
||||||
|
{
|
||||||
|
public char Symbol { get; init; } = symbol;
|
||||||
|
public PipeType Type { get; init; } = type;
|
||||||
|
public PipeCoordinate Coordinate { get; init; } = new(column, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PipeCoordinate(
|
||||||
|
int column,
|
||||||
|
int row
|
||||||
|
) : IEquatable<PipeCoordinate>
|
||||||
|
{
|
||||||
|
public int Column { get; init; } = column;
|
||||||
|
public int Row { get; init; } = row;
|
||||||
|
|
||||||
|
public bool Equals(PipeCoordinate? other) =>
|
||||||
|
other is not null &&
|
||||||
|
Column == other.Column &&
|
||||||
|
Row == other.Row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PipeType
|
||||||
|
{
|
||||||
|
UpAndDown, // Vertical Pipe
|
||||||
|
LeftAndRight, // Horizontal Pipe
|
||||||
|
UpAndRight, // North-East Pipe
|
||||||
|
UpAndLeft, // North-West Pipe
|
||||||
|
DownAndRight, // South-East Pipe
|
||||||
|
DownAndLeft, // South-West Pipe
|
||||||
|
Unknown, // Starting Pipe
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user