Last active
August 29, 2015 13:56
-
-
Save JohanLarsson/8977845 to your computer and use it in GitHub Desktop.
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 class Polynom | |
| { | |
| public Polynom(params double[] coefficients) | |
| { | |
| Coefficients = coefficients; | |
| } | |
| public static Polynom Parse(string s) | |
| { | |
| var cs = new Dictionary<int, double>(); | |
| var reader = new PolynomReader(s); | |
| if (reader.HasLeftSide) | |
| reader.ReadLeftSide(); | |
| while (!reader.IsEos) | |
| { | |
| var sign = reader.ReadSign(); | |
| double c = reader.ReadCoefficient(); | |
| var i = reader.ReadDegree(); | |
| cs.Add(i, sign * c); | |
| } | |
| var coffs = new double[cs.Keys.Max() + 1]; | |
| foreach (var c in cs) | |
| { | |
| coffs[c.Key] = c.Value; | |
| } | |
| return new Polynom(coffs); | |
| } | |
| public double[] Coefficients { get; private set; } | |
| public double CalcY(double x) | |
| { | |
| double y = 0; | |
| for (int i = 0; i < Coefficients.Count(); i++) | |
| { | |
| y += Coefficients[i] * Math.Pow(x, i); | |
| } | |
| return y; | |
| } | |
| public override string ToString() | |
| { | |
| return ToString("n3"); | |
| } | |
| public string ToString(int digits) | |
| { | |
| return ToString("n" + digits); | |
| } | |
| public string ToString(string format) | |
| { | |
| var sb = new StringBuilder(); | |
| sb.Append("y = "); | |
| bool hasTerm = false; | |
| for (int i = 0; i < Coefficients.Length; i++) | |
| { | |
| var c = Coefficients[i]; | |
| if (c == 0) | |
| continue; | |
| if (hasTerm) | |
| { | |
| if (c > 0) | |
| sb.Append(" + "); | |
| else | |
| { | |
| sb.Append(" - "); | |
| } | |
| } | |
| else | |
| { | |
| if (c < 0) | |
| sb.Append("-"); | |
| } | |
| hasTerm = true; | |
| if (Math.Abs(c) == 1 && i > 0) | |
| { | |
| sb.Append("x"); | |
| } | |
| else if (i > 0) | |
| { | |
| sb.AppendFormat("{0} * x", Math.Abs(c).ToString(format)); | |
| } | |
| switch (i) | |
| { | |
| case 0: | |
| sb.Append(Math.Abs(c).ToString(format)); | |
| break; | |
| case 1: | |
| break; | |
| default: | |
| sb.AppendFormat("^{0}", i); | |
| break; | |
| } | |
| } | |
| return sb.ToString(); | |
| } | |
| private class PolynomReader : StringReader | |
| { | |
| private StringBuilder sb = new StringBuilder(); | |
| public PolynomReader(string s) | |
| : base(s) | |
| { | |
| if (string.IsNullOrEmpty(s)) | |
| throw new FormatException("Input string was not in a correct format."); | |
| } | |
| public void MoveToContent() | |
| { | |
| while (Peek() != -1 && char.IsWhiteSpace(PeekChar())) | |
| { | |
| base.Read(); | |
| } | |
| } | |
| public int ReadSign() | |
| { | |
| MoveToContent(); | |
| var c = PeekChar(); | |
| if (char.IsNumber(c) || c == 'x') | |
| { | |
| return 1; | |
| } | |
| if (c == '+') | |
| { | |
| base.Read(); | |
| return 1; | |
| } | |
| if (c == '-') | |
| { | |
| base.Read(); | |
| return -1; | |
| } | |
| throw new FormatException("Input string was not in a correct format."); | |
| } | |
| public double ReadDouble() | |
| { | |
| MoveToContent(); | |
| this.sb.Clear(); | |
| var c = PeekChar(); | |
| if (!char.IsNumber(c)) | |
| throw new FormatException("Input string was not in a correct format."); | |
| while (char.IsNumber(c) || c == '.' || c=='e' || c=='E') | |
| { | |
| c = ReadChar(); | |
| sb.Append(c); | |
| if (IsEos) | |
| break; | |
| c = PeekChar(); | |
| } | |
| var value = double.Parse(sb.ToString(), CultureInfo.InvariantCulture); | |
| sb.Clear(); | |
| return value; | |
| } | |
| public int ReadInt() | |
| { | |
| MoveToContent(); | |
| this.sb.Clear(); | |
| var c = PeekChar(); | |
| while (char.IsNumber(c)) | |
| { | |
| c = ReadChar(); | |
| sb.Append(c); | |
| if (IsEos) | |
| break; | |
| c = PeekChar(); | |
| } | |
| var value = int.Parse(sb.ToString()); | |
| sb.Clear(); | |
| return value; | |
| } | |
| public int ReadDegree() | |
| { | |
| MoveToContent(); | |
| var c = PeekChar(); | |
| if (c == 'x') | |
| { | |
| Read(); | |
| MoveToContent(); | |
| c = PeekChar(); | |
| if (c != '^') | |
| { | |
| return 1; | |
| } | |
| Read(); | |
| return ReadInt(); | |
| } | |
| if (c == '*') | |
| { | |
| Read(); | |
| MoveToContent(); | |
| c = PeekChar(); | |
| if (char.IsNumber(c) || c == 'x') | |
| return ReadDegree(); | |
| throw new FormatException("Input string was not in a correct format."); | |
| } | |
| return 0; | |
| } | |
| public double ReadCoefficient() | |
| { | |
| MoveToContent(); | |
| var c = PeekChar(); | |
| if (c == 'x') | |
| { | |
| return 1; | |
| } | |
| return ReadDouble(); | |
| } | |
| public bool IsEos | |
| { | |
| get | |
| { | |
| MoveToContent(); | |
| return Peek() == -1; | |
| } | |
| } | |
| public void ReadLeftSide() | |
| { | |
| while (PeekChar() != '=' && Peek() != -1) | |
| { | |
| Read(); | |
| } | |
| var c = ReadChar(); | |
| if (c == '=') | |
| return; | |
| throw new FormatException("Input string was not in a correct format."); | |
| } | |
| public bool HasLeftSide | |
| { | |
| get | |
| { | |
| MoveToContent(); | |
| return PeekChar() == 'y'; | |
| } | |
| } | |
| public char PeekChar() | |
| { | |
| return (char)base.Peek(); | |
| } | |
| public char ReadChar() | |
| { | |
| return (char)base.Read(); | |
| } | |
| } | |
| } |
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 class PolynomTests | |
| { | |
| [TestCase(new double[] { 0, 1 }, "y = x")] | |
| [TestCase(new double[] { 1, 1 }, "y = 1 + x")] | |
| [TestCase(new double[] { -2, 1 }, "y = -2 + x")] | |
| [TestCase(new double[] { 2, 2 }, "y = 2 + 2 * x")] | |
| [TestCase(new double[] { 0, 0, 1 }, "y = x^2")] | |
| [TestCase(new double[] { 0, 0, -1 }, "y = -x^2")] | |
| [TestCase(new double[] { 1, 1, 1 }, "y = 1 + x + x^2")] | |
| [TestCase(new double[] { 2, 2, 2 }, "y = 2 + 2 * x + 2 * x^2")] | |
| [TestCase(new double[] { -1, -1, -1 }, "y = -1 - x - x^2")] | |
| [TestCase(new double[] { -2, -2, -2 }, "y = -2 - 2 * x - 2 * x^2")] | |
| public void ToStringTests(double[] coffs, string e) | |
| { | |
| var polynom = new Polynom(coffs); | |
| Assert.AreEqual(e, polynom.ToString(0)); | |
| } | |
| [TestCase("y = x", 0, 0)] | |
| [TestCase("y = x", 1, 1)] | |
| [TestCase("y = x", 2, 2)] | |
| [TestCase("y = x", -2, -2)] | |
| [TestCase("y = -x", 0, 0)] | |
| [TestCase("y = -x", 2, -2)] | |
| [TestCase("y = -x", -2, 2)] | |
| [TestCase("y = 2 + x", 0, 2)] | |
| [TestCase("y = 2 + 2 * x", 0, 2)] | |
| public void CalcYTest(string ps, double x, double ey) | |
| { | |
| var polynom = Polynom.Parse(ps); | |
| var y = polynom.CalcY(x); | |
| Assert.AreEqual(ey, y); | |
| } | |
| [TestCase("y = x", new double[] { 0, 1 })] | |
| [TestCase("y = x^2", new double[] { 0, 0, 1 })] | |
| [TestCase("y = 1 + x", new double[] { 1, 1 })] | |
| [TestCase("y = -2 + x", new double[] { -2, 1 })] | |
| [TestCase("y = 2 + 2 * x", new double[] { 2, 2 })] | |
| [TestCase("y = x^2", new double[] { 0, 0, 1 })] | |
| [TestCase("y = -x^2", new double[] { 0, 0, -1 })] | |
| [TestCase("y = 1 + x + x^2", new double[] { 1, 1, 1 })] | |
| [TestCase("y = 2 + 2 * x + 2 * x^2", new double[] { 2, 2, 2 })] | |
| [TestCase("y = -1 - x - x^2", new double[] { -1, -1, -1 })] | |
| [TestCase("y = -2 - 2 * x - 2 * x^2", new double[] { -2, -2, -2 })] | |
| [TestCase("y = -2.0 - 2.0 * x - 2.0 * x^2", new double[] { -2, -2, -2 })] | |
| [TestCase("y = -2.0 - 2.0x - 2.0x^2", new double[] { -2, -2, -2 })] | |
| [TestCase("y = - 2.0 * x - 2.0 - 2.0 * x^2", new double[] { -2, -2, -2 })] | |
| [TestCase("y = - 2.0 * x - 2.0 - 2.0 * x^2.0", new double[] { -2, -2, -2 }, ExpectedException = typeof(FormatException))] | |
| [TestCase("y = -2.0e-3 * x - 2.0 - 2.0 * x^2.0", new double[] { -0.002, -2, -2 }, ExpectedException = typeof(FormatException))] | |
| [TestCase("y = x^2 +x^3", new double[] { 0, 0, 1, 1 })] | |
| public void ParseTest(string s, double[] e) | |
| { | |
| var polynom = Polynom.Parse(s); | |
| Assert.AreEqual(e.Length, polynom.Coefficients.Length); | |
| for (int i = 0; i < e.Length; i++) | |
| { | |
| Assert.AreEqual(e[i], polynom.Coefficients[i]); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment