dsa_rust/maw/
maw_01.rs

1/*!
2This is a sandbox crate for chapter 1 of Data Structures and Algorithm Analysis in Java by Mark Allen Weiss
3*/
4
5#![allow(dead_code)]
6
7pub fn recursion(n: i32) {
8    // Defines base case
9    if n >= 10 {
10        // Recursive call to self
11        recursion(n / 10);
12    }
13    // Prints the digit
14    println!("{}", n % 10)
15}
16
17/** My (iterative) version of a binary search implementation;
18 * Takes a sorted array and a key and returns either Some(index) or None */
19pub fn binary_search(a: &[i32], key: i32) -> Option<i32> {
20    use std::cmp::Ordering;
21
22    // Sets initial position of the search boundaries
23    let mut left = 0;
24    let mut right = a.len() - 1;
25
26    // Loops until the search boundaries overlap;
27    // If the loop doesn't find the key, the function
28    // returns None
29    while left <= right {
30        let mid = (left + right) / 2;
31        match a[mid].cmp(&key) {
32            Ordering::Equal => return Some(mid as i32),
33            Ordering::Greater => right = mid - 1,
34            Ordering::Less => left = mid + 1,
35        }
36        //if a[mid] == key {
37        //    return Some(mid as i32);
38        //} else if a[mid] > key {
39        //    right = mid - 1;
40        //} else {
41        //    left = mid + 1;
42        //}
43        //match key {
44        //    val if val == a[mid] => Some(mid as i32),
45        //    _ => Some(0)
46        //};
47        println!("Guess index: {}", &mid);
48    }
49    None
50}
51
52#[test]
53pub fn binary_search_test() {
54    // The target 73 exists at the 37th index
55    let target = 73;
56    let array: [i32; 39] = [
57        1, 4, 5, 6, 10, 12, 16, 21, 23, 24, 25, 27, 31, 32, 33, 35, 37, 39, 40, 41, 42, 43, 45, 47,
58        49, 50, 51, 52, 54, 56, 57, 60, 61, 67, 70, 71, 72, 73, 74,
59    ];
60    let result = binary_search(&array, target).unwrap_or_default();
61    assert_eq!(result, 37)
62}
63
64use std::collections::HashMap;
65
66fn longest_unique_substring(s: &str) -> usize {
67    let mut map = HashMap::new(); // As HashMap<char, i32>
68    let mut left = 0;
69    let mut max_len = 0;
70
71    let chars: Vec<char> = s.chars().collect();
72
73    for right in 0..chars.len() {
74        *map.entry(chars[right]).or_insert(0) += 1;
75
76        while map[&chars[right]] > 1 {
77            *map.get_mut(&chars[left]).unwrap() -= 1;
78            left += 1;
79        }
80
81        max_len = max_len.max(right - left + 1);
82    }
83
84    max_len
85}
86
87fn longest_unique_substring_print(s: &str) -> usize {
88    let mut map = HashMap::new();
89    let mut left = 0;
90    let mut max_len = 0;
91    let mut best_range = (0, 0); // To store (start, end)
92
93    let chars: Vec<char> = s.chars().collect();
94
95    for right in 0..chars.len() {
96        *map.entry(chars[right]).or_insert(0) += 1;
97
98        while map[&chars[right]] > 1 {
99            *map.get_mut(&chars[left]).unwrap() -= 1;
100            left += 1;
101        }
102
103        let current_len = right - left + 1;
104        if current_len > max_len {
105            max_len = current_len;
106            best_range = (left, right);
107        }
108    }
109
110    // Print the substring using the captured indices
111    let result: String = chars[best_range.0..=best_range.1].iter().collect();
112    println!("Longest substring found: \"{result}\" (length {max_len})");
113
114    max_len
115}
116
117#[test]
118fn longest_unique_substring_test() {
119    let s = "this is a llama test.";
120    assert_eq!(longest_unique_substring(s), 6);
121    longest_unique_substring_print(s);
122    //panic!()
123}
124
125fn insertion_sort<T: Ord>(list: &mut [T]) {
126    for i in 1..list.len() {
127        let mut j = i;
128        while j > 0 && list[j] < list[j - 1] {
129            list.swap(j, j - 1);
130            j -= 1;
131        }
132    }
133}
134
135use std::ptr;
136fn unsafe_insertion_sort<T: Ord>(list: &mut [T]) {
137    for i in 1..list.len() {
138        unsafe {
139            // Move the element out without dropping it
140            let tmp = ptr::read(&list[i]);
141            let mut j = i;
142
143            // Shift elements right until correct spot is found
144            while j > 0 && tmp < list[j - 1] {
145                let dst = list.as_mut_ptr().add(j);
146                let src = list.as_ptr().add(j - 1);
147                ptr::copy_nonoverlapping(src, dst, 1);
148                j -= 1;
149            }
150
151            // Place the element into its final position
152            ptr::write(list.as_mut_ptr().add(j), tmp);
153        }
154    }
155}
156
157fn selection_sort<T: Ord>(list: &mut [T]) {
158    let len = list.len();
159
160    for i in 0..len {
161        let mut min_idx = i;
162
163        for j in (i + 1)..len {
164            if list[j] < list[min_idx] {
165                min_idx = j;
166            }
167        }
168
169        if min_idx != i {
170            list.swap(i, min_idx);
171        }
172    }
173}
174
175fn unsafe_selection_sort<T: Ord>(list: &mut [T]) {
176    let len = list.len();
177    let ptr = list.as_mut_ptr();
178
179    for i in 0..len {
180        unsafe {
181            let mut min_idx = i;
182
183            for j in (i + 1)..len {
184                if (*ptr.add(j)) < (*ptr.add(min_idx)) {
185                    min_idx = j;
186                }
187            }
188
189            if min_idx != i {
190                ptr::swap(ptr.add(i), ptr.add(min_idx));
191            }
192        }
193    }
194}
195
196fn merge_sort<T: Ord>(list: &mut [T]) {
197    let len = list.len();
198    if len <= 1 {
199        return;
200    }
201
202    let mid = len / 2;
203    let (left, right) = list.split_at_mut(mid);
204
205    merge_sort(left);
206    merge_sort(right);
207
208    // Allocate temporary buffer
209    let mut buf: Vec<T> = Vec::with_capacity(len);
210    let _: &mut [std::mem::MaybeUninit<T>] = buf.spare_capacity_mut();
211
212    unsafe {
213        // Set length without initializing
214        buf.set_len(len);
215
216        merge_into(left, right, &mut buf);
217
218        // Move merged result back into original slice
219        ptr::copy_nonoverlapping(buf.as_ptr(), list.as_mut_ptr(), len);
220    }
221}
222
223unsafe fn merge_into<T: Ord>(left: &mut [T], right: &mut [T], buf: &mut [T]) {
224    let mut i = 0;
225    let mut j = 0;
226    let mut k = 0;
227
228    while i < left.len() && j < right.len() {
229        if left[i] <= right[j] {
230            ptr::write(&mut buf[k], ptr::read(&left[i]));
231            i += 1;
232        } else {
233            ptr::write(&mut buf[k], ptr::read(&right[j]));
234            j += 1;
235        }
236        k += 1;
237    }
238
239    while i < left.len() {
240        ptr::write(&mut buf[k], ptr::read(&left[i]));
241        i += 1;
242        k += 1;
243    }
244
245    while j < right.len() {
246        ptr::write(&mut buf[k], ptr::read(&right[j]));
247        j += 1;
248        k += 1;
249    }
250}
251
252fn quick_sort<T: Ord>(list: &mut [T]) {
253    if list.len() <= 1 {
254        return;
255    }
256
257    let pivot_index = partition(list);
258
259    let (left, right) = list.split_at_mut(pivot_index);
260    quick_sort(left);
261    quick_sort(&mut right[1..]); // skip pivot
262}
263
264fn partition<T: Ord>(list: &mut [T]) -> usize {
265    let len = list.len();
266    let pivot_index = len - 1;
267
268    let mut store = 0;
269
270    for i in 0..pivot_index {
271        if list[i] < list[pivot_index] {
272            list.swap(i, store);
273            store += 1;
274        }
275    }
276
277    list.swap(store, pivot_index);
278    store
279}