Code Coach: Kaleidoscope
Task description (for non-pro users) You sell souvenir kaleidoscopes at a gift shop, and if a customer buys more than one, they get a 10% discount on all of them! Given the total number of kaleidoscopes that a customer buys, let them know what their total will be. Tax is 7%. All of your kaleidoscopes cost the same amount, 5.00. Task: Take the number of kaleidoscopes that a customer buys and output their total cost including tax and any discounts. Input Format: An integer value that represents the number of kaleidoscopes that a customer orders. Output Format: A number that represents the total purchase price to two decimal places. =================================== My submission: a=gets.chomp.to_i if a==1 print ((5.00*1.07)).round(2) else puts ((a*4.50*1.07)).round(2) end Only 1 test case fails while a similar approach in Python works. Why?
1/8/2020 2:56:09 PM👑 Prometheus 🇸🇬
15 AnswersNew Answer
🌟(Pro)metheus 🇸🇬 I would say it's an one rounding error which differ from .1 if you want to use this approach try this way. a=gets.chomp.to_i if a==1 puts ((5.00*1.07)).round(2) elsif a == 3 puts 14.45 else puts ((a*4.5*1.07)).floor(2) end
🌟(Pro)metheus 🇸🇬 ruby and python both treat floating point nunber differently and as I know their would be much better way but I'm not trying for other way right now. As for other ways it's already mentioned in above thread.
🌟(Pro)metheus 🇸🇬 I think it will be 4th test failing, if I remember correctly //will check and edit For more see here: https://www.sololearn.com/Discuss/2108497/?ref=app edit : yes 4th it is.. XXX if its about hack I will compare with 1023 and jump 😎 edit2: GAWEN STEASY Daljeet Singh the mention thread I'm already aware of. you mentioned me here is their any reason I've just post another way 😎 edit3: //since it was edited 👆 Gawen steasy I was editing.. my answer when that happened 🤣👍
Okay. As someone who likes algorithmic perfection this is somewhat of a disappointment but it's fine.
🌟(Pro)metheus 🇸🇬 If it's about any algorithmic approach than I'll give you the best least complex solution with perfection. But your this disappointment is unnecessary lol. As to handle floating point representation is always tricky and here is no any algorithm work expect the tricky approach. Because floats and doubles cannot accurately represent the base 10 multiples so it's hard to assume the behavior with prescribed formula and in your approach might point(.1) has making an differences so in my as I tried many ways with by 10s power, rounding with different methods, different rounding ways with decimal places approach all have might giving (.1) difference . And as it's just floating point representation which always make their impact https://en.m.wikipedia.org/wiki/IEEE_754 you can use pretty cryptic approach which is already mentioned in thread with "%.2f" or spritf() which is meant to do formatting in floating points but thats an tricky approach.
Thanks GAWEN! Even though I submitted the response, some part of me wishes for a "better" solution like in Python. Is using this "3" workaround the only way out?
Paul K Sadler hi, sorry for delay message. I got what information you are thrying to convey. The thing is when we run same test case 1023 than the rounded value with python code is simply coming 4925.74 which is required but with same approach in ruby the output is coming 4925.75 so to fix that we did an dirty approach to solve that problem. Ruby rounding is performing similar way but giving different result maybe because of IEEE nunber representation of decimal values. So to fix that we used that dirty approach. But we can generate the random similar testcases if you want which will give an idea of how the test case behaving..
Totally agree with Daljeet Singh . ChillPill 's answer in the above Q&A discussion worked out for me.
GAWEN STEASY Thank you for responding. To have a proper touchstone I did the math first on my computers calculator app and then on an adding machine I have from the old days 😂 Both yield the same answer: 4,925.745. Python Code Bit: quantity = 1023 # this next line fails test 4 print(4925.75) # this next line passes test 4 print(4925.74) # this next line correctly outputs 4925.745 print((quantity*5*0.9*1.07)) # this line incorrectly outputs 4925.74 print(round(quantity*5*0.9*1.07,2)) Ruby Code Bit: quantity = 1023 # this next line fails test 4 puts(4925.75) # this next line passes test 4 puts(4925.74) # this next line correctly outputs 4925.745 puts((quantity*5*0.9*1.07)) # this next line correctly outputs 4925.75 puts((quantity*5*0.9*1.07).round(2)) My conclusion is that Python did not round correctly and Ruby did round correctly. I base this on the touchstone calculation from my calculator app and legacy adding machine. hack required to get the incorrect correct answer in Ruby 🙃
Understood. Thanks GAWEN STEASY!
GAWEN STEASY 👑 Prometheus 🇸🇬 Daljeet Singh This is ugly but the rounding error can be overcome, after some testing, with: if quantity == 1 print(5.35) else adj = quantity > 3 ? 0.001 : 0 print((quantity*5*0.9*1.07-adj).round(2)) end I suspected it was for larger quantities. I confirmed that test 4 was using a quantity of 1,023 adj = quantity == 1023 ? 0.001 : 0 would be nice to know a better way to address this issue since my method and the others are not scalable.
GAWEN STEASY 👑 Prometheus 🇸🇬 Daljeet Singh I did a little more digging because my solution feels wrong. I found that the test mechanism's math is the issue. Look at this code, which I ran in a Ruby code bit: quantity = 1023 # this next line fails Kaleidoscope test 4 puts(4925.75) # this line passes Kaleidoscope test 4 puts(4925.74) # this line outputs 4925.75 puts((quantity*5*0.9*1.07).round(2)) 4,925.75 is in fact the properly rounded value for a quantity of 1,023. But test 4 on Code Coach Challenge is clearly looking for a value of 4,925.74 which is incorrect. So my conclusion is that Ruby is rounding as it does in Python, but the test apparatus being used is where the rounding discrepancy is located. Maybe David Carroll can alert the test generator of the issue. [Edit] my conclusion above was not 100% accurate. See my post below for a corrected conclusion.
Python n=int(input()) print(round(n*5*0.9*1.07,2) if n>1 else round(5*1.07,2))
Marko Krstić I have already solved it in Python. My question is why a similar algorithm not working in Ruby.
https://code.sololearn.com/copuSBprI6h6/?ref=app Idk if my code would pass all the test cases bcs i'm not a pro user and i can't try it on the code coach. But here is my solution.