// signsNumber - not digits - places between them private static void Problem10598(string filename, int signsNumber, bool allowNegative = true) { var sb = new StringBuilder(); for (var i = 1; i <= signsNumber + 1; i++) { sb.Append(i); } long totalExpr = 0; long matchedExpr = 0; var map = new Dictionary <double, string>(); var startTime = DateTime.Now; var fileInfo = new FileInfo(filename); using (var sw = new StreamWriter(fileInfo.Open(FileMode.Create))) { sw.WriteLine("============================="); var bracesEnumerator = new BracesEnumerator(sb.ToString(), allowNegative); var trees = bracesEnumerator.Braces(signsNumber, 0); foreach (var tree in trees) { totalExpr++; var res = tree.Evaluate(); if (Math.Abs(res - Math.Round(res)) > BracesEnumerator.Epsilon) { // ignore with fraction part //continue; } if (Math.Abs(res) > 20_000) { // ignore too large //continue; } if (Math.Abs(res) < BracesEnumerator.Epsilon) { // ignore numbers like 1.0E-117 // NOTE: zero is ignored too! //continue; } if (!map.ContainsKey(res)) { matchedExpr++; map[res] = tree.ToString(); } if (totalExpr % 1000000 == 0) { sw.Flush(); Console.WriteLine($"totalExpr = {totalExpr}"); } } var diffTime = DateTime.Now - startTime; sw.WriteLine( $"total {totalExpr} in {diffTime.TotalMilliseconds} => {totalExpr / diffTime.TotalMilliseconds} records/ms"); sw.WriteLine( $"real {matchedExpr} in {diffTime.TotalMilliseconds} => {matchedExpr/ diffTime.TotalMilliseconds} records/ms"); Console.WriteLine( $"total {totalExpr} in {diffTime.TotalMilliseconds} => {totalExpr / diffTime.TotalMilliseconds} records/ms"); Console.WriteLine( $"real {matchedExpr} in {diffTime.TotalMilliseconds} => {matchedExpr / diffTime.TotalMilliseconds} records/ms"); Console.WriteLine( $"total/real {(double)totalExpr / matchedExpr}"); // print keys in sorted order { sw.WriteLine("-------- The same sorted --------"); var keys = map.Keys.ToArray(); Array.Sort(keys); var prev = 2.0; var lastOk = 2.0; foreach (var key in keys) { //Console.WriteLine($"{key} = {map[key]}"); sw.WriteLine($"{key} = {map[key]}"); if (key >= prev && Math.Abs(lastOk - 2.0) < BracesEnumerator.Epsilon) { if (Math.Abs(key - prev - 1.0) >= BracesEnumerator.Epsilon && Math.Abs(key - prev) >= BracesEnumerator.Epsilon) { // not OK lastOk = prev; } prev = key; } } sw.WriteLine($"lastOk: {lastOk}"); } } }
public static void BarnaulHappyTickets(int fromIndex, int toIndex, string filename, bool allowNegative = true) { const int signsNumber = 5; // not digits - places between them long totalExpr = 0; long matchedExpr = 0; var startTime = DateTime.Now; var fileInfo = new FileInfo(filename); var workingFileMode = FileMode.Create; // fail over (for continue work after program stop) // if the last valuable line starts with number, continue from 1st number in the line var failoverFileInfo = new FileInfo($"lock-index-{fromIndex}-{toIndex}.txt"); if (failoverFileInfo.Exists && failoverFileInfo.Length > 0) { using (var sr = new StreamReader(failoverFileInfo.Name)) { var line = sr.ReadLine(); if (!int.TryParse(line, out var lastIndex)) { throw new Exception($"Cannot parse {line}"); } fromIndex = lastIndex + 1; // start from the next workingFileMode = FileMode.Append; } } using (var sw = new StreamWriter(fileInfo.Open(workingFileMode))) { sw.WriteLine("============================="); for (int i = fromIndex; i <= toIndex; i++) { var bracesEnumerator = new BracesEnumerator(UnknownTickets[i].ToString("000000"), allowNegative); var trees = bracesEnumerator.Braces(signsNumber, 0); foreach (var tree in trees) { totalExpr++; var res = tree.Evaluate(); if (Math.Abs(res - 100) < 1.0E-12) { matchedExpr++; var treeStr = tree.ToString(); sw.WriteLine($"{UnknownTickets[i]} : {treeStr}"); break; } const int divider = 1000_000; if (totalExpr % divider == 0) { sw.Flush(); Console.WriteLine($"totalExpr = {totalExpr / divider} M, thread {fromIndex} in {(DateTime.Now - startTime).TotalMilliseconds} ms"); Thread.Sleep(10); // allow other threads to do smth } } using (var lockSw = new StreamWriter(failoverFileInfo.Name)) { lockSw.WriteLine(i); } } var diffTime = DateTime.Now - startTime; sw.WriteLine( $"total {totalExpr} in {diffTime.TotalMilliseconds} => {totalExpr / diffTime.TotalMilliseconds} records/ms"); sw.WriteLine( $"real {matchedExpr} in {diffTime.TotalMilliseconds} => {matchedExpr/ diffTime.TotalMilliseconds} records/ms"); Console.WriteLine( $"total {totalExpr} in {diffTime.TotalMilliseconds} => {totalExpr / diffTime.TotalMilliseconds} records/ms"); Console.WriteLine( $"real {matchedExpr} in {diffTime.TotalMilliseconds} => {matchedExpr / diffTime.TotalMilliseconds} records/ms"); } }