Created
October 10, 2014 08:44
-
-
Save sudipto80/ccb75622b3f83b33b3f1 to your computer and use it in GitHub Desktop.
Armstrong DSL ( You need Evaluant LINQ Compiler)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class IntEx | |
{ | |
public static int Cube(this int number) | |
{ | |
return number * number * number; | |
} | |
public static int Square(this int number) | |
{ | |
return number * number; | |
} | |
public static IEnumerable<int> Digits(this int number) | |
{ | |
return number.ToString().ToCharArray().Select (n => | |
Convert.ToInt32(n.ToString())); | |
} | |
public static IEnumerable<int> ReverseDigits(this int number) | |
{ | |
return number.Digits().Reverse(); | |
} | |
public static IEnumerable<int> EvenDigits(this int number) | |
{ | |
return number.ToString().ToCharArray() | |
.Where ((m,i) => i%2==0).Select (n => Convert.ToInt32(n.ToString())); | |
} | |
public static IEnumerable<int> OddDigits(this int number) | |
{ | |
return number.ToString().ToCharArray() | |
.Where ((m,i) => i%2!=0).Select (n => Convert.ToInt32(n.ToString())); | |
} | |
public static bool Are(this IEnumerable<int> actualDigits, params int[] digits) | |
{ | |
return actualDigits.SequenceEqual(digits); | |
} | |
public static IEnumerable<int> DigitsAt(this int number, params int[] indices) | |
{ | |
var asString = number.ToString(); | |
return indices.Select (i => Convert.ToInt32(asString[i].ToString())); | |
} | |
public static bool AreZero(this IEnumerable<int> digits) | |
{ | |
return digits.All (d => d == 0); | |
} | |
public static int FormNumber(this IEnumerable<int> digits) | |
{ | |
return digits.Select ((d,i) => d * (int)Math.Pow (10,digits.Count()-(i+1))) | |
.Aggregate ((a,b) => a + b); | |
} | |
public static IEnumerable<int> Factorial(this IEnumerable<int> digits) | |
{ | |
foreach (var d in digits) | |
if (d == 0) | |
yield return 1; | |
else | |
yield return Enumerable.Range(1, d).Aggregate((a, b) => a * b); | |
} | |
public static int Product(this IEnumerable<int> digits) | |
{ | |
return digits.Aggregate ((f,s) => f*s); | |
} | |
public static IEnumerable<int> Square(this IEnumerable<int> digits) | |
{ | |
return digits.Select (d => d * d); | |
} | |
public static IEnumerable<int> RaiseSelfToSelf(this IEnumerable<int> digits) | |
{ | |
return digits.Select (d => (int) Math.Pow(d,d)); | |
} | |
public static IEnumerable<int> IncrementalPower(this IEnumerable<int> digits) | |
{ | |
return digits.Select ((d,i) => (int) Math.Pow(d , i)); | |
} | |
} | |
private static string SanitizeBraces(string generatedStatement) | |
{ | |
int gap = generatedStatement.ToCharArray().Count(c => c == '(') - | |
generatedStatement.ToCharArray().Count(c => c == ')'); | |
if (gap == 0) | |
return generatedStatement; | |
else | |
return generatedStatement + new string(')', gap); | |
} | |
private static string GenerateArmStrongStatement(List<string> tokens) | |
{ | |
Dictionary<string, string> mapping = new Dictionary<string, string>(); | |
mapping.Add("*", "*"); | |
mapping.Add("times", "*"); | |
mapping.Add("(", ")"); | |
mapping.Add(")", "("); | |
mapping.Add("are-same", ".IsSame()"); | |
mapping.Add("==", "=="); | |
mapping.Add("proper-divisors", ".ProperDivisors()"); | |
mapping.Add("even-digits", ".EvenDigits()"); | |
mapping.Add("odd-digits", ".OddDigits()"); | |
mapping.Add("number", "n"); | |
mapping.Add("square", ".Square()"); | |
mapping.Add("product", ".Product()"); | |
mapping.Add("is", "=="); | |
mapping.Add("!=", "!="); | |
mapping.Add("+", "+"); | |
mapping.Add("-", "-"); | |
mapping.Add("and", "&&"); | |
mapping.Add("or", "||"); | |
mapping.Add("/", "/"); | |
mapping.Add(">", "<"); | |
mapping.Add("<", ">"); | |
mapping.Add("<=", ">="); | |
mapping.Add(">=", "<="); | |
mapping.Add("divided-by", "/"); | |
mapping.Add("are", ".Are("); | |
mapping.Add("digits", ".Digits()"); | |
mapping.Add("reverse-digits",".ReverseDigits()"); | |
mapping.Add("cube", ".Cube()"); | |
mapping.Add("factorial", ".Factorial()"); | |
mapping.Add("sum", ".Sum()"); | |
//Add all normal LINQ operators | |
mapping.Add("average", ".Average()"); | |
mapping.Add("maximum", ".Max()"); | |
mapping.Add("minimum", ".Min()"); | |
mapping.Add("digits-at", ".DigitsAt("); | |
StringBuilder armstrongBuilder = new StringBuilder(); | |
foreach (string to in tokens) | |
{ | |
if (mapping.ContainsKey(to)) | |
armstrongBuilder.Append(mapping[to]); | |
if (to.ToCharArray().All(t => Char.IsNumber(t) || t == '.')) | |
armstrongBuilder.Append(to); | |
} | |
return SanitizeBraces("input.Where ( n => " + armstrongBuilder.ToString() + ")"); | |
} | |
private static List<string> GetTokens(string phrase) | |
{ | |
string[] specialOnes = {"are-same","digits-at"}; | |
if(specialOnes.Any (o => phrase.EndsWith(o))) | |
{ | |
return phrase.Split(new string[] { "of", "the", " " }, StringSplitOptions.RemoveEmptyEntries).ToList(); | |
} | |
else | |
{ | |
Stack<string> tokens = new Stack<string>(); | |
phrase.Split(new string[] { "of", "the", " " }, StringSplitOptions.RemoveEmptyEntries) | |
.ToList() | |
.ForEach(t => tokens.Push(t)); | |
tokens.Dump(); | |
return tokens.ToList(); | |
} | |
} | |
void Main() | |
{ | |
do | |
{ | |
var inputs = Enumerable.Range(1, 10000); | |
Console.WriteLine("Armstrong >>"); | |
string line = Console.ReadLine() | |
.Replace("(", "( ") | |
.Replace(")", " )"); | |
string statement = GenerateArmStrongStatement(GetTokens(line)); | |
LinqCompiler lc = new LinqCompiler(statement); | |
lc.ExternalAssemblies.Add(typeof(IntEx).Assembly); | |
// lc.ExternalAssemblies.Add(typeof(MathEx).Assembly); | |
lc.AddSource("input", inputs); | |
line.Dump("Armstrong Query Expressed in Plain English"); | |
statement.Dump("Generated LINQ Query"); | |
lc.Evaluate().Dump("Answers"); | |
} while (true); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment