I am trying to solve this exercise in a unique way: https://exercism.org/tracks/roc/exercises/darts
Using this quadratic equation: https://www.desmos.com/calculator/q7f0iozldx
x coordinate is the dart unit distance from (0,0) and y coordinate is used to determine the points based on the when clause below.
I have passed almost all tests, but 1 fails due to a precision rounding error in F64 data type:
Attempts to round y2 by multiplying 100000.0, using Num.round and then dividing by 100000.0 don't work.
y2 = (-1.0 / 180.0) * x2 * x2 + (17.0 / 60.0) * x2 - 23.0 / 18.0
vs
y2 = (Num.toFrac (Num.round ((Num.toF64 1000000.0) * (-1.0 / 180.0) * x2 * x2 + (17.0 / 60.0) * x2 - 23.0 / 18.0))) / 1000000.0
thread 'main' panicked at crates/compiler/gen_llvm/src/llvm/lowlevel.rs:1198:21:
not yet implemented: Support converting Dec values to floats
Any other ideas on how to eliminate the rounding error on this example?
1 failed and 12 passed.
[/mnt/exercism-iteration/Darts.roc:7] y2 = -0.9999999999999999
[/mnt/exercism-iteration/Darts.roc:9] c = 0
28│> # On the inner circle
29│> expect
30│> result = score 0.0f64 -1.0f64
31│> result == 10
result : U64
result = 5
score : F64, F64 -> U64
score = \x, y ->
x2 = Num.sqrt (x * x + y * y)
y2 = (-1.0 / 180.0) * x2 * x2 + (17.0 / 60.0) * x2 - 23.0 / 18.0
dbg y2
c = Num.ceiling y2
dbg c
when c is
-1 -> 10
0 -> 5
1 -> 1
_ -> 0
Not that it fixes the test results, but to get the code to compile, you can do this:
y2 = (Num.toF64 (Num.round (1000000.0 * (-1.0 / 180.0) * x2 * x2 + (17.0 / 60.0) * x2 - 23.0 / 18.0))) / 1000000.0
Oh, I think you need to multiply everything by the 1000000.0
for it to be correct
Cause the above only multiplies the first term by 1000000.0
Something like this?
y2 = (Num.toF64 (Num.round (1000000.0 * ((-1.0 / 180.0) * x2 * x2 + (17.0 / 60.0) * x2 - 23.0 / 18.0)))) / 1000000.0
Anyway, I don't think there are any rounding errors here (past expected float inaccuracies), but maybe I am missing something?
We definitely are missing the function to convert from dec to f64 and should add that.
Worked like a charm. Thanks!
score : F64, F64 -> U64
score = \x, y ->
distance = x * x + y * y
|> Num.sqrt
rawScore = (-1.0 / 180.0) * distance * distance + (17.0 / 60.0) * distance - 23.0 / 18.0
# Need rounded score to remove precision errors with F64 data type
roundedScore = rawScore * 1000000.0
|> Num.round
|> Num.toF64
|> \n -> n / 1000000.0
when Num.ceiling roundedScore is
-1 -> 10
0 -> 5
1 -> 1
_ -> 0
Last updated: Jul 06 2025 at 12:14 UTC