public static void MergePreVerToPostVer(string dataPath, string dataSuffix, string searchPath) { DataStore.Initialise(dataPath, dataSuffix); var pm = new PathManager(searchPath); pm.AddExcludePath(DataStore.LosPath); foreach (var f in pm.GetFiles()) { Console.WriteLine(f.FullName); Match match; if ((match = Regex.Match(f.Name, @"^(?<region>[A-Z]+)-match-id-nonexistent\.losmid$")).Success) { var region = EnumStrong.Parse <Region>(match.Groups["region"].Value); DataStore.LosMatchIdsNonExistent[region].AppendItems(new MatchIdContainer(f.FullName, region).ReadItems(), LosChunkFormat.LZ4HC); } else if ((match = Regex.Match(f.Name, @"^(?<region>[A-Z]+)-match-id-existing\.losmid$")).Success) { var region = EnumStrong.Parse <Region>(match.Groups["region"].Value); DataStore.LosMatchIdsExisting[region].AppendItems(new MatchIdContainer(f.FullName, region).ReadItems(), LosChunkFormat.LZ4HC); } else if ((match = Regex.Match(f.Name, @"^(?<region>[A-Z]+)-matches-(?<queueId>\d+)\.losjs$")).Success) { var region = EnumStrong.Parse <Region>(match.Groups["region"].Value); var queueId = int.Parse(match.Groups["queueId"].Value); foreach (var json in new JsonContainer(f.FullName).ReadItems()) { var info = new BasicMatchInfo(json); Ut.Assert(info.QueueId == queueId); DataStore.LosMatchJsons[region][info.GameVersion][info.QueueId].AppendItems(new[] { json }, LosChunkFormat.LZ4); } } } }
private static void MergePreVer(string outputPath, string searchPath, bool mergeJsons) { var mergers = new AutoDictionary <Region, RegionMergerPreVer>(region => new RegionMergerPreVer { Region = region }); foreach (var f in new PathManager(searchPath).GetFiles()) { var match = Regex.Match(f.Name, @"^(?<region>[A-Z]+)-matches-(?<queueId>\d+)\.losjs$"); var existing = Regex.Match(f.Name, @"^(?<region>[A-Z]+)-match-id-existing\.losmid$"); var nonexistent = Regex.Match(f.Name, @"^(?<region>[A-Z]+)-match-id-nonexistent\.losmid$"); if (match.Success && mergeJsons) { mergers[EnumStrong.Parse <Region>(match.Groups["region"].Value)].MatchFiles.Add((int.Parse(match.Groups["queueId"].Value), f)); } else if (existing.Success) { mergers[EnumStrong.Parse <Region>(existing.Groups["region"].Value)].ExistingIdsFiles.Add(f); } else if (nonexistent.Success) { mergers[EnumStrong.Parse <Region>(nonexistent.Groups["region"].Value)].NonexistentIdsFiles.Add(f); } } foreach (var merger in mergers.Values) { Console.WriteLine($"===== MERGING {merger.Region} ========"); merger.Merge(outputPath); Console.WriteLine(); Console.WriteLine(); if (mergeJsons) { File.WriteAllLines(Path.Combine(outputPath, $"{merger.Region}-redownload.txt"), merger.RedownloadIds.Select(id => id.ToString())); } } Console.WriteLine($"TOTAL non-existent: {mergers.Values.Sum(m => m.NonexistentCount):#,0}"); if (mergeJsons) { Console.WriteLine($"TOTAL re-download: {mergers.Values.Sum(m => m.RedownloadIds.Count):#,0}"); Console.WriteLine($"TOTAL have: {mergers.Values.Sum(m => m.HaveCounts.Values.Sum()):#,0}"); Console.WriteLine($"TOTAL have one-for-all: {mergers.Values.Sum(m => m.HaveCounts[1020]):#,0}"); } else { Console.WriteLine($"TOTAL existing: {mergers.Values.Sum(m => m.RedownloadIds.Count):#,0}"); } }
private void MergeIds(string region, string outputFile, string[] inputFiles) { var output = new MatchIdContainer(outputFile, EnumStrong.Parse <Region>(region)); var files = new[] { outputFile }.Concat(inputFiles).Select(file => new { file, count = new CountResult() }).ToList(); var ids = files.SelectMany(f => new MatchIdContainer(f.file).ReadItems().PassthroughCount(f.count)).ToHashSet(); foreach (var f in files) { Console.WriteLine($"Read input {f.file}: {f.count.Count:#,0} items"); } File.Delete(outputFile); output.AppendItems(ids.Order(), LosChunkFormat.LZ4HC); output.Rewrite(); }
private HttpResponse generateProfileZip(HttpRequest req) { var moduleInfoCache = _moduleInfoCache; byte[] generateProfile(int operation, Func <KtaneModuleInfo, bool> filter) { var jsonList = moduleInfoCache.Modules.Where(k => k.ModuleID != null && (k.Type == KtaneModuleType.Regular || k.Type == KtaneModuleType.Needy) && filter(k)).Select(k => k.ModuleID).ToJsonList(); return(new JsonDict { { operation == 0 ? "EnabledList" : "DisabledList", jsonList }, { "Operation", operation } }.ToString().ToUtf8()); } return(new UrlResolver( new UrlMapping(path: "/zip", handler: rq => { using (var mem = new MemoryStream()) { var zipFile = ZipFile.Create(mem); zipFile.BeginUpdate(new MemoryArchiveStorage(FileUpdateMode.Direct)); foreach (var difficulty in EnumStrong.GetValues <KtaneModuleDifficulty>()) { zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.DefuserDifficulty == difficulty)), @"Veto defuser {0}.json".Fmt(difficulty.ToReadable()), CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(0, k => k.ExpertDifficulty == difficulty)), @"Expert {0}.json".Fmt(difficulty.ToReadable()), CompressionMethod.Deflated, true); } zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.IsFullBoss)), @"Veto full boss modules.json", CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.IsSemiBoss)), @"Veto semi-boss modules.json", CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.IsPseudoNeedy)), @"Veto pseudo-needy modules.json", CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.IsTimeSensitive)), @"Veto heavily time-dependent modules.json", CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.IsSolveOrderSensitive)), @"Veto solve-order-sensitive modules.json", CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.RuleSeedSupport != KtaneSupport.Supported)), @"Only rule-seeded.json", CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.Souvenir == null || k.Souvenir.Status != KtaneModuleSouvenir.Supported)), @"Only Souvenir supported.json", CompressionMethod.Deflated, true); zipFile.Add(new InMemoryDataSource(generateProfile(1, k => k.Compatibility != KtaneModuleCompatibility.Compatible)), @"Veto incompatible.json", CompressionMethod.Deflated, true); zipFile.CommitUpdate(); zipFile.Close(); return HttpResponse.Create(mem.ToArray(), "application/octet-stream", headers: new HttpResponseHeaders { ContentDisposition = new HttpContentDisposition { Mode = HttpContentDispositionMode.Attachment, Filename = @"""Difficulty-based profiles.zip""" } }); } }) ).Handle(req)); }
public static void Initialise(string dataPath, string suffix, bool autoRewrites = true) { DataPath = dataPath; Suffix = suffix; var losDir = new DirectoryInfo(LosPath); if (!losDir.Exists) { losDir.Create(); } foreach (var file in losDir.GetFiles()) { Match match; if ((match = Regex.Match(file.Name, @"^(?<region>[A-Z]+)-match-id-existing\.losmid$")).Success) { var region = EnumStrong.Parse <Region>(match.Groups["region"].Value); LosMatchIdsExisting[region].EnableAutoRewrite = autoRewrites; LosMatchIdsExisting[region].Initialise(); } else if ((match = Regex.Match(file.Name, @"^(?<region>[A-Z]+)-match-id-nonexistent\.losmid$")).Success) { var region = EnumStrong.Parse <Region>(match.Groups["region"].Value); LosMatchIdsNonExistent[region].EnableAutoRewrite = autoRewrites; LosMatchIdsNonExistent[region].Initialise(); } else if ((match = Regex.Match(file.Name, @"^(?<region>[A-Z]+)-matches-(?<version>\d+\.\d+)-(?<queueId>\d+)\.losjs$")).Success) { var region = EnumStrong.Parse <Region>(match.Groups["region"].Value); var queueId = int.Parse(match.Groups["queueId"].Value); var version = match.Groups["version"].Value; LosMatchJsons[region][version][queueId].EnableAutoRewrite = autoRewrites; LosMatchJsons[region][version][queueId].Initialise(); } else if ((match = Regex.Match(file.Name, @"^(?<region>[A-Z]+)-match-infos\.losbi$")).Success) { var region = EnumStrong.Parse <Region>(match.Groups["region"].Value); LosMatchInfos[region].EnableAutoRewrite = autoRewrites; LosMatchInfos[region].Initialise(); } } }
public override ToolStripMenuItem[] CreateMenus(IIde ide) { var inputModes = EnumStrong.GetValues <InputMode>(); var inputModeItems = new ToolStripMenuItem[inputModes.Length]; var setInputMode = Ut.Lambda((InputMode mode) => { _settings.InputMode = mode; for (int i = 0; i < inputModes.Length; i++) { inputModeItems[i].Checked = (mode == inputModes[i]); } }); var ret = Ut.NewArray( new ToolStripMenuItem("&Input semantics", null, Ut.NewArray( (inputModeItems[0] = new ToolStripMenuItem("Encode input as UTF-&8", null, (_, __) => setInputMode(InputMode.Utf8))), (inputModeItems[1] = new ToolStripMenuItem("Encode input as UTF-1&6 (little endian)", null, (_, __) => setInputMode(InputMode.Utf16))), (inputModeItems[2] = new ToolStripMenuItem("Input string is a list of &bytes", null, (_, __) => setInputMode(InputMode.Numbers)))))); setInputMode(_settings.InputMode); return(ret); }
public static IList <SvgConstraint> Generate(int[] sudoku) => Enumerable.Range(0, 81) .Where(c => sudoku[c] != 9) .SelectMany(c => EnumStrong.GetValues <CellDirection>() .Where(dir => inRange(c % 9 + dx(dir) * sudoku[c]) && inRange(c / 9 + dy(dir) * sudoku[c]) && sudoku[c + dx(dir) * sudoku[c] + dy(dir) * 9 * sudoku[c]] == 9) .Select(dir => new FindThe9(c, dir))) .ToArray();
public override ToolStripMenuItem[] CreateMenus(IIde ide) { var inputModes = EnumStrong.GetValues <InputMode>(); var inputModeItems = new ToolStripMenuItem[inputModes.Length]; var setInputMode = Ut.Lambda((InputMode mode) => { _settings.InputMode = mode; for (int i = 0; i < inputModes.Length; i++) { inputModeItems[i].Checked = (mode == inputModes[i]); } }); var ret = Ut.NewArray( new ToolStripMenuItem("&Memory visualization", null, Ut.NewArray( // Unused mnemonics: cdefhijkmqruwxy new ToolStripMenuItem("&Background color...", null, delegate { color(ide.GetEnvironment(), _settings.MemoryBackgroundColor, c => { _settings.MemoryBackgroundColor = c; }); }), new ToolStripMenuItem("Grid color (&zeros)...", null, delegate { color(ide.GetEnvironment(), _settings.MemoryGridZeroColor, c => { _settings.MemoryGridZeroColor = c; }); }), new ToolStripMenuItem("&Grid color (non-zeros)...", null, delegate { color(ide.GetEnvironment(), _settings.MemoryGridNonZeroColor, c => { _settings.MemoryGridNonZeroColor = c; }); }), new ToolStripMenuItem("&Pointer color...", null, delegate { color(ide.GetEnvironment(), _settings.MemoryPointerColor, c => { _settings.MemoryPointerColor = c; }); }), new ToolStripMenuItem("&Value font...", null, delegate { font(ide.GetEnvironment(), _settings.MemoryValueFont, Color.CornflowerBlue, f => { _settings.MemoryValueFont = f; _valueColorItem.Enabled = true; }); }), (_valueColorItem = new ToolStripMenuItem("Va&lue color...", null, delegate { color(ide.GetEnvironment(), _settings.MemoryValueFont.Color, c => { _settings.MemoryValueFont = _settings.MemoryValueFont.SetColor(c); }); }) { Enabled = _settings.MemoryValueFont != null }), new ToolStripMenuItem("Ann&otation font...", null, delegate { font(ide.GetEnvironment(), _settings.MemoryAnnotationFont, Color.ForestGreen, f => { _settings.MemoryAnnotationFont = f; _annotationColorItem.Enabled = true; }); }), (_annotationColorItem = new ToolStripMenuItem("Anno&tation color...", null, delegate { color(ide.GetEnvironment(), _settings.MemoryAnnotationFont.Color, c => { _settings.MemoryAnnotationFont = _settings.MemoryAnnotationFont.SetColor(c); }); }) { Enabled = _settings.MemoryAnnotationFont != null }), new ToolStripMenuItem("&Annotate current edge...", null, checkDebugging(ide, env => { var newAnnotation = InputBox.GetLine("Enter annotation:", env.GetCurrentAnnotation(), "Annotate edge", "&OK", "&Cancel"); if (newAnnotation != null) { env.Annotate(newAnnotation); env.UpdateWatch(); } })), (_annotationSets = new ToolStripMenuItem("A&nnotation sets")), new ToolStripMenuItem("&Save memory as PNG...", null, checkDebugging(ide, env => { using (var dlg = new SaveFileDialog { DefaultExt = "png", Filter = "PNG files (*.png)|*.png", OverwritePrompt = true, Title = "Save memory visualization to file" }) if (dlg.ShowDialog() == DialogResult.OK) { env.SaveMemoryVisualization(dlg.FileName); } })))), new ToolStripMenuItem("&Source", null, Ut.NewArray( new ToolStripMenuItem("Generate &blank source...", null, delegate { string inputStr = "10"; while (true) { inputStr = InputBox.GetLine("Enter size of hexagon:", inputStr, "Generate blank source", "&OK", "&Cancel"); if (inputStr == null) { return; } int input; if (int.TryParse(inputStr, out input)) { ide.ReplaceSource(Grid.Parse(new string('.', 3 * input * (input - 1) + 1)).ToString()); return; } DlgMessage.Show("Please enter an integer value.", "Error", DlgType.Error); } }), new ToolStripMenuItem("&Layout source", null, delegate { ide.ReplaceSource(Grid.Parse(ide.GetSource()).ToString()); }), new ToolStripMenuItem("&Minify source", null, delegate { ide.ReplaceSource(Regex.Replace(ide.GetSource(), @"[\s`]", "").TrimEnd('.')); }))), new ToolStripMenuItem("&Input semantics", null, Ut.NewArray( (inputModeItems[0] = new ToolStripMenuItem("Encode input as UTF-&8", null, (_, __) => setInputMode(InputMode.Utf8))), (inputModeItems[1] = new ToolStripMenuItem("Encode input as UTF-1&6 (little endian)", null, (_, __) => setInputMode(InputMode.Utf16))), (inputModeItems[2] = new ToolStripMenuItem("Input string is a list of &bytes", null, (_, __) => setInputMode(InputMode.Numbers)))))); updateAnnotationSets(ide); setInputMode(_settings.InputMode); return(ret); }
public HttpResponse PuzzlePublish(HttpRequest req) { if (req.Method != HttpMethod.Post) { return(HttpResponse.Empty(HttpStatusCode._405_MethodNotAllowed)); } var jsonRaw = req.Post["puzzle"].Value; if (jsonRaw == null || !JsonDict.TryParse(jsonRaw, out var json)) { return(HttpResponse.PlainText("The data transmitted is not valid JSON.", HttpStatusCode._400_BadRequest)); } try { var puzzle = new Puzzle(); puzzle.Title = json["title"].GetString(); puzzle.Author = json["author"].GetString(); puzzle.Rules = json["rules"].GetString(); puzzle.UrlName = MD5.ComputeUrlName(jsonRaw); var givens = json["givens"].GetList().Select((v, ix) => (v, ix)).Where(tup => tup.v != null).Select(tup => (cell: tup.ix, value: tup.v.GetInt())).ToArray(); if (givens.Any(given => given.cell < 0 || given.cell >= 81)) { return(HttpResponse.PlainText($"At least one given is out of range (cell {puzzle.Givens.First(given => given.cell < 0 || given.cell >= 81).cell}).", HttpStatusCode._400_BadRequest)); } puzzle.Givens = givens.Length > 0 ? givens : null; var constraints = json["constraints"].GetList(); var customConstraintTypes = json["customConstraintTypes"].GetList(); using var tr = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.Serializable }); using var db = new Db(); if (db.Puzzles.Any(p => p.UrlName == puzzle.UrlName)) { return(HttpResponse.PlainText(puzzle.UrlName)); } var dbConstraintTypes = constraints.Select(c => c["type"].GetInt()).Where(c => c >= 0).Distinct().ToArray() .Apply(cIds => db.Constraints.Where(c => cIds.Contains(c.ConstraintID))).AsEnumerable().ToDictionary(c => c.ConstraintID); var faultyId = constraints.Select(c => c["type"].GetInt()).Where(c => c >= 0).FirstOrNull(c => !dbConstraintTypes.ContainsKey(c)); if (faultyId != null) { return(HttpResponse.PlainText($"Unknown constraint type ID: {faultyId.Value}.", HttpStatusCode._400_BadRequest)); } // Add the custom constraint types into the database foreach (var constraint in constraints) { if (constraint["type"].GetInt() is int typeId && typeId < 0 && !dbConstraintTypes.ContainsKey(typeId)) { if (~typeId >= customConstraintTypes.Count || customConstraintTypes[~typeId] == null) { return(HttpResponse.PlainText($"Undefined custom constraint type: {typeId}. List has {customConstraintTypes.Count} entries.", HttpStatusCode._400_BadRequest)); } var cType = customConstraintTypes[~typeId]; var kind = EnumStrong.Parse <ConstraintKind>(cType["kind"].GetString()); // Some verifications: // Make sure the variable types parse as valid Suco types var env = new SucoTypeEnvironment(); foreach (var(varName, varType) in cType["variables"].GetDict()) { if (!SucoType.TryParse(varType.GetString(), out var type)) { return(HttpResponse.PlainText($"Unrecognized Suco type: {varType.GetString()}.", HttpStatusCode._400_BadRequest)); } env = env.DeclareVariable(varName, type); }
public static Node[] Parse(string source, int?throwAtIndex = null) { var index = 0; while (index < source.Length && !" \t\n".Contains(source[index])) { index++; } var nodes = new List <Node>(); var instrs = EnumStrong.GetValues <Instruction>().Select(instr => instr.GetCustomAttribute <InstructionAttribute>().Apply(attr => new { Instruction = instr, Str = attr.Instr, Arg = attr.Arg })).ToArray(); while (index < source.Length) { var startIndex = index; var match = instrs .Select(inf => { var newIndex = index; var instrIndex = 0; while (newIndex < source.Length && instrIndex < inf.Str.Length) { if (" \t\n".Contains(source[newIndex])) { if (source[newIndex] == inf.Str[instrIndex]) { instrIndex++; } else { break; } } newIndex++; } if (instrIndex == inf.Str.Length) { return new { Instruction = inf.Instruction, NewIndex = newIndex, Arg = inf.Arg } } ; return(null); }) .Where(inf => inf != null) .FirstOrDefault(); if (match == null) { throw new CompileException($@"Instruction at index {index} not recognized.", index); } index = match.NewIndex; string labelArg = null; BigInteger? numberArg = null; List <bool> argBits = null; if (match.Arg != null) { while (index < source.Length && !" \t\n".Contains(source[index])) { index++; } var origIndex = index; argBits = new List <bool>(); while (index < source.Length && source[index] != '\n') { if (source[index] == ' ') { argBits.Add(false); } else if (source[index] == '\t') { argBits.Add(true); } index++; } if (index == source.Length) { throw new CompileException("Unterminated number literal or label name.", origIndex); } index++; if (match.Arg == ArgKind.Label) { if (argBits.Count >= 8) { var argIndex = 0; var bytes = new List <byte>(); while (argIndex < argBits.Count - 8) { bytes.Add((byte)argBits.Skip(argIndex).Take(8).Aggregate(0, (prev, next) => (prev << 1) | (next ? 1 : 0))); argIndex += 8; } bytes.Add((byte)argBits.Skip(argIndex).Aggregate(0, (prev, next) => (prev << 1) | (next ? 1 : 0))); labelArg = bytes.ToArray().FromUtf8(); } else { labelArg = argBits.Select(b => b ? '1' : '0').JoinString(); } } else { if (argBits.Count == 0) { throw new CompileException("Expected a number (need at least one space or tab before the terminating linefeed).", origIndex); } var bi = BigInteger.Zero; for (int i = 1; i < argBits.Count; i++) { bi = (bi << 1) | (argBits[i] ? 1 : 0); } numberArg = argBits[0] ? -bi : bi; } } if (throwAtIndex != null && startIndex <= throwAtIndex.Value && index > throwAtIndex.Value) { throw new ParseInfoException(match.Instruction, argBits, numberArg, labelArg); } nodes.Add(new Node(new Position(startIndex, index - startIndex), match.Instruction, numberArg, labelArg)); while (index < source.Length && !" \t\n".Contains(source[index])) { index++; } } nodes.Add(new Node(new Position(source.Length, 0), Instruction.Exit)); return(nodes.ToArray()); }
public static void RunSimulation() { const int iterations = 100000; var portTypes = EnumStrong.GetValues <PortType>(); var portTypeToDir = new int[6]; portTypeToDir[(int)PortType.Parallel] = 0; portTypeToDir[(int)PortType.DVI] = 1; portTypeToDir[(int)PortType.StereoRCA] = 2; portTypeToDir[(int)PortType.Serial] = 3; portTypeToDir[(int)PortType.PS2] = 4; portTypeToDir[(int)PortType.RJ45] = 5; var countConds = new Dictionary <string, int>(); for (int i = 0; i < iterations; i++) { var edgework = Edgework.Generate(5, 7); var counts = Ut.NewArray(edgework.GetNumPortPlates() + 1, j => j == 0 ? portTypes.ToHashSet() : new HashSet <PortType>()); foreach (var port in edgework.Widgets.Where(w => w.PortTypes != null).SelectMany(w => w.PortTypes)) { var ix = counts.IndexOf(c => c.Contains(port)); counts[ix].Remove(port); counts[ix + 1].Add(port); } var hexes = Hex.LargeHexagon(5).Select(hex => { Console.WriteLine(edgework); // Check the port types in order of most common to least common. for (int c = counts.Length - 1; c >= 0; c--) { // Check which of these port types can form a line of 5 var eligiblePortTypes = counts[c].Where(pt => Enumerable.Range(0, 5).All(dist => (hex + dist * Hex.GetDirection(portTypeToDir[(int)pt])).Distance < 5)).Take(2).ToArray(); if (eligiblePortTypes.Length != 1) { continue; } // We found an eligible port type; return the line return(new { Hex = hex, PortType = (PortType?)eligiblePortTypes[0], Line = Enumerable.Range(0, 5).Select(dist => hex + dist * Hex.GetDirection(portTypeToDir[(int)eligiblePortTypes[0]])).ToArray() }); } // Check if the two-step rule works for this hex for (int dir = 0; dir < 6; dir++) { if (Enumerable.Range(0, 5).All(dist => (hex + 2 * dist * Hex.GetDirection(dir)).Distance < 5)) { return new { Hex = hex, PortType = (PortType?)null, Line = Enumerable.Range(0, 5).Select(dist => hex + 2 * dist * Hex.GetDirection(dir)).ToArray() } } } ; return(null); }).ToArray(); } foreach (var kvp in countConds) { Console.WriteLine($"{kvp.Key} = {kvp.Value / (double) iterations * 100:0.00}%"); } }