Guest User

Untitled

a guest
Dec 10th, 2023
90
0
189 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.83 KB | None | 0 0
  1.  
  2. namespace AdventOfCode2023.Days.Ten
  3. {
  4.     internal class Day10Task2 : IRunnable
  5.     {
  6.         private HashSet<(int, int)> _megaMapVisitedNodes = new HashSet<(int, int)>();
  7.  
  8.         public void Run()
  9.         {
  10.             var inputLines = File.ReadAllLines("Days/Ten/Day10ExampleInput3.txt");
  11.  
  12.             var megaMapReference = new ExpandingPipeMap(inputLines,false);
  13.  
  14.             var megaMap = new ExpandingPipeMap(inputLines);
  15.             megaMap.PrintMap("E:\\OneDrive\\Programming\\AdventOfCode2023\\AdventOfCode2023\\Days\\Ten\\expanded.txt");
  16.  
  17.             _megaMapVisitedNodes.Add((megaMap.XCoord, megaMap.YCoord));
  18.  
  19.             while (true)
  20.             {
  21.                 bool haveMoved = false;
  22.                 for (int i = 0; i < 4; i++)
  23.                 {
  24.                     if (megaMap.CanMove((Direction)i))
  25.                     {
  26.                         megaMap.Move((Direction)i);
  27.                         if (_megaMapVisitedNodes.Contains((megaMap.XCoord, megaMap.YCoord)))
  28.                         {
  29.                             megaMap.Move(GetOppositeDirection((Direction)i));
  30.                         }
  31.                         else
  32.                         {
  33.                             _megaMapVisitedNodes.Add((megaMap.XCoord, megaMap.YCoord));
  34.                             haveMoved = true;
  35.                         }
  36.                     }
  37.                 }
  38.  
  39.                 if (!haveMoved)
  40.                 {
  41.                     break;
  42.                 }
  43.             }
  44.  
  45.             var prisonNodes = new List<(int, int)>();
  46.  
  47.             for (int y = 0; y < megaMap.Map.Count; y++)
  48.             {
  49.                 for (int x = 0; x < megaMap.Map[y].Count; x++)
  50.                 {
  51.                     if (_megaMapVisitedNodes.Contains((x,y)) || (megaMapReference.Map[y][x] == '#'))
  52.                     {
  53.                         continue;
  54.                     }
  55.  
  56.                     megaMap.Map[y][x] = '#';
  57.  
  58.                     var canEscape = new EscapeArtist(megaMap.Map,_megaMapVisitedNodes).CanEscape(x, y);
  59.  
  60.                     if (!canEscape)
  61.                     {
  62.                         prisonNodes.Add((x,y));
  63.                     }
  64.  
  65.                 }
  66.             }
  67.  
  68.             foreach(var prisonNode in prisonNodes)
  69.             {
  70.                 megaMap.Map[prisonNode.Item2][prisonNode.Item1] = '0';
  71.             }
  72.  
  73.             megaMap.PrintMap("E:\\OneDrive\\Programming\\AdventOfCode2023\\AdventOfCode2023\\Days\\Ten\\result.txt");
  74.             Console.WriteLine(prisonNodes.Count);
  75.  
  76.         }
  77.  
  78.         public class EscapeArtist
  79.         {
  80.             List<List<char>> Map;
  81.             HashSet<(int, int)> LoopNodes;
  82.             HashSet<(int, int)> EscapeVistedNodes = new HashSet<(int, int)>();
  83.  
  84.             public EscapeArtist(List<List<char>> map, HashSet<(int, int)> loopNodes)
  85.             {
  86.                 Map = map;
  87.                 LoopNodes = loopNodes;
  88.             }
  89.  
  90.             public bool CanEscape(int x, int y)
  91.             {
  92.                 if (LoopNodes.Contains((x,y)) || EscapeVistedNodes.Contains((x, y)))
  93.                 {
  94.                     return false;
  95.                 }
  96.  
  97.                 EscapeVistedNodes.Add((x, y));
  98.  
  99.                 if (x == 0 || y == 0 || x == Map[y].Count-1 || y == Map.Count - 1)
  100.                 {
  101.                     return true;
  102.                 }                
  103.  
  104.                 if (y - 1 >= 0 && CanEscape(x, y-1))
  105.                 {
  106.                     return true;
  107.                 }
  108.  
  109.                 if (y + 1 < Map.Count && CanEscape(x, y+1))
  110.                 {
  111.                     return true;
  112.                 }
  113.  
  114.                 if (x - 1 >= 0 && CanEscape(x-1, y))
  115.                 {
  116.                     return true;
  117.                 }
  118.  
  119.                 if (x + 1 < Map[y].Count && CanEscape(x+1, y))
  120.                 {
  121.                     return true;
  122.                 }
  123.  
  124.                 return false;
  125.             }
  126.         }
  127.  
  128.         public class ExpandingPipeMap : PipeMap
  129.         {
  130.             public ExpandingPipeMap(string[] mapString, bool fillGaps = true) : base(mapString)
  131.             {
  132.                 DoubleMapDimensions(mapString);
  133.  
  134.                 if (fillGaps)
  135.                 {
  136.                     FillInGaps();                    
  137.                 }
  138.  
  139.                 FindStart();
  140.  
  141.             }
  142.  
  143.             private void DoubleMapDimensions(string[] mapString)
  144.             {
  145.                 var originalWidth = Map[0].Count;
  146.                 for (int i = 0; i < Map.Count; i++)
  147.                 {
  148.                     for (int j = 0; j < Map[i].Count; j++)
  149.                     {
  150.                         Map[i].Insert(j + 1, '#');
  151.                         j++;
  152.                     }
  153.                     var newLine = new List<char>();
  154.                     for (int k = 0; k < originalWidth * 2; k++)
  155.                     {
  156.                         newLine.Add('#');
  157.                     }
  158.  
  159.                     Map.Insert(i + 1, newLine);
  160.                     i++;
  161.                 }
  162.             }
  163.  
  164.             private void FillInGaps()
  165.             {
  166.                 for (int y = 0; y < Map.Count; y++)
  167.                 {
  168.                     for (int x = 0; x < Map[y].Count; x++)
  169.                     {
  170.                         if (Map[y][x] == '#')
  171.                         {
  172.                             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]))
  173.                             {
  174.                                 Map[y][x] = '|';
  175.                             }
  176.                             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]))
  177.                             {
  178.                                 Map[y][x] = '-';
  179.                             }
  180.                         }
  181.                     }
  182.                 }
  183.             }
  184.         }
  185.  
  186.         public class PipeMap
  187.         {
  188.             public int XCoord { get; private set; }
  189.             public int YCoord { get; private set; }
  190.             public char CurrentPipe { get { return Map[YCoord][XCoord]; } }
  191.  
  192.             public List<List<char>> Map { get; set; }
  193.  
  194.             public PipeMap(string[] mapString)
  195.             {
  196.                 Map = mapString.Select(s => s.ToCharArray().ToList()).ToList();
  197.  
  198.                 FindStart();
  199.             }
  200.  
  201.             protected void FindStart()
  202.             {
  203.                 for (int y = 0; y < Map.Count; y++)
  204.                 {
  205.                     for (int x = 0; x < Map[y].Count; x++)
  206.                     {
  207.                         if (Map[y][x] == 'S')
  208.                         {
  209.                             YCoord = y;
  210.                             XCoord = x;
  211.                         }
  212.                     }
  213.                 }
  214.             }
  215.  
  216.             public void Move(Direction direction)
  217.             {
  218.                 var adjacent = GetAdjacent(direction);
  219.  
  220.                 XCoord = adjacent.Item1;
  221.                 YCoord = adjacent.Item2;
  222.             }
  223.  
  224.             public bool CanMove(Direction direction)
  225.             {
  226.                 bool currentPositionAllow = CanMoveFromCoord(direction, XCoord, YCoord);
  227.  
  228.                 if (!currentPositionAllow) return false;
  229.  
  230.                 var adjacent = GetAdjacent(direction);
  231.  
  232.                 if (adjacent.Item3 != '.' && adjacent.Item3 != '#' && CanMoveFromCoord(GetOppositeDirection(direction), adjacent.Item1, adjacent.Item2))
  233.                 {
  234.                     return true;
  235.                 }
  236.  
  237.                 return false;
  238.             }
  239.  
  240.             private bool CanMoveFromCoord(Direction direction, int xCoord, int yCoord)
  241.             {
  242.                 switch (Map[yCoord][xCoord])
  243.                 {
  244.                     case '|':
  245.                         return direction == Direction.Up || direction == Direction.Down;
  246.                     case '-':
  247.                         return direction == Direction.Left || direction == Direction.Right;
  248.                     case 'L':
  249.                         return direction == Direction.Up || direction == Direction.Right;
  250.                     case 'J':
  251.                         return direction == Direction.Up || direction == Direction.Left;
  252.                     case '7':
  253.                         return direction == Direction.Left || direction == Direction.Down;
  254.                     case 'F':
  255.                         return direction == Direction.Right || direction == Direction.Down;
  256.                     case 'S':
  257.                         return true;
  258.                     case '.':
  259.                     default:
  260.                         throw new Exception("you dun fucked up");
  261.                 }
  262.             }
  263.  
  264.             private (int, int, char) GetAdjacent(Direction direction)
  265.             {
  266.                 var newXCoord = XCoord;
  267.                 var newYCoord = YCoord;
  268.  
  269.                 switch (direction)
  270.                 {
  271.                     case Direction.Up:
  272.                         newYCoord--;
  273.                         break;
  274.                     case Direction.Down:
  275.                         newYCoord++;
  276.                         break;
  277.                     case Direction.Left:
  278.                         newXCoord--;
  279.                         break;
  280.                     case Direction.Right:
  281.                         newXCoord++;
  282.                         break;
  283.                 }
  284.  
  285.                 return (newXCoord, newYCoord, Map[newYCoord][newXCoord]);
  286.             }
  287.  
  288.             public void PrintMap(string filePath)
  289.             {
  290.                 if (File.Exists(filePath))
  291.                 {
  292.                     File.Delete(filePath);
  293.                 }              
  294.  
  295.                 for (int y = 0; y < Map.Count; y++)
  296.                 {
  297.                     for (int x = 0; x < Map[y].Count; x++)
  298.                     {
  299.                         //Console.Write($" {Map[y][x]} ");
  300.                         File.AppendAllText(filePath, $" {Map[y][x]} ");
  301.                     }
  302.                     //Console.WriteLine();
  303.                     File.AppendAllText(filePath, Environment.NewLine);
  304.  
  305.                 }
  306.             }
  307.         }
  308.  
  309.         public enum Direction
  310.         {
  311.             Up, Right, Down, Left
  312.         }
  313.  
  314.         public static Direction GetOppositeDirection(Direction direction)
  315.         {
  316.             switch (direction)
  317.             {
  318.                 case Direction.Up:
  319.                     return Direction.Down;
  320.                 case Direction.Down:
  321.                     return Direction.Up;
  322.                 case Direction.Right:
  323.                     return Direction.Left;
  324.                 case Direction.Left:
  325.                     return Direction.Right;
  326.                 default: throw new Exception("You dun fucked up... again");
  327.             }
  328.         }
  329.     }
  330. }
  331.  
  332.  
Add Comment
Please, Sign In to add comment