Skip to content

Commit

Permalink
leetcode: Add building h2o
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Dec 5, 2023
1 parent 61a7fca commit d02295d
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions leetcode/1117.building-h2o/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "lc-1117-building-h2o"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
106 changes: 106 additions & 0 deletions leetcode/1117.building-h2o/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2023 Xu Shaohua <[email protected]>. All rights reserved.
// Use of this source is governed by General Public License that can be
// found in the LICENSE file.

use std::sync::{Arc, Condvar, Mutex};
use std::thread;

struct H2O {
water: String,
// true -> hydrogen
// false -> oxygen
mutex: Mutex<bool>,
cvar: Condvar,
}

fn print_atom(atom: char) {
print!("{atom}");
}

impl H2O {
const OXYGEN: char = 'O';
const HYDROGEN: char = 'H';
const RELEASE_HYDROGEN: bool = true;

pub fn new(water: &str) -> Self {
Self {
water: water.to_owned(),
mutex: Mutex::new(Self::RELEASE_HYDROGEN),
cvar: Condvar::new(),
}
}

pub fn oxygen(&self) {
let mut index = 0;
loop {
let mut mutex = self.mutex.lock().unwrap();
while *mutex == Self::RELEASE_HYDROGEN {
mutex = self.cvar.wait(mutex).unwrap();
}

let mut count = 0;
while index < self.water.len() && count < 1 {
if self.water.chars().nth(index) == Some(Self::OXYGEN) {
print_atom(Self::OXYGEN);
count += 1;
}
index += 1;
}

if count == 0 {
return;
}
assert_eq!(count, 1);
*mutex = Self::RELEASE_HYDROGEN;
self.cvar.notify_all();
}
}

pub fn hydrogen(&self) {
let mut index = 0;
let len = self.water.len();
loop {
let mut mutex = self.mutex.lock().unwrap();
while *mutex != Self::RELEASE_HYDROGEN {
mutex = self.cvar.wait(mutex).unwrap();
}

let mut count = 0;
while index < len && count < 2 {
if self.water.chars().nth(index) == Some(Self::HYDROGEN) {
print_atom(Self::HYDROGEN);
count += 1;
}
index += 1;
}

if count == 0 {
*mutex = !Self::RELEASE_HYDROGEN;
self.cvar.notify_all();
return;
}
assert_eq!(count, 2);
*mutex = !Self::RELEASE_HYDROGEN;
self.cvar.notify_all();
}
}
}

fn main() {
let s = "HOH";
let s = "OOHHHH";
let h2o = Arc::new(H2O::new(s));
let a = {
let h2o = Arc::clone(&h2o);
thread::spawn(move || {
h2o.oxygen();
})
};
let b = {
thread::spawn(move || {
h2o.hydrogen();
})
};
let _ = a.join();
let _ = b.join();
}

0 comments on commit d02295d

Please sign in to comment.