Skip to content

Commit

Permalink
leetcode: Add print zero even odd
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Dec 4, 2023
1 parent a4c61bf commit f202e7c
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 4 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions leetcode/1116.print-zero-even-odd/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "lc-1116-print-zero-even-odd"
version = "0.1.0"
edition = "2021"

[dependencies]
11 changes: 11 additions & 0 deletions leetcode/1116.print-zero-even-odd/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// 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.

mod with_atomic;
mod with_condvar;

fn main() {
with_atomic::run();
//with_condvar::run();
}
92 changes: 92 additions & 0 deletions leetcode/1116.print-zero-even-odd/src/with_atomic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// 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::hint;
use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::Arc;
use std::thread;

struct ZeroEvenOdd {
n: i32,
counter: AtomicI32,
}

fn print_number(x: i32) {
print!("{x}");
}

impl ZeroEvenOdd {
const ZERO: i32 = 0;
const ODD: i32 = 1;
const EVEN: i32 = 2;

pub fn new(n: i32) -> Self {
Self {
n,
counter: AtomicI32::new(Self::ZERO),
}
}

pub fn zero(&self) {
for i in 0..self.n {
while self.counter.load(Ordering::SeqCst) != Self::ZERO {
hint::spin_loop();
}

print_number(0);
let is_even = if (i + 1) % 2 == 0 {
Self::EVEN
} else {
Self::ODD
};
self.counter.store(is_even, Ordering::SeqCst);
}
}

pub fn even(&self) {
for i in (2..=self.n).step_by(2) {
while self.counter.load(Ordering::SeqCst) != Self::EVEN {
hint::spin_loop();
}

print_number(i);
self.counter.store(Self::ZERO, Ordering::SeqCst);
}
}

pub fn odd(&self) {
for i in (1..=self.n).step_by(2) {
while self.counter.load(Ordering::SeqCst) != Self::ODD {
hint::spin_loop();
}

print_number(i);
self.counter.store(Self::ZERO, Ordering::SeqCst);
}
}
}

pub fn run() {
//let n = 2;
let n = 5;
let zero_even_odd = Arc::new(ZeroEvenOdd::new(n));
let a = {
let zero_even_odd = Arc::clone(&zero_even_odd);
thread::spawn(move || {
zero_even_odd.zero();
})
};
let b = {
let zero_even_odd = Arc::clone(&zero_even_odd);
thread::spawn(move || {
zero_even_odd.even();
})
};
let c = thread::spawn(move || {
zero_even_odd.odd();
});
let _ = a.join();
let _ = b.join();
let _ = c.join();
}
98 changes: 98 additions & 0 deletions leetcode/1116.print-zero-even-odd/src/with_condvar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// 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.

#![allow(dead_code)]

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

struct ZeroEvenOdd {
n: i32,
mutex: Mutex<i32>,
cvar: Condvar,
}

fn print_number(x: i32) {
print!("{x}");
}

impl ZeroEvenOdd {
const ZERO: i32 = 0;
const ODD: i32 = 1;
const EVEN: i32 = 2;

pub fn new(n: i32) -> Self {
Self {
n,
mutex: Mutex::new(Self::ODD),
cvar: Condvar::new(),
}
}

pub fn zero(&self) {
for i in 0..self.n {
eprintln!("zero() {i}");
let mut counter = self.mutex.lock().unwrap();
while *counter != Self::ZERO {
eprintln!("zero counter: {}", *counter);
counter = self.cvar.wait(counter).unwrap();
}
print_number(0);
*counter = if i % 2 == 0 { Self::EVEN } else { Self::ODD };
self.cvar.notify_all();
}
}

pub fn even(&self) {
for i in (0..self.n).step_by(2) {
eprintln!("even() {i}");
let mut counter = self.mutex.lock().unwrap();
while *counter != Self::EVEN {
eprintln!("even counter: {}", *counter);
counter = self.cvar.wait(counter).unwrap();
}
print_number(i);
*counter = Self::ZERO;
self.cvar.notify_all();
}
}

pub fn odd(&self) {
for i in (1..self.n).step_by(2) {
eprintln!("odd() {i}");
let mut counter = self.mutex.lock().unwrap();
while *counter != Self::ODD {
eprintln!("odd counter: {}", *counter);
counter = self.cvar.wait(counter).unwrap();
}

print_number(i);
*counter = Self::ZERO;
self.cvar.notify_all();
}
}
}

pub fn run() {
let n = 1;
let zero_even_odd = Arc::new(ZeroEvenOdd::new(n));
let a = {
let zero_even_odd = Arc::clone(&zero_even_odd);
thread::spawn(move || {
zero_even_odd.zero();
})
};
let b = {
let zero_even_odd = Arc::clone(&zero_even_odd);
thread::spawn(move || {
zero_even_odd.even();
})
};
let c = thread::spawn(move || {
zero_even_odd.odd();
});
let _ = a.join();
let _ = b.join();
let _ = c.join();
}

0 comments on commit f202e7c

Please sign in to comment.