diff --git a/projects/Four4Sample/Four4.Test/NumberTest.cs b/projects/Four4Sample/Four4.Test/NumberTest.cs index 1a011c0..ab57301 100644 --- a/projects/Four4Sample/Four4.Test/NumberTest.cs +++ b/projects/Four4Sample/Four4.Test/NumberTest.cs @@ -16,7 +16,7 @@ public sealed class NumberTest [InlineData("4444")] public void WholeNumbers(string input) { - Number.Parse(input).IsWhole.Should().BeTrue(); + Parse(input).IsWhole.Should().BeTrue(); } [Theory] @@ -24,7 +24,7 @@ public void WholeNumbers(string input) [InlineData(".4_")] public void Fractions(string input) { - Number.Parse(input).IsWhole.Should().BeFalse(); + Parse(input).IsWhole.Should().BeFalse(); } [Theory] @@ -43,9 +43,17 @@ public void NonPositiveNumbersAreNotWhole(string input) [InlineData("4444", 4444)] public void CastToInt32(string input, int result) { - int value = (int)Number.Parse(input); + int value = (int)Parse(input); value.Should().Be(result); } + + private static Number Parse(string input) + { + Number number; + bool valid = Number.TryParse(input, out number, out int d); + valid.Should().BeTrue(); + return number; + } } } diff --git a/projects/Four4Sample/Four4/Expression.cs b/projects/Four4Sample/Four4/Expression.cs index 6ff077d..2b781cc 100644 --- a/projects/Four4Sample/Four4/Expression.cs +++ b/projects/Four4Sample/Four4/Expression.cs @@ -62,11 +62,11 @@ public Expression Append(string token) case "R": return this.Unary(token, x => x.SquareRoot()); default: + Number number; int add; - if (IsNumeric(token, out add)) + if (Number.TryParse(token, out number, out add)) { - Number number = Number.Parse(token); - return this.Push(add, token, Number.Parse(token)); + return this.Push(add, token, number); } else { @@ -75,41 +75,6 @@ public Expression Append(string token) } } - private static bool IsNumeric(string token, out int add) - { - add = 0; - int n = token.Length; - for (int i = 0; i < n; ++i) - { - char d = token[i]; - switch (d) - { - case '4': - ++add; - break; - case '.': - if (i > 0) - { - return false; - } - - break; - case '_': - if (i < (n - 1)) - { - return false; - } - - break; - - default: - return false; - } - } - - return add > 0; - } - private Expression Push(int add, string token, Number number) { return new Expression(this.count + add, this.Join(token), this.operands.Push(number)); diff --git a/projects/Four4Sample/Four4/Number.cs b/projects/Four4Sample/Four4/Number.cs index 8e40454..c2c1cd6 100644 --- a/projects/Four4Sample/Four4/Number.cs +++ b/projects/Four4Sample/Four4/Number.cs @@ -71,17 +71,55 @@ public Number(int num, int denom) return left * new Number(right.denom, right.num); } - public static Number Parse(string s) + public static bool TryParse(string s, out Number number, out int digits) { - switch (s) + number = NaN; + digits = 0; + int a = 0; + int b = s.Length; + int nr = 0; + int dr = 0; + int f = 1; + + if (b == 0) + { + return false; + } + + if (s[0] == '.') + { + a = 1; + f = 10; + } + + if (s[b - 1] == '_') + { + --b; + f = 9; + } + + for (int i = a; i < b; ++i) { - case ".4": - return new Number(2, 5); - case ".4_": - return new Number(4, 9); - default: - return new Number(int.Parse(s), 1); + int d = s[i] - '0'; + if (d != 4) + { + return false; + } + + nr = (10 * nr) + d; + ++digits; + if (f != 1) + { + dr = (dr * 10) + f; + } + else + { + dr = 1; + } } + + number = new Number(nr, dr); + return true; } public Number Factorial()