Решение на Домашно 1 - търсене на съкровища от Нели Илиева

Обратно към всички решения

Към профила на Нели Илиева

Резултати

  • 20 точки от тестове
  • 0 бонус точки
  • 20 точки общо
  • 5 успешни тест(а)
  • 0 неуспешни тест(а)

Код

use std::sync::{Arc, Mutex, Condvar};
use std::sync::atomic::{AtomicBool, Ordering};
#[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,
}
pub struct Scan<'a> {
pub start_coord: usize,
pub cells: &'a [i32],
}
struct SharedState {
treasures: Vec<TreasureLoc>,
finished_drones: usize,
total_drones: usize,
big_treasure_found: bool,
}
pub struct Drone {
lane_index: usize,
shared: Arc<(Mutex<SharedState>, Condvar)>,
stop_signal: Arc<AtomicBool>,
}
impl Drone {
pub fn explore(&mut self, scanner: &mut dyn Iterator<Item = Scan<'_>>) {
let mut best_treasure: Option<TreasureLoc> = None;
for scan in scanner {
if self.stop_signal.load(Ordering::Relaxed) {
break;
}
for (idx, &value) in scan.cells.iter().enumerate() {
if value > 0 {
let treasure = TreasureLoc {
lane_index: self.lane_index,
cell_coord: scan.start_coord + idx,
value,
};
if best_treasure.as_ref().map_or(true, |t| value > t.value) {
best_treasure = Some(treasure);
}
}
}
if let Some(ref treasure) = best_treasure {
if treasure.value >= 999 {
let (lock, cvar) = &*self.shared;
let mut state = lock.lock().unwrap();
if !state.big_treasure_found {
state.big_treasure_found = true;
state.treasures.clear();
state.treasures.push(treasure.clone());
self.stop_signal.store(true, Ordering::Relaxed);
cvar.notify_all();
}
break;
}
}
}
let (lock, cvar) = &*self.shared;
let mut state = lock.lock().unwrap();
if !state.big_treasure_found {
if let Some(treasure) = best_treasure {
state.treasures.push(treasure);
}
}
state.finished_drones += 1;
cvar.notify_all();
}
}
pub struct DroneController {
shared: Arc<(Mutex<SharedState>, Condvar)>,
stop_signal: Arc<AtomicBool>,
drone_count: usize,
}
impl DroneController {
pub fn new() -> Self {
let shared = Arc::new((
Mutex::new(SharedState {treasures: Vec::new(), finished_drones: 0, total_drones: 0, big_treasure_found: false,
}),
Condvar::new(),
));
DroneController {
shared,
stop_signal: Arc::new(AtomicBool::new(false)),
drone_count: 0,
}
}
pub fn create_drone(&mut self, lane_index: usize) -> Drone {
{
let (lock, _) = &*self.shared;
let mut state = lock.lock().unwrap();
state.total_drones += 1;
}
self.drone_count += 1;
Drone {
lane_index,
shared: Arc::clone(&self.shared),
stop_signal: Arc::clone(&self.stop_signal),
}
}
pub fn run(&mut self) -> FoundTreasures {
let (lock, cvar) = &*self.shared;
let mut state = lock.lock().unwrap();
while !state.big_treasure_found && state.finished_drones < state.total_drones {
state = cvar.wait(state).unwrap();
}
if state.big_treasure_found {
return FoundTreasures::Big(state.treasures[0].clone());
}
if state.treasures.is_empty() {
return FoundTreasures::Nothing;
}
let total_value: i32 = state.treasures.iter().map(|t| t.value).sum();
if total_value >= 300 {
return FoundTreasures::Small(state.treasures.clone());
}
FoundTreasures::Nothing
}
}
const fn assert_send_static<T: Send + 'static>() {}
const _: () = assert_send_static::<DroneController>();
const _: () = assert_send_static::<Drone>();

Лог от изпълнението

Updating crates.io index
     Locking 46 packages to latest compatible versions
   Compiling proc-macro2 v1.0.104
   Compiling unicode-ident v1.0.22
   Compiling quote v1.0.42
   Compiling libc v0.2.178
   Compiling syn v2.0.111
   Compiling futures-core v0.3.31
   Compiling futures-sink v0.3.31
   Compiling pin-project-lite v0.2.16
   Compiling parking_lot_core v0.9.12
   Compiling futures-channel v0.3.31
   Compiling memchr v2.7.6
   Compiling futures-task v0.3.31
   Compiling smallvec v1.15.1
   Compiling scopeguard v1.2.0
   Compiling cfg-if v1.0.4
   Compiling pin-utils v0.1.0
   Compiling slab v0.4.11
   Compiling futures-io v0.3.31
   Compiling lock_api v0.4.14
   Compiling errno v0.3.14
   Compiling signal-hook-registry v1.4.8
   Compiling parking_lot v0.12.5
   Compiling socket2 v0.6.1
   Compiling futures-macro v0.3.31
   Compiling tokio-macros v2.6.0
   Compiling futures-util v0.3.31
   Compiling mio v1.1.1
   Compiling bytes v1.11.0
   Compiling tokio v1.48.0
   Compiling futures-executor v0.3.31
   Compiling futures v0.3.31
   Compiling solution v0.1.0 (/tmp/d20251229-4108951-1koqmiu/solution)
warning: function `assert_send_static` is never used
   --> src/lib.rs:151:10
    |
151 | const fn assert_send_static<T: Send + 'static>() {}
    |          ^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: `solution` (lib) generated 1 warning
    Finished `test` profile [unoptimized + debuginfo] target(s) in 17.17s
     Running tests/solution_test.rs (target/debug/deps/solution_test-f512224d9fb3caf8)

running 5 tests
test solution_test::test_nothing ... ok
test solution_test::test_big_treasure ... ok
test solution_test::test_small_treasure ... ok
test solution_test::test_small_treasure_2 ... ok
test solution_test::test_return_immediately_when_found ... ok

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s

История (1 версия и 1 коментар)

Нели качи първо решение на 23.12.2025 13:56 (преди около 1 месеца)

Имаш пропуск в решението.
Имплементирала си спиране, когато бъде открито едно голямо съкровище, но не си имплементирала спиране, когато бъдат открити малки съкровища на стойност поне 300. Ако scanner итераторите са безкрайни решението ти никога няма да върне FoundTreasures::Small(_).
Но съм пропуснал да добавя тест за това.