public static void Register(CommandLineApplication app) { app.Command( "solve", (command) => { command.Description = "Solve all problems with all solvers"; command.HelpOption("-?|-h|--help"); var solverOption = command.Option( "-s|--solver", "Solver name prefix", CommandOptionType.SingleValue); var problemsOption = command.Option( "-p|--problems", "Single problem id or problem ids range", CommandOptionType.SingleValue); command.OnExecute( () => { var solvers = RunnableSolvers .Enumerate() .Select(x => x.Invoke()) .Where(x => !solverOption.HasValue() || solverOption.HasValue() && x.GetName().StartsWith(solverOption.Value())) .ToList(); var problemIds = new List <int>(); if (problemsOption.HasValue()) { if (int.TryParse(problemsOption.Value(), out var problemId)) { problemIds.Add(problemId); } else { var parts = problemsOption.Value().Split(new [] { ".." }, StringSplitOptions.RemoveEmptyEntries); var pStart = int.Parse(parts[0]); var pEnd = int.Parse(parts[1]); problemIds.AddRange(Enumerable.Range(pStart, pEnd - pStart + 1)); Console.WriteLine($"Will solve problems: {string.Join(", ", problemIds)}"); } } solvers.ForEach( solver => { ProblemReader .ReadAll() .Where(x => !problemIds.Any() || problemIds.Contains(x.ProblemId)) .ToList() .ForEach(problemMeta => Common.Solve(solver, problemMeta)); }); return(0); }); }); }
public static void Register(CommandLineApplication app) { app.Command( "solve-unsolved", (command) => { command.Description = "Create solutions for all nonexistent problem-solver pairs"; command.HelpOption("-?|-h|--help"); var threadsOption = command.Option( "-t|--threads", "Number of worker threads", CommandOptionType.SingleValue); command.OnExecute( () => { var threadsCount = threadsOption.HasValue() ? int.Parse(threadsOption.Value()) : Environment.ProcessorCount; var threads = Enumerable.Range(0, threadsCount).ToList(); Parallel.ForEach( threads, new ParallelOptions { MaxDegreeOfParallelism = threadsCount }, thread => { while (true) { var solvers = RunnableSolvers .Enumerate() .OrderBy(_ => Guid.NewGuid()) .Select(x => x.Invoke()) .ToList(); var problems = ProblemReader.ReadAll(); solvers.ForEach( solver => { var solved = Storage.EnumerateSolved(solver).Select(x => x.ProblemId); var unsolved = problems .Select(x => x.ProblemId) .Except(solved) .OrderBy(_ => Guid.NewGuid()) .ToList() .First(); Common.Solve(solver, problems.Find(x => x.ProblemId == unsolved), thread); }); } }); return(0); }); }); }
public static void Solve(ISolver solver, ProblemMeta problemMeta, int?thread = null) { var prefix = thread.HasValue ? $"#{thread.Value}: " : string.Empty; Console.WriteLine($"{prefix}{DateTime.Now}: Solving {problemMeta.ProblemId} with {solver.GetName()} v{solver.GetVersion()}... "); new SolutionInProgress(problemMeta.ProblemId, solver.GetName(), solver.GetVersion()).SaveToDb(); try { var solutionMeta = RunnableSolvers.Solve(solver, problemMeta); solutionMeta.SaveToDb(); Console.WriteLine($"{prefix}Done in {solutionMeta.CalculationTookMs} ms, {solutionMeta.OurTime} time units"); } catch (Exception e) { Console.WriteLine(e); } }
private static async Task <int> SolveBlock(CommandOption blockNumberOption, CommandOption submitOption) { BlockchainBlock block; if (blockNumberOption.HasValue()) { block = await Api.GetBlockchainBlock(int.Parse(blockNumberOption.Value())); } else { block = await Api.GetBlockchainBlock(); } Console.WriteLine($"Solving block #{block.BlockNumber} ... {DateTime.Now}"); var blockProblemPath = Path.Combine(FileHelper.PatchDirectoryName("problems"), "puzzles", $"block{block.BlockNumber:000}_orig.desc"); if (submitOption.HasValue() && File.Exists(blockProblemPath)) { Console.WriteLine("Already solved."); Thread.Sleep(TimeSpan.FromSeconds(10)); return(0); } File.WriteAllText(blockProblemPath, block.Problem.ToString()); var puzzlePath = Path.Combine(FileHelper.PatchDirectoryName("problems"), "puzzles", $"block{block.BlockNumber:000}.cond"); File.WriteAllText(puzzlePath, block.Puzzle.ToString()); Console.WriteLine($"Solving puzzle ..."); var puzzleSolvers = new List <IPuzzleSolver> { new MstPuzzleSolver(), }; var puzzleSolved = false; var ourProblemPath = Path.Combine(FileHelper.PatchDirectoryName("problems"), "puzzles", $"block{block.BlockNumber:000}.desc"); foreach (var puzzleSolver in puzzleSolvers) { var ourProblem = puzzleSolver.Solve(block.Puzzle); if (!ourProblem.IsValidForPuzzle(block.Puzzle)) { continue; } puzzleSolved = true; File.WriteAllText(ourProblemPath, ourProblem.ToString()); } if (!puzzleSolved) { throw new Exception("Puzzle not solved."); } var solvers = RunnableSolvers .PuzzleSolvers() .Select(x => x.Invoke()) //.Take(1) .ToList(); var mapSize = block.Problem.ToState().Map; Console.WriteLine($"Solving problem {mapSize.SizeX}x{mapSize.SizeY} with {solvers.Count} solvers ..."); var results = new List <Tuple <ISolver, List <List <ActionBase> > > >(); var stopwatch = Stopwatch.StartNew(); foreach (var solver in solvers) { if (stopwatch.Elapsed > TimeSpan.FromMinutes(10)) { break; } var solved = solver.Solve(block.Problem.ToState().Clone()); var calculationTime = stopwatch.ElapsedMilliseconds; var actions = solved.Actions; var time = solved.CalculateTime(); var solutionBlob = solved.FormatSolution(); var path = Path.Combine(FileHelper.PatchDirectoryName("problems"), "puzzles", $"block{block.BlockNumber:000}_sol_{solver.GetName()}_v{solver.GetVersion()}_{time}.sol"); File.WriteAllText(path, solutionBlob); Console.WriteLine($"{solver.GetName()}_v{solver.GetVersion()} score = {time} time = {stopwatch.Elapsed}"); new SolutionMeta( block.BlockNumber, solutionBlob, time, solver.GetName(), solver.GetVersion(), calculationTime, null, 0 ).SaveToDb(isBlockSolution: true); results.Add(Tuple.Create(solver, actions)); } var(bestSolver, bestActions) = results .OrderBy(x => x.Item2.CalculateTime()) .First(); var solutionPath = Path.Combine(FileHelper.PatchDirectoryName("problems"), "puzzles", $"block{block.BlockNumber:000}_best_{bestSolver.GetName()}_v{bestSolver.GetVersion()}_{bestActions.CalculateTime()}.sol"); File.WriteAllText(solutionPath, bestActions.Format()); Console.WriteLine($"Best score = {bestActions.CalculateTime()}"); if (submitOption.HasValue()) { Console.WriteLine("Submitting block ..."); var submissionResult = await Api.Submit(block.BlockNumber, solutionPath, ourProblemPath); if (submissionResult.Errors != null && submissionResult.Errors.Count > 0) { submissionResult.Errors.ToList() .ForEach( e => { Console.WriteLine($"Error {e.Key}: {e.Value}"); }); } } Console.WriteLine("Done."); return(0); }