diff --git a/Yolol.Cylon/Deserialisation/Versions/V_0_3_0.cs b/Yolol.Cylon/Deserialisation/Versions/V_0_3_0.cs index f5efca2..b04b44c 100644 --- a/Yolol.Cylon/Deserialisation/Versions/V_0_3_0.cs +++ b/Yolol.Cylon/Deserialisation/Versions/V_0_3_0.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using Newtonsoft.Json.Linq; using Semver; @@ -132,7 +133,7 @@ private BaseExpression ParseExpression(JToken jtok) return ParseUnaryExpression(jtok); case "expression::number": - return new ConstantNumber((Number)decimal.Parse(jtok.Value("num"))); + return new ConstantNumber((Number)decimal.Parse(jtok.Value("num"), CultureInfo.InvariantCulture)); case "expression::string": return new ConstantString(jtok.Value("str")); diff --git a/Yolol.Cylon/Deserialisation/Versions/V_1_X_X.cs b/Yolol.Cylon/Deserialisation/Versions/V_1_X_X.cs index c9766c5..e8041fc 100644 --- a/Yolol.Cylon/Deserialisation/Versions/V_1_X_X.cs +++ b/Yolol.Cylon/Deserialisation/Versions/V_1_X_X.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Linq; using Newtonsoft.Json.Linq; using Yolol.Execution; @@ -192,7 +193,7 @@ BaseExpression ParseModify(string op) return ParseModify(type[2]); case "number": - return new ConstantNumber((Number)decimal.Parse(jtok.Value("num"))); + return new ConstantNumber((Number)decimal.Parse(jtok.Value("num"), CultureInfo.InvariantCulture)); case "string": return new ConstantString(jtok.Value("str")); diff --git a/Yolol/Execution/Number.cs b/Yolol/Execution/Number.cs index 5bd8ad1..bbb3e62 100644 --- a/Yolol/Execution/Number.cs +++ b/Yolol/Execution/Number.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Runtime.CompilerServices; using Yolol.Execution.Attributes; @@ -124,13 +125,13 @@ public override int GetHashCode() public static Number Parse(string s) { // First check if the number is out of the valid range - var d = double.Parse(s); + var d = double.Parse(s, CultureInfo.InvariantCulture); if (d >= MaxValue._value) return MaxValue; else if (d <= MinValue._value) return MinValue; - return (Number)decimal.Parse(s); + return (Number)decimal.Parse(s, CultureInfo.InvariantCulture); } public static explicit operator Number(bool b) diff --git a/Yolol/Grammar/Parser.cs b/Yolol/Grammar/Parser.cs index 4e54378..a559b7f 100644 --- a/Yolol/Grammar/Parser.cs +++ b/Yolol/Grammar/Parser.cs @@ -16,7 +16,7 @@ public static Result ParseProgram(string program) catch (FormatException e) { var c = e.Data["cursor"] as Cursor; - return new Result(new ParseError(c!, e.Message)); + return new Result(new ParseError(c, e.Message)); } } @@ -65,10 +65,10 @@ public Result(TErr err) public class ParseError { - public Cursor Cursor { get; } + public Cursor? Cursor { get; } public string Message { get; } - public ParseError(Cursor cursor, string message) + public ParseError(Cursor? cursor, string message) { message = message .Replace("\r", "\\r") @@ -80,6 +80,9 @@ public ParseError(Cursor cursor, string message) public override string ToString() { + if (Cursor == null) + return Message; + var spaces = new string(' ', Math.Max(0, Cursor.Column - 2)); return $"{Cursor.Subject}\n" diff --git a/Yolol/Yolol.csproj b/Yolol/Yolol.csproj index e1de5f1..beb366b 100644 --- a/Yolol/Yolol.csproj +++ b/Yolol/Yolol.csproj @@ -9,7 +9,7 @@ https://github.com/martindevans/Yolol https://github.com/martindevans/Yolol true - 13.0.0 + 13.0.1 8.0 enable AnyCPU;x64 diff --git a/YololEmulator.Tests/Ladder/PrimeCountingFunction.cs b/YololEmulator.Tests/Ladder/PrimeCountingFunction.cs new file mode 100644 index 0000000..40729d8 --- /dev/null +++ b/YololEmulator.Tests/Ladder/PrimeCountingFunction.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Yolol.Execution; + +namespace YololEmulator.Tests.Ladder +{ + [TestClass] + public class PrimeCountingFunction + : BaseGenerator + { + private readonly Dictionary _cache = new(); + + [TestMethod] + public void Generate() + { + Run(34923, 10000, false, Generator.ScoreMode.BasicScoring); + } + + protected override bool GenerateCase(Random random, int index, Dictionary inputs, Dictionary outputs) + { + var i = index + 1; + inputs.Add("i", i); + outputs.Add("o", PrimeCount(i)); + return true; + } + + private int PrimeCount(int n) + { + var count = n >= 2 ? 1 : 0; + for (var i = 3; i < n; i += 2) + if (IsOddIntPrime(i)) + count++; + return count; + } + + private bool IsOddIntPrime(int number) + { + if (number <= 1) + return false; + if (_cache.TryGetValue(number, out var cached)) + return cached; + + var boundary = (int)Math.Floor(Math.Sqrt(number)); + + for (var i = 3; i <= boundary; i += 2) + { + if (number % i == 0) + { + _cache[number] = false; + return false; + } + } + + _cache[number] = true; + return true; + } + } +} diff --git a/YololEmulator/YololEmulator.csproj b/YololEmulator/YololEmulator.csproj index 482fd75..ff1997f 100644 --- a/YololEmulator/YololEmulator.csproj +++ b/YololEmulator/YololEmulator.csproj @@ -7,7 +7,7 @@ 8.0 enable AnyCPU;x64 - 10.0.0 + 10.0.1