Полное описание проблемы можно найти здесь, немного урезанная версия ниже:
Водитель автомобиля едет по изолированной дороге (без заправочных станций, домов и сотовой связи). Водитель смотрит на указатель уровня топлива: осталось ровно полбака. Они останавливаются и видят, что топливный бак протекает.
Водитель не может устранить утечку. Используя контейнер известного объема и наручные часы, они измеряют скорость потери топлива при
𝑋галлонов в час. Они опорожняют контейнер обратно в резервуар.Водитель проверяет руководство и видит, что емкость топливного бака
𝐶галлонов. Также есть таблица, похожая на приведенную ниже, показывающую снижение эффективности использования топлива в милях на галлон (MPG) по мере увеличения скорости движения в милях в час (MPH). Они должны торговать друг с другом, пытаясь добраться до ближайшей заправочной станции.𝑀миль до наступления темноты.Speed (MPH) Fuel Efficiency (MPG) 55 22.0 60 21.3 65 20.2 70 18.3 75 16.9 80 15.8Водитель предполагает, что авторы руководств являются экспертами, и не любит интерполяцию (и экстраполяцию), они решают двигаться ровно на одной из 6 перечисленных скоростей. Таким образом, расстояние, пройденное до того, как закончится бензин, будет на 100% предсказуемым.
Сможет ли водитель добраться до АЗС до того, как закончится топливо? Если да, то с какой максимальной скоростью они могут двигаться?
Примеры:
| Вход | Выход |
|---|---|
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");
}
}
Сначала я написал уменьшенную версию, которая делала все в основной функции, но я хотел попробовать использовать struct и impl. Я в основном использую python, поэтому в основном ищу указатели по стилю / идиоматической ржавчине и промежуточным / продвинутым темам, которые я мог бы попробовать. Любые советы приветствуются 🙂
1 ответ
- Просто конструируй
let mut car = Car ...в началеmain. - Не разворачивать, заменять собирает на
collectвход вResult<Vec<A>, E>и беги?по результату. ВозвращатьсяResult<(), E>изmain. Вы можете использовать ящик, напримерanyhow. Посмотрите на обработку ошибок при синтаксическом анализе в этом решении. Появление кода 2020 — День 3: спуск на санях
impl<A, E, V> FromIterator<Result<A, E>> for Result<V, E>
where
V: FromIterator<A>,
- Вместо того, чтобы выполнять синтаксический анализ самостоятельно, изучите такие ящики, как
parse-display,reformationили жеrecap. - За
in_range, Я бы сделалmaxна итераторе, чтобы код был функциональным, а не императивно сохраняющим состояние сresПеременная. - опечатка
efficiancy->efficiency
