private static void Main(string[] args) { var gen = new Generator(); gen.Iterate(); var rz = gen.Results.OrderBy(p => Math.Abs(p.Key - Math.Round(p.Key))).ThenBy(p => p.Value.Count); Console.WriteLine("Completed in {0} iterations", gen.IterationCount); using (var fw = File.CreateText("numbers.html")) { fw.WriteLine("<h1>Possible combinations for {0}</h1>", string.Join(", ", gen.Sources)); fw.WriteLine("<table>"); fw.WriteLine("<tr><td>#</td><td>expressions</td></tr>"); foreach (var item in rz) { fw.WriteLine("<tr>"); fw.Write("<td>"); fw.WriteLine("{0,3} results for {1}:", item.Value.Count, DecimalToFraction(item.Key)); fw.Write("</td>"); fw.Write("<td style='border-bottom: 1px solid black'>"); foreach (var expression in item.Value) { var vc = new EvaluationHashVisitor(); vc.Visit(expression); fw.WriteLine("{0,20} [{1}]<br/>", expression, vc.DivisionVisitCount); } fw.Write("</td>"); fw.Write("</tr>"); } fw.Write("</table>"); } }
public void Iterate() { var stack = new Stack <Snapshot>(); //seed stack with constant roots foreach (var constant in Sources) { var ss = new Snapshot { Tree = Expression.Constant(constant), AvailableConstants = new List <decimal>(Sources.Where(c => c != constant)) }; ss.ActiveSite = ss.Tree; stack.Push(ss); } //expand tree while (stack.Count != 0) { IterationCount++; var snapshot = stack.Pop(); var evaluationHashVisitor = new EvaluationHashVisitor(); evaluationHashVisitor.Visit(snapshot.Tree); if (!snapshot.AvailableConstants.Any()) { decimal val; if (Compiled.Contains(evaluationHashVisitor.Hash)) { continue; } Compiled.Add(evaluationHashVisitor.Hash); try { val = Expression.Lambda <Func <decimal> >(snapshot.Tree).Compile()(); } catch (DivideByZeroException) { continue; } List <Expression> list; val = Math.Abs(decimal.Round(val, 4)); if (!Results.TryGetValue(val, out list)) { list = new List <Expression>(); Results[val] = list; } list.Add(snapshot.Tree); continue; } //some constants left, so expand foreach (var constant in snapshot.AvailableConstants) { foreach (var expressionType in _operationTypes) { for (int direction = 0; direction < 2; direction++) { //dont spawn excessive b*a variant if spawned a*b if (direction != 0 && (expressionType == ExpressionType.Multiply || expressionType == ExpressionType.Add)) { continue; } var spawn = new Snapshot(); var vtor = new ExpandConstExpressionVisitor(snapshot.ActiveSite, expressionType, constant, direction == 0); spawn.Tree = vtor.Visit(snapshot.Tree); spawn.ActiveSite = vtor.ActiveSite; spawn.AvailableConstants = new List <decimal>(snapshot.AvailableConstants.Where(ac => ac != constant)); stack.Push(spawn); } } } } }