diff --git a/aufgaben/sheet12/sol1/sleep-sort.rs b/aufgaben/sheet12/sol1/sleep-sort.rs new file mode 100755 index 0000000..c685f4e --- /dev/null +++ b/aufgaben/sheet12/sol1/sleep-sort.rs @@ -0,0 +1,54 @@ +use std::thread; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +fn main() { + let mut arr = [83, 12, 13, 35, 91, 71, 75, 58, 26, 38, 2, 23, 10]; + sleep_sort(&mut arr); + assert_eq!(arr, [2, 10, 12, 13, 23, 26, 35, 38, 58, 71, 75, 83, 91]); +} + +fn sleep_sort(arr: &mut [u64]) { + let mut time_multiplier = 1.0; + let mut attempts = 0; + + loop { + let result = Arc::new(Mutex::new(Vec::new())); + let mut handles = Vec::with_capacity(arr.len()); + + // Iterate over the immutable slice + for &thread_elem in arr.as_ref() { + // Create a new owner of the Arc to move into the new thread + let result = result.clone(); + + handles.push(thread::spawn(move || { + let time = (thread_elem as f64 * time_multiplier) as u32; + thread::sleep(Duration::new(0, time)); + result.lock().unwrap().push(thread_elem); + })); + } + + // Make sure our main thread waits until all other threads are finished + for handle in handles { + handle.join().unwrap(); + } + + attempts += 1; + time_multiplier *= 2.0; + + // Now, there should be only one owner of the Arc left: this main + // thread. Thus we can unwrap it to get the ownership of the vector. + let result = Arc::try_unwrap(result).unwrap().into_inner().unwrap(); + + // If the resulting vector is actually sorted, we can write all + // elements to the original slice. + if result.iter().zip(&result[1..]).all(|(&a, &b)| a <= b) { + for (orig, new) in arr.iter_mut().zip(result) { + *orig = new; + } + break; + } + } + + println!("Sorted in {} attempts (multiplier: {})", attempts, time_multiplier); +}