Background
I am learning Elixir by making exercises in Codewars as much as I can. I have stumbled upon one specific exercise that I think may be incorrect and I could use a hand in checking out my solution.
Exercise
Two tortoises named A and B must run a race. A starts with an average speed of 720 feet per hour
. Young B knows she runs faster than A , and furthermore has not finished her cabbage.
When she starts, at last, she can see that A has a 70 feet lead
but B 's speed is 850 feet per hour
. How long will it take B to catch A ?
More generally: given two speeds v1
( A 's speed, integer > 0) and v2
( B 's speed, integer > 0) and a lead g
(integer > 0) how long will it take B to catch A ?
The result will be an array [hour, min, sec]
which is the time needed in hours, minutes and seconds (round down to the nearest second) or a string in some languages.
If v1 >= v2
then return nil
Examples:
race(720, 850, 70) => [0, 32, 18]
race(80, 91, 37) => [3, 21, 49]
My Solution
Spoiler
defmodule Tortoise do
def race(v1, v2, _) when v1 >= v2, do: nil
def race(v1, v2, lead) do
#Step 1
slow_speed = v1 / 3600 #v1 feets per second
fast_speed = v2 / 3600 #v2 feets per second
#Steps 2 and 3
seconds_to_catchup(lead, 0, slow_speed, fast_speed, 0)
|> to_compound_date()
end
defp seconds_to_catchup( slow_distance, fast_distance, _, _, secs ) when fast_distance >= slow_distance, do: secs-1
defp seconds_to_catchup( slow_distance, fast_distance, slow_speed, fast_speed, secs ) do
seconds_to_catchup( slow_distance+slow_speed, fast_distance+fast_speed, slow_speed, fast_speed, secs+1)
end
defp to_compound_date(total_seconds, hours\\0, minutes\\0, seconds\\0) do
cond do
minutes >= 60 -> to_compound_date(total_seconds, hours + 1, 0, 0)
seconds >= 60 -> to_compound_date(total_seconds, hours, minutes + 1, 0)
total_seconds === 0 -> [hours, minutes, seconds]
true -> to_compound_date(total_seconds - 1, hours, minutes, seconds + 1)
end
end
end
Tests
dotest(720, 850, 70, [0, 32, 18])
dotest(80, 91, 37, [3, 21, 49])
dotest(820, 81, 550, nil)
Problem
The problem here is that I believe the tests to be wrong.
My solution is based on the following algorithm:
- Convert feets/hour to feets/second
- Iterate over each second adding the distanced traveled to the total distance
- Convert number of total seconds to a compound duration
However, when I run the tests I get errors like:
Testing : 720 850 70
1939
[0, 32, 19]
[0, 32, 18]
I believe this happens because the author’s solution rounds and truncates numbers, while my solution does not. I believe my solution to be mathematically more correct because it never loses precision.
Question
However I can’t convince the author and he thinks my solution is incorrect. I can’t see how. Could anyone give me a hint?