Loading collection data...
Collections are a way for you to organize kata so that you can create your own training routines. Every collection you create is public and automatically sharable with other warriors. After you have added a few kata to a collection you and others can train on the kata contained within the collection.
Get started now by creating a new collection.
What do you mean I am wrong? I checked that tests don't conform to kata description.
Actually 5 loop tests are broken, check my solution.
Broken test
*[>*]
expects all bits to be flipped, but it is only first bit that has to be flipped.Also this kata is more difficult than 1 kyu katas that I solved, so it's either this kata is underrated or those katas are overrated.
Really nice kata, I really underestimated it and thought people are joking about edge cases, but they are not joking and I spend few days having fun solving it, this is the most brainstorming kata I've ever solved, thank you!
it's nice that you keep your code short, but why rely on
Debug
?yes, your solution is correct 😀
and you're right, I was aware from the beginning that unary minus has highest precedence, but assigned it to a wrong function and it failed to parse, then assigned it to different wrong function again and it worked for all tests except the last two
I can't use
munch
because we use different packages, in your solution it'sText.ParserCombinators.ReadP
frombase
and in my solution it'sText.ParserCombinators.Parsec
fromparsec
, but it's amazing how similar they are 🙂ok, I patched the line responsible for unary minus and now I get expected results 😌
maybe I should mark my comment above as a spoiler? 😀
TLDR: I have a correct left-to-right order, but the cause of mismatch is the way my solution handles unary minus
let's carefully analyze the expression, first it needs to be cleaned up with
unwords . words
:"-77.74 - -49.83 -( 87.1 * ( 95.77 ) ) * 60.89 /( 19.4 /( 48.03 ) /( 9.36 * 60.54 * -54.34 /( 88.69 ) ) ) - ( 30.12* 16.51 ) +76.58 + 7.33 * ( 37.22 )* 32.52- ( 71.16 ) + 66.99 /( 34.22 )- 99.3 /(59.18 )+ 47.01 - -2.64* 99.59 + 40.75 + 48.83 * 65.14 + 11.3 + 89.38 * -5.43 + ( 6.75 - ( 32.38- -----( 27.88 ) * -45.71+40.16 + 21.69 ) * 80.87 * 74.01 )"
I need to break this into variables:
a = "-77.74 - -49.83 "
b = "( 87.1 * ( 95.77 ) ) * 60.89 "
c = "( 19.4 /( 48.03 ) /( 9.36 * 60.54 * -54.34 /( 88.69 ) ) ) "
d = " ( 30.12* 16.51 ) +76.58 + 7.33 * ( 37.22 )* 32.52- ( 71.16 ) + 66.99 /( 34.22 )"
e = " 99.3 /(59.18 )+ 47.01 - -2.64* 99.59 + 40.75 + 48.83 * 65.14 + 11.3 + 89.38 * -5.43 "
f = " ( 6.75 - ( 32.38- -----( 27.88 ) * -45.71+40.16 + 21.69 ) * 80.87 * 74.01 )"
so the expression is:
entire = a ++ "-" ++ b ++ "/" ++ c ++ "-" ++ d ++ "-" ++ e ++ "+" ++ f
let's evaluate those variables one at a time:
> calc a
"((- 77.74) - (- 49.83))"
> calc b
"((87.1 * 95.77) * 60.89)"
> calc c
"((19.4 / 48.03) / ((9.36 * 60.54) * (- (54.34 / 88.69))))"
> calc d
"(((((30.12 * 16.51) + 76.58) + ((7.33 * 37.22) * 32.52)) - 71.16) + (66.99 / 34.22))"
> calc e
"(((((((99.3 / 59.18) + 47.01) - (- (2.64 * 99.59))) + 40.75) + (48.83 * 65.14)) + 11.3) + (89.38 * (- 5.43)))"
> calc f
"(6.75 - (((((32.38 - (- (- (- (- (- (27.88 * (- 45.71)))))))) + 40.16) + 21.69) * 80.87) * 74.01))"
here we observe the interesting propery twice:
> calc "-2.64* 99.59"
"(- (2.64 * 99.59))"
> calc "-( 27.88 ) * -45.71"
"(- (27.88 * (- 45.71)))"
but the order is still correct, now the tricky part is evaluating them together:
> calc (a ++ "-" ++ b ++ "/" ++ c) == ("(" ++ calc a ++ " - (" ++ calc b ++ " / " ++ calc c ++ "))")
True
part = a ++ "-" ++ b ++ "/" ++ c ++ "-" ++ d
> calc part == ("((" ++ calc a ++ " - (" ++ calc b ++ " / " ++ calc c ++ ")) - " ++ calc d ++ ")")
False
I know exactly why that happens even if mathematically what I specified on the right is correct, now let's observe:
> calc part
"((((((((- 77.74) - (- 49.83)) - (((87.1 * 95.77) * 60.89) / ((19.4 / 48.03) / ((9.36 * 60.54) * (- (54.34 / 88.69)))))) - (30.12 * 16.51)) + 76.58) + ((7.33 * 37.22) * 32.52)) - 71.16) + (66.99 / 34.22))"
it simplifies to:
u = ((((((a - (b / c)) - (30.12 * 16.51)) + 76.58) + ((7.33 * 37.22) * 32.52)) - 71.16) + (66.99 / 34.22))
we still correctly get expressions evaluated left-to-right, let's move on:
> calc (part ++ "-" ++ e)
"(((((((((((((((- 77.74) - (- 49.83)) - (((87.1 * 95.77) * 60.89) / ((19.4 / 48.03) / ((9.36 * 60.54) * (- (54.34 / 88.69)))))) - (30.12 * 16.51)) + 76.58) + ((7.33 * 37.22) * 32.52)) - 71.16) + (66.99 / 34.22)) - (99.3 / 59.18)) + 47.01) - (- (2.64 * 99.59))) + 40.75) + (48.83 * 65.14)) + 11.3) + (89.38 * (- 5.43)))"
we get more parantheses on the left, it's ok:
(((((((((((((a - (b / c)) - (30.12 * 16.51)) + 76.58) + ((7.33 * 37.22) * 32.52)) - 71.16) + (66.99 / 34.22)) - (99.3 / 59.18)) + 47.01) - (- (2.64 * 99.59))) + 40.75) + (48.83 * 65.14)) + 11.3) + (89.38 * (- 5.43)))
now let's remove the duplicate from previous part to make it easier to see:
v = (((((((u - (99.3 / 59.18)) + 47.01) - (- (2.64 * 99.59))) + 40.75) + (48.83 * 65.14)) + 11.3) + (89.38 * (- 5.43)))
again it's correctly evaluated left-to-right, now let's get the final result:
> calc entire
"((((((((((((((((- 77.74) - (- 49.83)) - (((87.1 * 95.77) * 60.89) / ((19.4 / 48.03) / ((9.36 * 60.54) * (- (54.34 / 88.69)))))) - (30.12 * 16.51)) + 76.58) + ((7.33 * 37.22) * 32.52)) - 71.16) + (66.99 / 34.22)) - (99.3 / 59.18)) + 47.01) - (- (2.64 * 99.59))) + 40.75) + (48.83 * 65.14)) + 11.3) + (89.38 * (- 5.43))) + (6.75 - (((((32.38 - (- (- (- (- (- (27.88 * (- 45.71)))))))) + 40.16) + 21.69) * 80.87) * 74.01)))"
don't be scared, simplify and deduplicate from previous result again:
(v + (6.75 - (((((32.38 - (- (- (- (- (- (27.88 * (- 45.71)))))))) + 40.16) + 21.69) * 80.87) * 74.01)))
and fortunately:
> calc entire == ("(" ++ calc (part ++ "-" ++ e) ++ " + " ++ calc f ++ ")")
True
so, I do have a correct left-to-right order, if I evaluated it differently the result would be
4.436349535535873e8
instead of4.436588275515455e8
which is pretty close to expected4.4365882755154556e8
for reference here's the failed test:
Falsifiable (after 33 tests): " -77.74\t- -49.83\t\n-(\n87.1\t*\t(\t95.77 )\t) \n*\t\n60.89 /(\n\t19.4\t/(\n48.03 ) /(\t\t9.36 *\n60.54\t*\n-54.34\t/( 88.69\t)\n\n\n\t) ) -\t \n ( \n30.12* 16.51 \t)\n+76.58 +\t7.33\t*\n(\n37.22\t)*\t32.52- \t(\n71.16 )\t+\t\t 66.99\t/( 34.22\t)-\n\n 99.3\n/(59.18 )+\n47.01\t- \t-2.64*\n99.59\n+\n40.75\n\t\t+\n48.83\n\t * 65.14 \t+ \n11.3\t+\n89.38\t\t\n\n\t\t*\n-5.43\t\n + (\n 6.75\t- (\n32.38-\n-----(\t27.88 )\n\n\n\n*\n-45.71+40.16 \t+\t21.69\n \n\t)\n* \n80.87 *\n74.01\t\t ) " expected 4.4365882755154556e8 but got 4.436588275515455e8
and this is how my solution treats it:
"((((((((((((((((- 77.74) - (- 49.83)) - (((87.1 * 95.77) * 60.89) / ((19.4 / 48.03) / ((9.36 * 60.54) * (- (54.34 / 88.69)))))) - (30.12 * 16.51)) + 76.58) + ((7.33 * 37.22) * 32.52)) - 71.16) + (66.99 / 34.22)) - (99.3 / 59.18)) + 47.01) - (- (2.64 * 99.59))) + 40.75) + (48.83 * 65.14)) + 11.3) + (89.38 * (- 5.43))) + (6.75 - (((((32.38 - (- (- (- (- (- (27.88 * (- 45.71)))))))) + 40.16) + 21.69) * 80.87) * 74.01)))"
because the input is too long it's hard for me to spot where exactly it evaluates in wrong order
using
foldl1
instead doesn't change the result because it's used simply for a lookup table:This comment is hidden because it contains spoiler information about the solution
please fix random tests, they are extremely strict about precision "expected -56483.677637104585 but got -56483.67763710458"
those test answers were calculated by using python interpreter...
ah, right, makes sense
Loading more items...