private static int FindPuzzleWithConstraint() { var lockObj = new object(); Db.ConnectionString = @"Server=CORNFLOWER;Database=Kyudosudoku;Trusted_Connection=True;"; var notFound = new HashSet <string> { "YSum" }; Enumerable.Range(192, 1000).ParallelForEach(Environment.ProcessorCount, seed => { using (var db = new Db()) if (db.Puzzles.Any(p => p.PuzzleID == seed)) { return; } lock (lockObj) { if (notFound.Count == 0) { return; } Console.WriteLine(seed); } var puz = Kyudosudoku.Generate(seed); lock (lockObj) { if (notFound.Count == 0) { return; } foreach (var lk in puz.Constraints) { var str = lk.GetType().Name; if (notFound.Contains(str)) { puz.SaveToDb(seed, null); ConsoleUtil.WriteLine($" — {seed} has {str}".Color(ConsoleColor.White, ConsoleColor.DarkGreen)); notFound.Remove(str); } } } }); Console.WriteLine("Done."); Console.ReadLine(); return(0); }
private HttpResponse PuzzlePage(HttpRequest req, DbSession session, Db db) { Match m; if ((m = Regex.Match(req.Url.Path, @"^/db-update/(\d+)$")).Success && req.Method == HttpMethod.Post) { return(dbUpdate(req, session, db, int.Parse(m.Groups[1].Value))); } var puzzleIdStr = req.Url.Path.Length == 0 ? "" : req.Url.Path.Substring(1); if (!int.TryParse(puzzleIdStr, out int puzzleId) || puzzleId < 0) { return(page404(req)); } var dbPuzzle = db.Puzzles.FirstOrDefault(p => p.PuzzleID == puzzleId); if (dbPuzzle == null || dbPuzzle.Invalid) { return(page404(req)); } var puzzle = new Kyudosudoku(dbPuzzle.KyudokuGrids.Split(36).Select(subgrid => subgrid.Select(ch => ch - '0').ToArray()).ToArray(), dbPuzzle.Constraints == null ? new SvgConstraint[0] : ClassifyJson.Deserialize <SvgConstraint[]>(JsonValue.Parse(dbPuzzle.Constraints))); var userPuzzle = session.User == null ? null : db.UserPuzzles.FirstOrDefault(up => up.UserID == session.User.UserID && up.PuzzleID == puzzleId); var extraTop = puzzle.Constraints.MaxOrDefault(c => c.ExtraTop, 0); var extraRight = puzzle.Constraints.MaxOrDefault(c => c.ExtraRight, 0); var extraLeft = puzzle.Constraints.MaxOrDefault(c => c.ExtraLeft, 0); var helpSvg = @"<g transform='translate(.05, .05) scale(.008)'> <path fill='#fcedca' stroke='black' stroke-width='2' d='M12.5 18.16h75v25h-75z'/> <text class='label' x='50' y='33.4' font-size='24' text-anchor='middle' transform='translate(0 5.66)'>???</text> <path fill='white' stroke='black' stroke-width='2' d='M53.238 33.237V73.17l9.513-9.513 7.499 18.106 5.272-2.184-7.38-17.818h13.62z'/> </g>"; var fillSvg = @"<text x='.45' y='.4' font-size='.25'>Auto</text><text x='.45' y='.65' font-size='.25' fill='hsl(217, 80%, 50%)'>123</text>"; var buttonsRight = Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>(9, btn => ((btn + 1).ToString(), false, (btn + 1).ToString(), .9, 0)) .Concat(Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>( ("Normal", false, "normal", 2.6, 1), ("Corner", false, "corner", 2.6, 1), ("Center", false, "center", 2.6, 1), (fillSvg, true, "fill", .9, 1), ("<path d='m 0.65,0.25 v 0.4 l -0.4,-0.2 z' />", true, "switch", .9, 2), ("Clear", false, "clear", 2.55, 2), ("Undo", false, "undo", 2.1, 2), ("Redo", false, "redo", 2.1, 2), (helpSvg, true, "help", .9, 2))); var buttonsLeft = Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>(9, btn => ((btn + 1).ToString(), false, $"{btn + 1}-left", .85, 0)) .Concat(Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>( ("Clear", false, "clear-left", 2.45, 1), ("Undo", false, "undo-left", 2.45, 1), ("Redo", false, "redo-left", 2.45, 1), ("<path d='m 0.25,0.25 v 0.4 l 0.4,-0.2 z' />", true, "switch-left", .9, 1))); string renderButton(string id, double x, double y, double width, string label, bool isSvg = false) => $@" <g class='button' id='{id}' transform='translate({x}, {y})'> <rect class='clickable' x='0' y='0' width='{width}' height='.9' stroke-width='.025' rx='.08' ry='.08'/> {(isSvg ? label : $"<text class='label' x='{width / 2}' y='.65' font-size='.55' text-anchor='middle'>{label}</text>")}
private static void RunStatistics() { var lockObj = new object(); var seedCounter = 1000; var stats = new Dictionary <string, int>(); var arrowLengthStats = new Dictionary <int, int>(); var inclusionNumStats = new Dictionary <int, int>(); var killerCageSizeStats = new Dictionary <int, int>(); var killerCageSumStats = new Dictionary <int, int>(); var renbanCageSizeStats = new Dictionary <int, int>(); var palindromeSizeStats = new Dictionary <int, int>(); var thermometerSizeStats = new Dictionary <int, int>(); var cappedLineSizeStats = new Dictionary <int, int>(); //var json = JsonValue.Parse(File.ReadAllText(@"D:\temp\kyudo-stats.json")); //var strings = @"AntiBishop,AntiKing,AntiKnight,NoConsecutive,OddEven,,,Arrow,KillerCage,Palindrome,RenbanCage,Snowball,Thermometer,,,Battlefield,Binairo,Sandwich,Skyscraper,ToroidalSandwich,XSum,,,Battenburg,Clockface,ConsecutiveNeighbors,DoubleNeighbors,Inclusion,LittleKiller".Split(','); //Clipboard.SetText(strings.Select(s => string.IsNullOrWhiteSpace(s) ? "" : json["Stats"][s].GetInt().ToString()).JoinString("\n")); //return; Enumerable.Range(0, Environment.ProcessorCount).ParallelForEach(proc => { var seed = 0; while (true) { lock (lockObj) { seed = seedCounter++; Console.WriteLine($"Generating {seed}"); } var puzzle = Kyudosudoku.Generate(seed); lock (lockObj) { foreach (var constr in puzzle.Constraints) { stats.IncSafe(constr.GetType().Name); if (constr is Arrow a) { arrowLengthStats.IncSafe(a.Cells.Length - 1); } if (constr is Inclusion i) { inclusionNumStats.IncSafe(i.Digits.Length); } if (constr is KillerCage kc) { killerCageSizeStats.IncSafe(kc.Cells.Length); killerCageSumStats.IncSafe(kc.Sum ?? -1); } if (constr is RenbanCage rc) { renbanCageSizeStats.IncSafe(rc.Cells.Length); } if (constr is Palindrome p) { palindromeSizeStats.IncSafe(p.Cells.Length); } if (constr is Thermometer t) { thermometerSizeStats.IncSafe(t.Cells.Length); } if (constr is CappedLine cl) { cappedLineSizeStats.IncSafe(cl.Cells.Length); } } ClassifyJson.SerializeToFile(new { Stats = stats, ArrowLengths = arrowLengthStats, InclusionNums = inclusionNumStats, KillerCageSizes = killerCageSizeStats, KillerCageSums = killerCageSumStats, RenbanCageSizes = renbanCageSizeStats, PalindromeSizes = palindromeSizeStats, ThermometerSizes = thermometerSizeStats, CappedLineSizeStats = cappedLineSizeStats }, @"D:\temp\kyudo-stats.json"); } } }); }