コード例 #1
0
ファイル: Program.cs プロジェクト: lazy/icfpc2019
        private static async Task SolveCurrentBlockAsync()
        {
            var balanceInfo = int.Parse(await FetchApiAsync("getbalance", "83"));
            var metaInfo    = JObject.Parse(await FetchApiAsync("getblockchaininfo", null));
            var blockNum    = metaInfo["block"].Value <int>();
            var blockSubs   = metaInfo["block_subs"].Value <int>();
            var blockInfo   = JObject.Parse(await FetchApiAsync("getblockinfo", blockNum.ToString()));
            var blockTs     = DateTimeOffset.FromUnixTimeSeconds((int)blockInfo["block_ts"].Value <double>());
            var blockAge    = DateTimeOffset.UtcNow - blockTs;
            var puzzleText  = blockInfo["puzzle"].Value <string>();
            var taskText    = blockInfo["task"].Value <string>();

            Console.WriteLine($"Current block: #{blockNum}, aged {blockAge}, {blockSubs} submissions, our balance: {balanceInfo}");

            var solutionDir = FindSolutionDir();
            var blockDir    = Path.Combine(solutionDir, $@"Data\blocks\{blockNum}");

            if (!Directory.Exists(blockDir))
            {
                Console.WriteLine("This is a totally new block; creating a new directory");
                Directory.CreateDirectory(blockDir);
            }

            var puzzleFile = Path.Combine(blockDir, "puzzle.cond");

            if (!File.Exists(puzzleFile))
            {
                Console.WriteLine($"Writing the original puzzle: {puzzleText}");
                File.WriteAllText(puzzleFile, puzzleText);
            }

            var puzzleSolutionFile = $"{puzzleFile}.desc";

            if (!File.Exists(puzzleSolutionFile))
            {
                Console.WriteLine("Solving puzzle");
                var seed  = 3133337;
                var tries = 0;
                while (true)
                {
                    if (++tries == 200)
                    {
                        throw new Exception("Faile to solve puzzle!");
                    }

                    Console.WriteLine($"Solving puzzle with seed {seed}");
                    var puzzle = new Puzzle(puzzleText, seed);
                    File.WriteAllText(puzzleSolutionFile, puzzle.SaveToMap());
                    puzzle.SaveToBitmap().Save($"{puzzleFile}.png");
                    try
                    {
                        puzzle.EnsureMapIsValid(puzzleSolutionFile);
                        Console.WriteLine("Have a valid solution");
                        break;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Puzzle solution is invalid: {ex.Message}");
                        ++seed;
                    }
                }
            }

            var taskFile = Path.Combine(blockDir, "task.desc");

            if (!File.Exists(taskFile))
            {
                Console.WriteLine($"Writing the original task: {taskText}");
                File.WriteAllText(taskFile, taskText);
            }

            var extSolutionFile = $"{taskFile}.ext-sol";
            var solutionFile    = $"{taskFile}.sol";

            Console.WriteLine("Solving task");
            var sw = new Stopwatch();

            sw.Start();

            // shuffled strategies list
            var strategies = StrategyFactory.GenerateStrategies().ToArray();
            var rng        = new Random();

            strategies = new[] { new DumbBfs() }.Concat(strategies.OrderBy(s => rng.Next())).ToArray();

            // Block lives for 15 minutes, lets try to solve everything by 14:00
            var blockLifetimeMs = 10 * 60 * 1000;
            var timeToSolve     = Math.Max(5000, blockLifetimeMs - blockAge.TotalMilliseconds);

            Console.WriteLine($"Time to solve: {timeToSolve} ms");

            var map       = MapParser.Parse(taskText, string.Empty);
            var solutions = strategies.AsParallel().WithDegreeOfParallelism(10)
                            .Select(
                strategy =>
            {
                var run = false;
                lock (sw)
                {
                    run = sw.ElapsedMilliseconds < timeToSolve;
                }

                return(run
                            ? Emulator.MakeExtendedSolution(map, strategy, string.Empty)
                            : Emulator.MakeExtendedSolution(map, "fail", new Command[][] { }, string.Empty));
            });

            var numSuccess = 0;

            foreach (var sln in solutions)
            {
                if (sln.IsSuccessful)
                {
                    ++numSuccess;
                }

                sln.SaveIfBetter(extSolutionFile);
            }

            Console.WriteLine($" Solution took: {sw.ElapsedMilliseconds} ms, {numSuccess} strategies out of {strategies.Length} successed");

            var extSolution = ExtendedSolution.Load(extSolutionFile);

            if (!extSolution.IsSuccessful)
            {
                throw new Exception("ext solution is not successful!");
            }

            File.WriteAllText(solutionFile, extSolution.Commands);

            var submissionResultFile = Path.Combine(blockDir, "submit.txt");

            if (!File.Exists(submissionResultFile))
            {
                Console.WriteLine("SUBMITTING!");

                var payload = new MultipartFormDataContent();
                payload.Add(new StringContent("2a78df7b478788ae4cf9d338"), "private_id");
                payload.Add(new StringContent(blockNum.ToString()), "block_num");
                payload.Add(new ByteArrayContent(File.ReadAllBytes(solutionFile)), "solution", "task.desc.sol");
                payload.Add(new ByteArrayContent(File.ReadAllBytes(puzzleSolutionFile)), "puzzle", "puzzle.cond.desc");

                var httpClient = new HttpClient();
                var response   = await httpClient.PostAsync($"{BlockChainUrl}/submit", payload);

                var submissionResult = await response.Content.ReadAsStringAsync();

                Console.WriteLine($"RESULT: {submissionResult}");
                File.WriteAllText(submissionResultFile, submissionResult);
            }
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: lazy/icfpc2019
        public static void Main(string[] args)
        {
            var baseDir = args.Length > 0 ? args[0] : FindSolutionDir();

            Directory.SetCurrentDirectory(baseDir);

            var mapFiles = Directory.EnumerateFiles("Data/maps", "*.desc").ToList();
            var maps     = mapFiles.Select(
                filename =>
            {
                var mapName = Path.GetFileNameWithoutExtension(filename);
                var map     = MapParser.Parse(File.ReadAllText(filename), string.Empty);

                var originalSolution = ExtendedSolution.Load($"Data/extended-solutions/{mapName}.ext-sol");

                var boostedSolution = File.Exists($"Data/extended-solutions-packed/{mapName}.ext-sol")
                            ? ExtendedSolution.Load($"Data/extended-solutions-packed/{mapName}.ext-sol")
                            : null;

                return(new MapData
                {
                    Name = mapName,
                    OriginalSolution = originalSolution,
                    Width = map.Width,
                    Height = map.Height,
                    BoostedSolution = boostedSolution,
                });
            })
                           .ToArray();

            var nameToSolution = maps.ToDictionary(
                data => data.Name,
                data => data.OriginalSolution);

            var budget = InitialBudget;

            foreach (var map in maps.OrderBy(data => (data.GetProfit() / (float)data.BoostCost)))
            {
                if (map.BoostedSolution != null && map.BoostCost < budget)
                {
                    nameToSolution[map.Name] = map.BoostedSolution;
                    budget -= map.BoostCost;
                }
            }

            if (Directory.Exists("Data/submission"))
            {
                Directory.Delete("Data/submission", true);
            }

            Directory.CreateDirectory("Data/submission");

            foreach (var kvp in nameToSolution)
            {
                var(name, solution) = kvp;
                File.WriteAllText($"Data/submission/{name}.sol", solution.Commands);
                if (!string.IsNullOrEmpty(solution.BoosterPack))
                {
                    File.WriteAllText($"Data/submission/{name}.buy", solution.BoosterPack);
                }
            }

            var submissionFile = $"Data/submission.zip";

            if (File.Exists(submissionFile))
            {
                File.Delete(submissionFile);
            }

            ZipFile.CreateFromDirectory($"Data/submission", submissionFile);
        }
コード例 #3
0
        public static void Main(string[] args)
        {
            var baseDir = args.Length > 0 ? args[0] : FindSolutionDir();

            Directory.SetCurrentDirectory(baseDir);

            var mapFiles = Directory.EnumerateFiles("Data/maps", "*.desc").ToList();
            var maps     = mapFiles.Select(
                filename =>
            {
                var mapName  = Path.GetFileNameWithoutExtension(filename);
                var map      = MapParser.Parse(File.ReadAllText(filename), string.Empty);
                var solution = ExtendedSolution.Load($"Data/extended-solutions/{mapName}.ext-sol");

                return(new MapState
                {
                    MapName = mapName,
                    OriginalTime = solution.TimeUnits ?? 0,
                    Width = map.Width,
                    Height = map.Height,
                    HasSpawns = map.NumSpawnPoints > 0,
                    NumOriginalClones = map.NumCloneBoosts,
                    NumNewClones = 0,
                });
            })
                           .ToArray();

            var budget = OriginalBudget;

            while (budget >= 2000)
            {
                budget -= 2000;

                var best       = maps[0];
                var bestProfit = 0;

                foreach (var map in maps)
                {
                    var curScore = map.ProfitWithExtra(map.NumNewClones);
                    var newScore = map.ProfitWithExtra(map.NumNewClones + 1);
                    var profit   = newScore - curScore;

                    if (profit > bestProfit)
                    {
                        best       = map;
                        bestProfit = profit;
                    }
                }

                best.NumNewClones += 1;
                best.Boosters     += 'C';
            }

            foreach (var map in maps)
            {
                if (map.NumNewClones > 0)
                {
                    Console.WriteLine($"{map.MapName} {map.Boosters}");
                }
            }
        }
コード例 #4
0
        public static void Main(string[] args)
        {
            const int Iterations = 1;

            for (var i = 0; i < Iterations; ++i)
            {
                var baseDir = args.Length > 0 ? args[0] : FindSolutionDir();
                Directory.SetCurrentDirectory(baseDir);

                var strategies = StrategyFactory.GenerateStrategies().ToArray();
                var packFile   = "Data/booster-pack.txt";
                var mapToPack  = File.ReadAllLines(packFile).Select(line => line.Split(' ')).ToDictionary(tokens => tokens[0], tokens => tokens[1]);

                var totalTimeUnits = 0;
                var haveFailures   = false;

                var outputLock = new object();

                Parallel.ForEach(
                    Directory.EnumerateFiles("Data/maps", "*.desc"),
                    new ParallelOptions {
                    MaxDegreeOfParallelism = 10
                },
                    mapFile =>
                {
                    var log     = new List <string>();
                    var mapName = Path.GetFileNameWithoutExtension(mapFile);

                    void Log(string msg)
                    {
                        if (LogImmediately)
                        {
                            Console.WriteLine($"{mapName}: {msg}");
                        }
                        else
                        {
                            log.Add(msg);
                        }
                    }

                    if (!mapToPack.ContainsKey(mapName))
                    {
                        return;
                    }

                    string packedBoosters = mapToPack.ContainsKey(mapName) ? mapToPack[mapName] : string.Empty;
                    Log($"Processing {mapName} with extra boosters: [{packedBoosters}]");
                    var map            = MapParser.Parse(File.ReadAllText(mapFile), packedBoosters);
                    var solutionSuffix = packedBoosters != string.Empty ? "-packed" : string.Empty;

                    var extSolutionPath = $"Data/extended-solutions{solutionSuffix}/{mapName}.ext-sol";

                    // Delete broken solutions
                    if (File.Exists(extSolutionPath))
                    {
                        var oldSolution = ExtendedSolution.Load(extSolutionPath);
                        var oldCommands = CommandsSerializer.Parse(oldSolution.Commands);
                        if (!Emulator.MakeExtendedSolution(map, string.Empty, oldCommands, packedBoosters).IsSuccessful)
                        {
                            File.Delete(extSolutionPath);
                        }
                    }

                    var rng = new Random();
                    var currentStrategies = StrategiesLimit != null
                            ? strategies.OrderBy(s => rng.Next()).Take(StrategiesLimit.Value).ToArray()
                            : strategies;

                    var solutions = currentStrategies.AsParallel()
                                    .Where(strategy => !(mapName.Contains("294") && strategy.Name.Contains("DumbBfs")))
                                    .Select(strategy => (strategy, Emulator.MakeExtendedSolution(map, strategy, packedBoosters)));

                    var numSuccessful = 0;
                    foreach (var pair in solutions)
                    {
                        var(strategy, solution) = pair;
                        solution.SaveIfBetter(extSolutionPath);
                        if (solution.IsSuccessful)
                        {
                            Log($"  {strategy.Name}: {solution.TimeUnits}");
                            if (StrategiesLimit != null && ++numSuccessful >= StrategiesLimit)
                            {
                                break;
                            }
                        }
                    }

                    var best = ExtendedSolution.Load(extSolutionPath);
                    File.WriteAllText($"Data/solutions{solutionSuffix}/{mapName}.sol", best.Commands);
                    if (solutionSuffix != string.Empty)
                    {
                        File.WriteAllText($"Data/solutions{solutionSuffix}/{mapName}.buy", packedBoosters);
                    }

                    Log($"  BEST ({best.StrategyName}): {best.IsSuccessful}/{best.TimeUnits}");

                    lock (outputLock)
                    {
                        if (best.TimeUnits.HasValue)
                        {
                            totalTimeUnits += best.TimeUnits.Value;
                        }
                        else
                        {
                            haveFailures = true;
                        }

                        foreach (var line in log)
                        {
                            Console.WriteLine(line);
                        }
                    }
                });