Beispiel #1
0
        public static void Day13()
        {
            //int favoriteNum = 10;
            //var destination = new Day13Location() {location = new Tuple<int, int>(7, 4)};
            int favoriteNum = 1358;
            var destination = new Day13Location()
            {
                location = new Tuple <int, int>(31, 39)
            };
            Func <Day13Location, Day13Location, double> distanceFunc = (Day13Location l1, Day13Location l2) => Math.Sqrt((l2.x - l1.x) * (l2.x - l1.x) + (l2.y - l1.y) * (l2.y - l1.y));

            int [,] officeSpace = new int[255, 255];
            var cameFrom        = new Dictionary <Day13Location, Day13Location>();
            var currentLocation = new Day13Location()
            {
                location = new Tuple <int, int>(1, 1), gScore = 0
            };

            currentLocation.fScore = distanceFunc(currentLocation, destination);
            Func <int, int, bool> IsSpace = (x, y) =>
            {
                int z      = (x * x + 3 * x + 2 * x * y + y + y * y) + favoriteNum;
                int onBits = 0;
                for (int i = 0; i < 15; i++)
                {
                    if ((z & (int)Math.Pow(2, i)) > 0)
                    {
                        onBits++;
                    }
                }
                return(onBits % 2 == 0);
            };

            var openSet = new List <Day13Location>();

            openSet.Add(currentLocation);
            var  closedSet = new List <Day13Location>();
            bool success   = false;

            while (openSet.Count > 0)
            {
                openSet.Sort();
                currentLocation = openSet.First();
                if (currentLocation.Equals(destination))
                {
                    Console.WriteLine("Success!");
                    success = true;
                    break;
                }
                openSet.Remove(currentLocation);
                closedSet.Add(currentLocation);
                double nextGScore = currentLocation.gScore + 1;
                for (int x = -1; x < 2; x++)
                {
                    for (int y = -1; y < 2; y++)
                    {
                        if ((x != 0 && y != 0) || x == 0 && y == 0)
                        {
                            continue;                                     // cardinal directions only, no diagonal and avoid the current location
                        }
                        var neighborTuple = new Tuple <int, int>(currentLocation.x + x, currentLocation.y + y);
                        if (neighborTuple.Item1 < 0 || neighborTuple.Item2 < 0)
                        {
                            continue;                                                    // negative values are invalid
                        }
                        if (IsSpace(currentLocation.x + x, currentLocation.y + y))
                        {
                            double possibleFScore = distanceFunc(currentLocation, destination) + currentLocation.gScore;

                            var neighbor = openSet.FirstOrDefault(l => l.Equals(new Day13Location()
                            {
                                location = neighborTuple
                            }));
                            if (neighbor != null && neighbor.gScore > nextGScore)
                            {
                                openSet.Remove(neighbor);
                            }

                            neighbor = closedSet.FirstOrDefault(l => l.Equals(new Day13Location()
                            {
                                location = neighborTuple
                            }));
                            if (neighbor != null && neighbor.gScore > nextGScore)
                            {
                                closedSet.Remove(neighbor);
                            }

                            if (!closedSet.Contains(neighbor) && !openSet.Contains(neighbor))
                            {
                                if (null == neighbor)
                                {
                                    neighbor = new Day13Location()
                                    {
                                        location = neighborTuple
                                    }
                                }
                                ;
                                openSet.Add(neighbor);
                                neighbor.gScore    = nextGScore;
                                neighbor.fScore    = nextGScore + possibleFScore;
                                cameFrom[neighbor] = currentLocation;
                            }
                        }
                    }
                }
            }

            // print out the path
            Console.WriteLine(currentLocation);
            int steps = 0;

            while (cameFrom.TryGetValue(currentLocation, out currentLocation))
            {
                Console.WriteLine(currentLocation);
                steps++;
            }
            Console.WriteLine($"Took {steps} steps");
        }
Beispiel #2
0
        public static void Day13Part2()
        {
            int favoriteNum = 1358;
            Func <Day13Location, Day13Location, double> distanceFunc = (Day13Location l1, Day13Location l2) => Math.Sqrt((l2.x - l1.x) * (l2.x - l1.x) + (l2.y - l1.y) * (l2.y - l1.y));
            var currentLocation = new Day13Location()
            {
                location = new Tuple <int, int>(1, 1), gScore = 0
            };
            Func <int, int, bool> IsSpace = (x, y) =>
            {
                int z      = (x * x + 3 * x + 2 * x * y + y + y * y) + favoriteNum;
                int onBits = 0;
                for (int i = 0; i < 15; i++)
                {
                    if ((z & (int)Math.Pow(2, i)) > 0)
                    {
                        onBits++;
                    }
                }
                return(onBits % 2 == 0);
            };

            var openSet = new List <Day13Location>();

            openSet.Add(currentLocation);
            var  closedSet = new List <Day13Location>();
            bool success   = false;

            while (openSet.Count > 0)
            {
                currentLocation = openSet.First();
                openSet.Remove(currentLocation);
                closedSet.Add(currentLocation);
                double nextGScore = currentLocation.gScore + 1;
                if (nextGScore > 50)
                {
                    continue;
                }
                for (int x = -1; x < 2; x++)
                {
                    for (int y = -1; y < 2; y++)
                    {
                        if ((x != 0 && y != 0) || x == 0 && y == 0)
                        {
                            continue;                                          // cardinal directions only, no diagonal and avoid the current location
                        }
                        var neighborTuple = new Tuple <int, int>(currentLocation.x + x, currentLocation.y + y);
                        if (neighborTuple.Item1 < 0 || neighborTuple.Item2 < 0)
                        {
                            continue;                                                     // negative values are invalid
                        }
                        if (IsSpace(currentLocation.x + x, currentLocation.y + y))
                        {
                            var neighbor = new Day13Location()
                            {
                                location = neighborTuple, gScore = nextGScore
                            };

                            if (!closedSet.Contains(neighbor) && !openSet.Contains(neighbor))
                            {
                                openSet.Add(neighbor);
                                neighbor.gScore = nextGScore;
                            }
                        }
                    }
                }
            }

            // print out the path
            var gScore50Locs = closedSet.Where(l => l.gScore <= 50);

            Console.WriteLine($"There are {gScore50Locs.Count()} locations within 50 steps from the start");
        }