我正在解决此kata:"How far I will go?"!
描述中说:
输入:[您最近发现马以独特的方式行走-他们要么在奔跑(以最快的速度),要么在静止(静止)。
这是一匹特定的马可能如何行进的示例:
[Blaze马可以以14米/秒的速度运行60秒,但必须然后休息45秒钟。
500秒后,大火将行驶4200米。
您的工作是编写一个函数,该函数返回一匹马将要骑多久在给定的时间后旅行。
totalTime - How long the horse will be traveling (in seconds)
runTime - How long the horse can run for before having to rest (in seconds)
restTime - How long the horse have to rest for after running (in seconds)
speed - The max speed of the horse (in metres/second)
我已经手工完成了演算:
给出:速度= 14,运行时间= 60,休息时间= 45,总时间= 500
->要计算马跑多少时间,我们计算以下内容:
totalTime /(runTime + restTime)= 500 /(60 + 45)= 500/105 = 4.76 ...roundUp(totalTime)= 5
totalRunTime = 5 * runTime = 5 * 60 = 300
->计算马走了多少距离:
x =速度* totalRunTime = 14 * 300 = 4200
我将其翻译为以下代码:
public class Kata {
public static int travel(int totalTime, int runTime, int restTime, int speed) {
int totalRunTime = 0;
if(totalTime < runTime){
totalRunTime = totalTime;
}else{
totalRunTime = (int)Math.ceil( (double)totalTime/(runTime + restTime) ) * runTime;
}
return speed * totalRunTime;
}
}
[当我们运行基本测试时,它会提供预期的输出:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class KataTest {
@Test
public void exampleTests() {
assertEquals(4200, Kata.travel(500, 60, 45, 14));
assertEquals(1120, Kata.travel(1000, 10, 127, 14));
assertEquals(1000, Kata.travel(100, 10, 0, 10));
assertEquals(1000, Kata.travel(100, 10, 0, 10));
assertEquals(450, Kata.travel(25, 50, 120, 18));
}
}
但是,当我们用大量高级示例进行测试时,它显示的结果不准确。
例如:
给出:速度= 6,运行时间= 34,休息时间= 180,总计时间= 99094;预期的输出是94524,但是我发布的代码给了我们94656
我已经手工编写了跟踪以了解我的代码的作用:
->要计算这匹马奔跑的总时间:
totalTime /(runTime + restTime)= 99094 /(34 + 180)= 99094/214 = 463.05 ...roundUp(totalTime)= 464
totalRunTime = 464 * runTime = 464 * 34 = 15776
->计算马走了多远:
x =速度* totalRunTime = 6 * 15776 = 94656
因此失败的测试是:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class KataTest {
@Test
public void biggerTests() {
assertEquals(84954920, Kata.travel(35869784, 90, 100, 5));
}
}
我有一种直觉,必须在从double到int的转换或使用Math.ceil进行四舍五入的过程中改进代码,但是我不知道为什么或如何解决它。这是我认为可以改进的行:
totalRunTime = (int)Math.ceil( (double)totalTime/(runTime + restTime) ) * runTime;
我也读过:
问题不在于四舍五入。让我们看一下示例travel(35869784, 90, 100, 5)
。
根据您的公式35869784/(100+90) = 188788.336
,向上舍入得出188789,再乘以runTime
,然后乘以speed
得到84,955,050米,而正确的答案是84,954,920。这不是一个四舍五入的问题。公式是错误的。
为什么?考虑最后一次运行。我们进行了90,100次运行的188,788次完整迭代,在此过程中,我们在35,869,720秒内行驶了84,954,600米。在这些“满员”奔跑之后,这匹马现在只剩64秒可以跑了,这比runTime
还短!
[马在64秒内跑了多远? 320米因此总数为84,954,600 + 320 = 84,954,920
米。