Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace AdventOfCode2023.Days.Ten
- {
- internal class Day10Task2 : IRunnable
- {
- private HashSet<(int, int)> _megaMapVisitedNodes = new HashSet<(int, int)>();
- public void Run()
- {
- var inputLines = File.ReadAllLines("Days/Ten/Day10ExampleInput3.txt");
- var megaMapReference = new ExpandingPipeMap(inputLines,false);
- var megaMap = new ExpandingPipeMap(inputLines);
- megaMap.PrintMap("E:\\OneDrive\\Programming\\AdventOfCode2023\\AdventOfCode2023\\Days\\Ten\\expanded.txt");
- _megaMapVisitedNodes.Add((megaMap.XCoord, megaMap.YCoord));
- while (true)
- {
- bool haveMoved = false;
- for (int i = 0; i < 4; i++)
- {
- if (megaMap.CanMove((Direction)i))
- {
- megaMap.Move((Direction)i);
- if (_megaMapVisitedNodes.Contains((megaMap.XCoord, megaMap.YCoord)))
- {
- megaMap.Move(GetOppositeDirection((Direction)i));
- }
- else
- {
- _megaMapVisitedNodes.Add((megaMap.XCoord, megaMap.YCoord));
- haveMoved = true;
- }
- }
- }
- if (!haveMoved)
- {
- break;
- }
- }
- var prisonNodes = new List<(int, int)>();
- for (int y = 0; y < megaMap.Map.Count; y++)
- {
- for (int x = 0; x < megaMap.Map[y].Count; x++)
- {
- if (_megaMapVisitedNodes.Contains((x,y)) || (megaMapReference.Map[y][x] == '#'))
- {
- continue;
- }
- megaMap.Map[y][x] = '#';
- var canEscape = new EscapeArtist(megaMap.Map,_megaMapVisitedNodes).CanEscape(x, y);
- if (!canEscape)
- {
- prisonNodes.Add((x,y));
- }
- }
- }
- foreach(var prisonNode in prisonNodes)
- {
- megaMap.Map[prisonNode.Item2][prisonNode.Item1] = '0';
- }
- megaMap.PrintMap("E:\\OneDrive\\Programming\\AdventOfCode2023\\AdventOfCode2023\\Days\\Ten\\result.txt");
- Console.WriteLine(prisonNodes.Count);
- }
- public class EscapeArtist
- {
- List<List<char>> Map;
- HashSet<(int, int)> LoopNodes;
- HashSet<(int, int)> EscapeVistedNodes = new HashSet<(int, int)>();
- public EscapeArtist(List<List<char>> map, HashSet<(int, int)> loopNodes)
- {
- Map = map;
- LoopNodes = loopNodes;
- }
- public bool CanEscape(int x, int y)
- {
- if (LoopNodes.Contains((x,y)) || EscapeVistedNodes.Contains((x, y)))
- {
- return false;
- }
- EscapeVistedNodes.Add((x, y));
- if (x == 0 || y == 0 || x == Map[y].Count-1 || y == Map.Count - 1)
- {
- return true;
- }
- if (y - 1 >= 0 && CanEscape(x, y-1))
- {
- return true;
- }
- if (y + 1 < Map.Count && CanEscape(x, y+1))
- {
- return true;
- }
- if (x - 1 >= 0 && CanEscape(x-1, y))
- {
- return true;
- }
- if (x + 1 < Map[y].Count && CanEscape(x+1, y))
- {
- return true;
- }
- return false;
- }
- }
- public class ExpandingPipeMap : PipeMap
- {
- public ExpandingPipeMap(string[] mapString, bool fillGaps = true) : base(mapString)
- {
- DoubleMapDimensions(mapString);
- if (fillGaps)
- {
- FillInGaps();
- }
- FindStart();
- }
- private void DoubleMapDimensions(string[] mapString)
- {
- var originalWidth = Map[0].Count;
- for (int i = 0; i < Map.Count; i++)
- {
- for (int j = 0; j < Map[i].Count; j++)
- {
- Map[i].Insert(j + 1, '#');
- j++;
- }
- var newLine = new List<char>();
- for (int k = 0; k < originalWidth * 2; k++)
- {
- newLine.Add('#');
- }
- Map.Insert(i + 1, newLine);
- i++;
- }
- }
- private void FillInGaps()
- {
- for (int y = 0; y < Map.Count; y++)
- {
- for (int x = 0; x < Map[y].Count; x++)
- {
- if (Map[y][x] == '#')
- {
- if (y - 1 >= 0 && y + 1 < Map.Count && new char[] { '|', 'F', '7', 'S' }.Contains(Map[y - 1][x]) && new char[] { '|', 'L', 'J', 'S' }.Contains(Map[y + 1][x]))
- {
- Map[y][x] = '|';
- }
- else if (x - 1 >= 0 && x + 1 < Map[y].Count && new char[] { '-', 'F', 'L', 'S' }.Contains(Map[y][x - 1]) && new char[] { '-', '7', 'J', 'S' }.Contains(Map[y][x + 1]))
- {
- Map[y][x] = '-';
- }
- }
- }
- }
- }
- }
- public class PipeMap
- {
- public int XCoord { get; private set; }
- public int YCoord { get; private set; }
- public char CurrentPipe { get { return Map[YCoord][XCoord]; } }
- public List<List<char>> Map { get; set; }
- public PipeMap(string[] mapString)
- {
- Map = mapString.Select(s => s.ToCharArray().ToList()).ToList();
- FindStart();
- }
- protected void FindStart()
- {
- for (int y = 0; y < Map.Count; y++)
- {
- for (int x = 0; x < Map[y].Count; x++)
- {
- if (Map[y][x] == 'S')
- {
- YCoord = y;
- XCoord = x;
- }
- }
- }
- }
- public void Move(Direction direction)
- {
- var adjacent = GetAdjacent(direction);
- XCoord = adjacent.Item1;
- YCoord = adjacent.Item2;
- }
- public bool CanMove(Direction direction)
- {
- bool currentPositionAllow = CanMoveFromCoord(direction, XCoord, YCoord);
- if (!currentPositionAllow) return false;
- var adjacent = GetAdjacent(direction);
- if (adjacent.Item3 != '.' && adjacent.Item3 != '#' && CanMoveFromCoord(GetOppositeDirection(direction), adjacent.Item1, adjacent.Item2))
- {
- return true;
- }
- return false;
- }
- private bool CanMoveFromCoord(Direction direction, int xCoord, int yCoord)
- {
- switch (Map[yCoord][xCoord])
- {
- case '|':
- return direction == Direction.Up || direction == Direction.Down;
- case '-':
- return direction == Direction.Left || direction == Direction.Right;
- case 'L':
- return direction == Direction.Up || direction == Direction.Right;
- case 'J':
- return direction == Direction.Up || direction == Direction.Left;
- case '7':
- return direction == Direction.Left || direction == Direction.Down;
- case 'F':
- return direction == Direction.Right || direction == Direction.Down;
- case 'S':
- return true;
- case '.':
- default:
- throw new Exception("you dun fucked up");
- }
- }
- private (int, int, char) GetAdjacent(Direction direction)
- {
- var newXCoord = XCoord;
- var newYCoord = YCoord;
- switch (direction)
- {
- case Direction.Up:
- newYCoord--;
- break;
- case Direction.Down:
- newYCoord++;
- break;
- case Direction.Left:
- newXCoord--;
- break;
- case Direction.Right:
- newXCoord++;
- break;
- }
- return (newXCoord, newYCoord, Map[newYCoord][newXCoord]);
- }
- public void PrintMap(string filePath)
- {
- if (File.Exists(filePath))
- {
- File.Delete(filePath);
- }
- for (int y = 0; y < Map.Count; y++)
- {
- for (int x = 0; x < Map[y].Count; x++)
- {
- //Console.Write($" {Map[y][x]} ");
- File.AppendAllText(filePath, $" {Map[y][x]} ");
- }
- //Console.WriteLine();
- File.AppendAllText(filePath, Environment.NewLine);
- }
- }
- }
- public enum Direction
- {
- Up, Right, Down, Left
- }
- public static Direction GetOppositeDirection(Direction direction)
- {
- switch (direction)
- {
- case Direction.Up:
- return Direction.Down;
- case Direction.Down:
- return Direction.Up;
- case Direction.Right:
- return Direction.Left;
- case Direction.Left:
- return Direction.Right;
- default: throw new Exception("You dun fucked up... again");
- }
- }
- }
- }
Add Comment
Please, Sign In to add comment