Example #1
0
        public override object Part2()
        {
            V2 pos      = V2.Zero;
            V2 waypoint = new V2(10, -1);

            foreach (var line in lines)
            {
                char   action = line[0];
                int    amount = int.Parse(line.Substring(1));
                double rad    = 0;

                switch (action)
                {
                case 'F':
                    pos += waypoint * amount;
                    break;

                case 'N':
                    waypoint += V2.Up * amount;
                    break;

                case 'S':
                    waypoint += V2.Down * amount;
                    break;

                case 'E':
                    waypoint += V2.Right * amount;
                    break;

                case 'W':
                    waypoint += V2.Left * amount;
                    break;

                case 'L':
                    rad      = -amount * Math.PI / 180;
                    waypoint = new V2(waypoint.x * (int)Math.Cos(rad) - waypoint.y * (int)Math.Sin(rad),
                                      waypoint.x * (int)Math.Sin(rad) + waypoint.y * (int)Math.Cos(rad));
                    break;

                case 'R':
                    rad      = amount * Math.PI / 180;
                    waypoint = new V2(waypoint.x * (int)Math.Cos(rad) - waypoint.y * (int)Math.Sin(rad),
                                      waypoint.x * (int)Math.Sin(rad) + waypoint.y * (int)Math.Cos(rad));
                    break;


                default:
                    throw new Exception("Unhandled char" + line);
                }
            }

            return(Math.Abs(pos.x) + Math.Abs(pos.y));
        }
Example #2
0
        int FindPath(Dictionary <V2, Node> map)
        {
            Heap <Node> open   = new(map.Count);
            V2          target = map.Last().Value.v;

            open.Add(map[V2.Zero]);
            map[V2.Zero].totalRisk = 0;
            int visitCount = 0;

            while (open.Count > 0)
            {
                Node next = open.RemoveFirst();
                next.visited = true;
                visitCount++;

                foreach (var dir in V2.Directions)
                {
                    if (map.TryGetValue(next.v + dir, out Node opt))
                    {
                        if (!opt.visited)
                        {
                            int thisRisk = next.totalRisk + opt.risk;
                            if (thisRisk < opt.totalRisk)
                            {
                                opt.totalRisk = thisRisk;

                                if (!open.Contains(opt))
                                {
                                    open.Add(opt);
                                }
                                else
                                {
                                    open.UpdateItem(opt);
                                }
                            }

                            if (opt.v == target)
                            {
                                return(opt.totalRisk);
                            }
                        }
                    }
                }
            }

            return(-1);
        }
Example #3
0
        public override object Part2()
        {
            for (int i = 0; i < 100; i++)
            {
                List <V2> list    = blackTiles.ToList();
                int       listLen = list.Count;

                for (int j = 0; j < listLen; j++)
                {
                    V2   tile = list[j];
                    V2[] dirs = EvenTile(tile) ? evenDirs : oddDirs;
                    foreach (V2 dir in dirs)
                    {
                        list.Add(tile + dir);
                    }
                }

                HashSet <V2> newTiles = new HashSet <V2>();
                HashSet <V2> toCheck  = new HashSet <V2>(list);

                foreach (V2 tile in toCheck)
                {
                    int count = 0;
                    if (EvenTile(tile))
                    {
                        count = evenDirs.Count(dir => blackTiles.Contains(tile + dir));
                    }
                    else
                    {
                        count = oddDirs.Count(dir => blackTiles.Contains(tile + dir));
                    }

                    if (blackTiles.Contains(tile) && count > 0 && count <= 2)
                    {
                        newTiles.Add(tile);
                    }
                    else if (!blackTiles.Contains(tile) && count == 2)
                    {
                        newTiles.Add(tile);
                    }
                }

                blackTiles = new HashSet <V2>(newTiles);
            }

            return(blackTiles.Count);
        }
Example #4
0
        int FindOverlaps(bool diagonals)
        {
            Dictionary <V2, int> map = new();
            Regex r = new Regex(@"(\d+)");

            foreach (var line in lines)
            {
                var matches = r.Matches(line);
                V2  v1      = new V2(int.Parse(matches[0].Value), int.Parse(matches[1].Value));
                V2  v2      = new V2(int.Parse(matches[2].Value), int.Parse(matches[3].Value));

                if (diagonals || v1.x == v2.x || v1.y == v2.y)
                {
                    V2 dir    = new V2(Math.Sign(v2.x - v1.x), Math.Sign(v2.y - v1.y));
                    V2 target = v1;

                    while (target != v2)
                    {
                        if (!map.ContainsKey(target))
                        {
                            map.Add(target, 0);
                        }

                        map[target]++;
                        target += dir;
                    }

                    if (!map.ContainsKey(v2))
                    {
                        map.Add(v2, 0);
                    }

                    map[v2]++;
                }
            }


            return(map.Values.Count(x => x > 1));
        }
Example #5
0
        int getSlope(V2 slope)
        {
            int len = lines[0].Length;

            var pos   = new V2(0, 0);
            int trees = 0;

            while (pos.y < lines.Length)
            {
                if (map[pos])
                {
                    trees++;
                }

                pos += slope;
                if (pos.x >= len)
                {
                    pos.x -= len;
                }
            }

            return(trees);
        }
Example #6
0
        public override object Part1()
        {
            V2 v = new V2();

            for (int i = 0; i < lines.Length; i++)
            {
                string[] temp = lines[i].Split(' ');
                if (temp[0] == "forward")
                {
                    v += V2.Right * int.Parse(temp[1]);
                }
                if (temp[0] == "up")
                {
                    v += V2.Up * int.Parse(temp[1]);
                }
                if (temp[0] == "down")
                {
                    v += V2.Down * int.Parse(temp[1]);
                }
            }

            return(v.x * v.y);
        }
Example #7
0
 public Node(V2 v, int risk)
 {
     this.v    = v;
     this.risk = risk;
 }
Example #8
0
        public override string Part1()
        {
            var input  = File.ReadAllLines("Input/24.txt").Select(line => line.ToCharArray()).ToArray();
            var map    = new Dictionary <V2, char>();
            var newMap = new Dictionary <V2, char>();
            var states = new HashSet <string>();

            for (int y = 0; y < 5; y++)
            {
                for (int x = 0; x < 5; x++)
                {
                    map[new V2(x, y)] = input[y][x];
                }
            }

            states.Add(GetMapString(map));

            while (true)
            {
                for (int y = 0; y < 5; y++)
                {
                    for (int x = 0; x < 5; x++)
                    {
                        var pos   = new V2(x, y);
                        int count = 0;
                        foreach (var dir in V2.Directions)
                        {
                            if (map.TryGetValue(pos + dir, out char c))
                            {
                                if (c == '#')
                                {
                                    count++;
                                }
                            }
                        }

                        newMap[pos] = (count == 1 || map[pos] == '.' && count == 2) ? '#' : '.';
                    }
                }


                string state = GetMapString(newMap);

                if (states.Contains(state))
                {
                    long value = 0;
                    foreach (var kv in newMap)
                    {
                        if (kv.Value == '#')
                        {
                            value += (long)Math.Pow(2, kv.Key.y * 5 + kv.Key.x);
                        }
                    }

                    return(value.ToString());
                }
                else
                {
                    states.Add(state);
                }

                foreach (var key in map.Keys.ToList())
                {
                    map[key] = newMap[key];
                }
            }
        }
Example #9
0
 bool EvenTile(V2 tile) => tile.y % 2 == 0;
Example #10
0
        public override string Part1()
        {
            // Get map
            var lines = File.ReadAllLines("Input/20.txt");

            for (int y = 0; y < lines.Length; y++)
            {
                var chars = lines[y].ToCharArray();
                for (int x = 0; x < chars.Length; x++)
                {
                    if (chars[x] == '.' || chars[x] >= 'A' && chars[x] <= 'Z')
                    {
                        nodes.Add(new Node()
                        {
                            pos = new V2(x, y),
                            c   = chars[x]
                        });
                    }
                }
            }

            foreach (var node in nodes)
            {
                // Get list of neighbours
                List <Node> neighbours = new List <Node>();
                foreach (var dir in V2.Directions)
                {
                    Node neighbour = nodes.Find(n => n.pos == node.pos + dir);
                    if (neighbour != null)
                    {
                        neighbours.Add(neighbour);
                    }
                }
                node.neighbours = neighbours.ToArray();

                // Get list of portals
                if (node.c >= 'A' && node.c <= 'Z')
                {
                    bool start    = false;
                    char other    = 'x';
                    V2   otherDir = V2.Zero;
                    Node exitNode = null;

                    foreach (var neighbour in neighbours)
                    {
                        if (neighbour.c == '.')
                        {
                            start    = true;
                            exitNode = neighbour;
                        }
                        else
                        {
                            other    = neighbour.c;
                            otherDir = neighbour.pos - node.pos;
                        }
                    }

                    if (start)
                    {
                        node.exit = exitNode;
                        node.name = (otherDir == V2.Up || otherDir == V2.Left) ? other.ToString() + node.c : node.c.ToString() + other;
                        if (node.pos.x == 1 || node.pos.x == lines[0].Length - 2)
                        {
                            node.outSide = true;
                        }
                        else if (node.pos.y == 1 || node.pos.y == lines.Length - 2)
                        {
                            node.outSide = true;
                        }
                    }
                }
            }

            startNode = nodes.Find(n => n.name == "AA").exit;

            // Connect portals
            foreach (var node in nodes)
            {
                if (node.name != null)
                {
                    Node other = nodes.Find(n => n.name == node.name && n != node);
                    if (other != null)
                    {
                        node.other = other;
                    }
                }
            }

            int steps = FindPath(startNode);

            return(steps.ToString());
        }