Домашно 1 - търсене на съкровища
- Краен срок:
- 23.12.2025 23:59
- Точки:
- 20
Златко търси съкровища с дрони. Помогнете му да намери съкровищата намиращи се на острова.
X
+——————————————————————>
| ~ ~ ~ д→. . . ♣ ♣ ♣
| ~ ≈ ~ д→. . ♠ ♠ ♣ ♣
| ~ ≈ ~ д→. . ♠ ♠ *3♣
| ~ ~ ~ д→. . . ♠ ♠ *8
| ~ ~ ≈ д→. . . ♠ ♣ ♠
| ~ ~ ≈ д→. . . ♣ ♠ ♣
| ~ ≈ ~ д→. . . ♠ ♣ ♣
| ~ ~ ~ д→. ♠ . ♠ *5♣
| ~ ≈ ~ д→. . . ♠ ♠ ♣
Y v
(имаше повече смисъл от тази диаграма в предишна чернова на задачата)
Златко мисловно е разделил картата на острова на коридори.
Във всеки коридор е поставил по един дрон. Дроновете сканират повърхността и получават поредица от числови стойности, където 0 означава нищо, а положително число означава, че е намерено съкровище със съответната стойност.
Златко разграничава два вида съкровища - малки (стойност < 999) и големи (стойност >= 999).
Целта му е да намери едно от следните:
- едно голямо съкровище
- произволен брой малки съкровища със обща стойност поне
300
Решението трябва да съдържа координатите и стойностите на всички избрани съкровища.
Поради ограничената товароносимост на дроновете, от всеки коридор може да бъде избрано най-много едно съкровище.
Острова може да бъде безкрайно голям, затова не може да бъде обходен целия. Ако в даден момент бъде намерено решение (едно голямо съкровище или множество малки със стойност >= 300), претърсването трябва да бъде прекратено и да се върне намереното решение. Търси се първото решение, а не най-доброто.
FoundTreasures::Nothing трябва да се върне само ако оствора е крайно голям и бъде обходен целия, без да е намерено решение.
Общи типове:
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TreasureLoc {
pub lane_index: usize,
pub cell_coord: usize,
pub value: i32,
}
#[derive(Debug, PartialEq, Eq)]
pub enum FoundTreasures {
Big(TreasureLoc),
Small(Vec<TreasureLoc>),
Nothing,
}
Дрон - работи самостоятелно, сканира картата и предава информация на контролера.
scanner може да е краен или безкраен итератор.
pub struct Scan<'a> {
// coord of first element in `cells`
pub start_coord: usize,
pub cells: &'a [i32],
}
pub struct Drone {
// ...
}
impl Drone {
pub fn explore(&mut self, scanner: &mut dyn Iterator<Item = Scan<'_>>) {
todo!()
}
}
Контролер - контролира дроновете и събира информацията от тях. Връща решението на задачата.
pub struct DroneController {
// ...
}
impl DroneController {
pub fn new() -> Self {
todo!()
}
pub fn create_drone(&mut self, lane_index: usize) -> Drone {
todo!()
}
pub fn run(&mut self) -> FoundTreasures {
todo!()
}
}
Задачата ще работи по следния начин. Тестовете ще:
- създадат контролера и всички дронове, извиквайки
DroneController::create_drone() - извикат методите
DroneController::run()иDrone::explore(). Тези методи се очаква да работят паралелно. Няма предвиден начин за комуникация между тях - за това трябва да се погрижите сами.
Задачата се счита за решена, когато:
- всички дронове са излезли от
exlore()метода си - контролера е върнал резултат от
run()метода си
Тестовете ще изискват типовете Drone и DroneControler да имплементират Send + 'static (от къде ви е познато това ограничение - hint - thread::spawn). Един вариант да се подсигурите за това е да си направите ad hoc static assertion по следния начин:
const fn assert_send_static<T: Send + 'static>() {}
const _: () = assert_send_static::<DroneController>();
const _: () = assert_send_static::<Drone>();
За разлика от упражненията, за това домашно напълно важат указанията по-долу. Специфично всички типове и функции, които се използват от теста трябва да са публично видими.
Базовия тест е само примерен, финалния тест ще съдържа повече проверки.
Задължително прочетете (или си припомнете): Указания за предаване на домашни
Погрижете се решението ви да се компилира с базовия тест:
