The full problem description can be found here, a slightly trimmed version below:
A car driver is travelling on an isolated road (no gas stations, houses, or cell phone coverage). The driver glances at their fuel gauge: there is exactly half a tank left. They stop and see that the fuel tank is leaking.
The driver cannot repair the leak. Using a container of known volume and a wristwatch, they measure the rate of fuel loss at
𝑋
gallons per hour. They empty the container back into the tank.The driver checks the manual and sees the fuel tank capacity is
𝐶
gallons. There's also a table resembling the one below, showing declining fuel efficiency in miles per gallon (MPG) as driving speed in miles per hour (MPH) increases. They must trade one against the other in an attempt to reach the nearest gas station𝑀
miles away before nightfall.Speed (MPH) Fuel Efficiency (MPG) 55 22.0 60 21.3 65 20.2 70 18.3 75 16.9 80 15.8
The driver assumes manuals authors are experts, and has an aversion to interpolation (and extrapolation), they decide to drive at exactly one of the 6 speeds listed. That way, the distance travelled before running out of gas will be 100% predictable.
Can the driver reach the gas station before running out of fuel? If so, what is the maximum speed they can drive?
Examples:
Input | Output |
---|---|
18 0.5 160 |
YES 60 |
16 0.07 160 |
NO |
main.rs
use std::io::{self, BufRead};
#[derive(Debug)]
struct Car {
capacity: f32,
rate_of_loss: f32,
remaining: f32,
efficiancy: Vec<MPG>,
}
#[derive(Debug)]
struct MPG {
mph: f32,
mpg: f32,
}
impl Car {
fn in_range(&self, distance: f32) -> f32 {
let mut res: f32 = -1.0;
let volume = self.capacity * self.remaining;
for entry in &self.efficiancy {
let time = distance / entry.mph;
let total_loss = time * self.rate_of_loss;
let max_distance = (volume - total_loss) * entry.mpg;
if max_distance > distance {
res = res.max(entry.mph);
}
}
res
}
}
fn main() {
let remaining: f32 = 0.5;
let mut c: f32 = 0.0;
let mut x: f32 = 0.0;
let mut m: f32 = 0.0;
let mut efficiancies: Vec<MPG> = Vec::new();
let stdin = io::stdin();
for (i, line) in stdin.lock().lines().map(|x| x.unwrap()).enumerate() {
let nums: Vec<f32> = line
.split_whitespace()
.map(|n| n.parse().unwrap())
.collect();
if i == 0 {
c = nums[0];
x = nums[1];
m = nums[2];
} else {
efficiancies.push(MPG {
mph: nums[0],
mpg: nums[1],
});
}
}
let car = Car {
capacity: c,
rate_of_loss: x,
remaining: remaining,
efficiancy: efficiancies,
};
let y = car.in_range(m);
if y > 0.0 {
println!("YES {:.0}", y);
} else {
println!("NO");
}
}
I did initially write a smaller version that did everything in the main function, but I wanted to try using struct
and impl
. I primarily use python, so I'm mostly looking for pointers on style/idiomatic rust and intermediate/advanced topics that I could try out. Any advice is welcome :)