java - 我们怎么能用大数字计算行进距离‽
问题描述
我目前正在解决这个 kata:“我会走多远?” !
描述说:
输入:您最近发现马以一种独特的方式行进——它们要么在奔跑(以最高速度),要么在休息(静止不动)。
以下是一匹特定马如何旅行的示例:
马 Blaze 可以以 14 米/秒的速度跑 60 秒,但之后必须休息 45 秒。
500 秒后,Blaze 将行驶 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
总运行时间 = 5 * 运行时间 = 5 * 60 = 300
--> 计算马跑了多少距离:
x = 速度 * 总运行时间 = 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
总运行时间 = 464 * 运行时间 = 464 * 34 = 15776
--> 计算马走了多远:
x = 速度 * 总运行时间 = 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
84,955,050speed
米,而正确答案是 84,954,920。这不是一个四舍五入的问题。公式是错误的。
为什么?考虑最后一次休息后的跑步。这匹马已经跑了 188,788 次 90 秒 + 100 秒的完整迭代,在此期间它在 35,869,720 秒内跑了 84,954,600 米的距离。在那些“全”跑之后,这匹马现在只剩下 64 秒可以跑了,比runTime
!
马在64秒内跑了多远?320米。所以总数是84,954,600 + 320 = 84,954,920
米。
推荐阅读
- java - 为什么 CrudRepository 中的“delete()”方法需要具有唯一 ID 的实体?
- excel - 如何使用 Excel SparkLines 复制范围并将其粘贴到 Outlook
- java - 如果使用 Low Level Rest Client 对特定数据库列进行了任何更改,弹性搜索如何检索数据
- c - 在二叉树中找到最大数,但仅在叶节点中
- css - 使包裹的项目像列一样垂直对齐?
- python - Selenium WebDriverChromer:
- amazon-web-services - 在 EC2 实例上远程执行包含敏感数据的命令
- bash - 在jenkinsfile groovy脚本中从bash访问字符串变量
- pandas - 如何在 Jupyter/Colab 的完整单元格魔术命令中传递变量?
- python - Python openpyxl获取日期输出格式