From 2ef354eec0a5872bfc89e713a749cfa3a8119ea3 Mon Sep 17 00:00:00 2001 From: Mariano Riefolo Date: Sat, 17 Aug 2024 16:38:20 +0200 Subject: [PATCH] Wrote program for Day 23 --- README.md | 2 +- .../day23/Cargo.toml | 6 + .../day23/src/lib.rs | 116 ++++++++++++++++++ .../day23/src/main.rs | 19 +++ 4 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 Week-04/Day-23_The-Dining_Philosophers/day23/Cargo.toml create mode 100644 Week-04/Day-23_The-Dining_Philosophers/day23/src/lib.rs create mode 100644 Week-04/Day-23_The-Dining_Philosophers/day23/src/main.rs diff --git a/README.md b/README.md index 8464510..6f92035 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ We encourage you to share your progress and ask questions in the Discussions sec | Day #20 | [API Challenge](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-20_API-Challenge) | :white_check_mark: | | Day #21 | [Random Maze Generator](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-21_Random-Maze-Generator) | :white_check_mark: | | Day #22 | [Marcio Mellos Challenge](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-04/Day-22_Marcio-Mellos-Challenge) | :white_check_mark: | -| Day #23 | [The Dining Philosophers](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-04/Day-23_The-Dining_Philosophers) | :white_large_square: | +| Day #23 | [The Dining Philosophers](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-04/Day-23_The-Dining_Philosophers) | :white_check_mark: | | Day #24 | [The Josephus Problem](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-04/Day-24_The-Josephus-Problem) | :white_large_square: | | Day #25 | [Coin Trouble](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-04/Day-25_Coin-Trouble) | :white_large_square: | | Day #26 | [Briefcase Lock](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-04/Day-26_Briefcase-Lock) | :white_large_square: | diff --git a/Week-04/Day-23_The-Dining_Philosophers/day23/Cargo.toml b/Week-04/Day-23_The-Dining_Philosophers/day23/Cargo.toml new file mode 100644 index 0000000..2f4996b --- /dev/null +++ b/Week-04/Day-23_The-Dining_Philosophers/day23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day23" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/Week-04/Day-23_The-Dining_Philosophers/day23/src/lib.rs b/Week-04/Day-23_The-Dining_Philosophers/day23/src/lib.rs new file mode 100644 index 0000000..9f9297e --- /dev/null +++ b/Week-04/Day-23_The-Dining_Philosophers/day23/src/lib.rs @@ -0,0 +1,116 @@ +use std::sync::{mpsc, Arc, Mutex}; +use std::thread; + +pub fn dining_philosophers(n: u8) -> Vec<[u8; 3]> { + let table = Arc::new(Mutex::new([true; 5])); + let mut handles = vec![]; + + let (tx, tr) = mpsc::channel(); + + for i in 0..5 { + let forks = Arc::clone(&table); + let tx = tx.clone(); + let handle = thread::spawn(move || { + for _ in 0..n { + let forks = Arc::clone(&forks); + let tx = tx.clone(); + wants_to_eat( + i, + forks, + tx, + &pick_left_fork, + &pick_right_fork, + &put_left_fork, + &put_right_fork, + ); + } + }); + handles.push(handle); + } + + let mut vecs = vec![]; + let mut count = 0; + + for v in tr { + count += 1; + vecs.push(v); + if count == 5 * 5 * n { + break; + } + } + + vecs +} + +fn wants_to_eat( + philosopher: u8, + forks: Arc>, + tx: mpsc::Sender<[u8; 3]>, + pick_left_fork: &dyn Fn(u8, Arc>), + pick_right_fork: &dyn Fn(u8, Arc>), + put_left_fork: &dyn Fn(u8, Arc>), + put_right_fork: &dyn Fn(u8, Arc>), +) { + loop { + let left_fork = philosopher; + let right_fork = (philosopher + 1) % 5; + let mut have_left = false; + let mut have_right = false; + let mut ate = false; + + if forks.lock().unwrap()[left_fork as usize] && forks.lock().unwrap()[right_fork as usize] { + pick_left_fork(philosopher, forks.clone()); + have_left = true; + tx.send([philosopher, 1, 1]).unwrap(); + pick_right_fork(philosopher, forks.clone()); + have_right = true; + tx.send([philosopher, 2, 1]).unwrap(); + } + + if have_left && have_right { + thread::sleep(std::time::Duration::from_millis(300)); + ate = true; + tx.send([philosopher, 0, 3]).unwrap(); + } + + if ate && have_left { + put_left_fork(philosopher, forks.clone()); + have_left = false; + tx.send([philosopher, 1, 2]).unwrap(); + } + + if ate && have_right { + put_right_fork(philosopher, forks.clone()); + have_right = false; + tx.send([philosopher, 2, 2]).unwrap(); + } + + if ate && !have_left && !have_right { + break; + } + } +} + +fn pick_left_fork(philosopher: u8, forks: Arc>) { + let left_fork = philosopher % 5; + let mut forks = forks.lock().unwrap(); + forks[left_fork as usize] = false; +} + +fn pick_right_fork(philosopher: u8, forks: Arc>) { + let right_fork = (philosopher + 1) % 5; + let mut forks = forks.lock().unwrap(); + forks[right_fork as usize] = false; +} + +fn put_left_fork(philosopher: u8, forks: Arc>) { + let left_fork = philosopher % 5; + let mut forks = forks.lock().unwrap(); + forks[left_fork as usize] = true; +} + +fn put_right_fork(philosopher: u8, forks: Arc>) { + let right_fork = (philosopher + 1) % 5; + let mut forks = forks.lock().unwrap(); + forks[right_fork as usize] = true; +} diff --git a/Week-04/Day-23_The-Dining_Philosophers/day23/src/main.rs b/Week-04/Day-23_The-Dining_Philosophers/day23/src/main.rs new file mode 100644 index 0000000..dcc8098 --- /dev/null +++ b/Week-04/Day-23_The-Dining_Philosophers/day23/src/main.rs @@ -0,0 +1,19 @@ +use std::io::{self, Write}; + +use day23::dining_philosophers; + +fn main() { + let mut buffer = String::new(); + + print!("Insert number of turns: "); + io::stdout().flush().expect("Failed to flush"); + + io::stdin() + .read_line(&mut buffer) + .expect("Failed to read line"); + + let turns = buffer.trim().parse().expect("Failed to parse input"); + let res = dining_philosophers(turns); + + println!("{:?}", res); +}