コード例 #1
0
        private IEnumerable <object> Day1(List <string> map)
        {
            HashSet <string> part2 = new HashSet <string>();

            var start = new TileDay13();

            start.Y = map.FindIndex(x => x.Contains("A"));
            start.X = map[start.Y].IndexOf("A");


            var finish = new TileDay13();

            finish.Y = map.FindIndex(x => x.Contains("B"));
            finish.X = map[finish.Y].IndexOf("B");

            start.SetDistance(finish.X, finish.Y);

            var activeTiles = new List <TileDay13>();

            activeTiles.Add(start);
            var visitedTiles = new List <TileDay13>();

            while (true)
            {
                var checkTile = activeTiles.OrderBy(x => x.CostDistance).First();

                if (checkTile.X == finish.X && checkTile.Y == finish.Y)
                {
                    if (checkTile.Cost < 50)
                    {
                        part2.Add($"{checkTile.X}-{checkTile.Y}");
                    }
                    //We found the destination and we can be sure (Because the the OrderBy above)
                    //That it's the most low cost option.
                    var tile = checkTile;
                    //Console.WriteLine("Retracing steps backwards...");
                    while (true)
                    {
                        //Console.WriteLine($"{tile.X} : {tile.Y}");
                        if (map[tile.Y][tile.X] == '.')
                        {
                            var newMapRow = map[tile.Y].ToCharArray();
                            newMapRow[tile.X] = 'O';
                            map[tile.Y]       = new string(newMapRow);
                        }
                        tile = tile.Parent;
                        if (tile == null)
                        {
                            //Console.WriteLine();
                            //map.ForEach(x => Console.WriteLine(x));
                            //Console.WriteLine();
                            yield return(checkTile.Cost);
                        }
                    }
                }

                visitedTiles.Add(checkTile);
                activeTiles.Remove(checkTile);

                var walkableTiles = GetWalkableTiles(map, checkTile, finish);

                foreach (var walkableTile in walkableTiles)
                {
                    //We have already visited this tile so we don't need to do so again!
                    if (visitedTiles.Any(x => x.X == walkableTile.X && x.Y == walkableTile.Y))
                    {
                        continue;
                    }

                    //It's already in the active list, but that's OK, maybe this new tile has a better value (e.g. We might zigzag earlier but this is now straighter).
                    if (activeTiles.Any(x => x.X == walkableTile.X && x.Y == walkableTile.Y))
                    {
                        var existingTile = activeTiles.First(x => x.X == walkableTile.X && x.Y == walkableTile.Y);
                        if (existingTile.CostDistance > checkTile.CostDistance)
                        {
                            activeTiles.Remove(existingTile);
                            activeTiles.Add(walkableTile);
                        }
                    }
                    else
                    {
                        //We've never seen this tile before so add it to the list.
                        activeTiles.Add(walkableTile);
                    }
                }
            }

            //Console.WriteLine("No Path Found!");
            //yield return $"";
        }
コード例 #2
0
        private IEnumerable <object> Day2(List <string> map)
        {
            HashSet <string> part2 = new HashSet <string>();

            //map.ForEach(a => Console.WriteLine(a));

            var start = new TileDay13();

            start.Y = map.FindIndex(x => x.Contains("A"));
            start.X = map[start.Y].IndexOf("A");


            var finish = new TileDay13();

            finish.Y = map.FindIndex(x => x.Contains("B"));
            finish.X = map[finish.Y].IndexOf("B");

            start.SetDistance(finish.X, finish.Y);

            var activeTiles = new List <TileDay13>();

            activeTiles.Add(start);
            var visitedTiles = new List <TileDay13>();

            bool MoreTiles = true;

            while (MoreTiles)
            {
                var checkTile = activeTiles.OrderBy(x => x.CostDistance).First();

                if (checkTile.Cost < 50)
                {
                    part2.Add($"{checkTile.X}-{checkTile.Y}");
                }

                yield return(part2.Count() + 1);

                visitedTiles.Add(checkTile);
                activeTiles.Remove(checkTile);

                var walkableTiles = GetWalkableTiles(map, checkTile, finish);

                foreach (var walkableTile in walkableTiles)
                {
                    //We have already visited this tile so we don't need to do so again!
                    if (visitedTiles.Any(x => x.X == walkableTile.X && x.Y == walkableTile.Y))
                    {
                        continue;
                    }

                    //It's already in the active list, but that's OK, maybe this new tile has a better value (e.g. We might zigzag earlier but this is now straighter).
                    if (activeTiles.Any(x => x.X == walkableTile.X && x.Y == walkableTile.Y))
                    {
                        var existingTile = activeTiles.First(x => x.X == walkableTile.X && x.Y == walkableTile.Y);
                        if (existingTile.CostDistance > checkTile.CostDistance)
                        {
                            activeTiles.Remove(existingTile);
                            activeTiles.Add(walkableTile);
                        }
                    }
                    else
                    {
                        //We've never seen this tile before so add it to the list.
                        activeTiles.Add(walkableTile);
                    }
                }
                if (activeTiles.Count() == 0)
                {
                    MoreTiles = false;
                }
            }
        }