fetch_modi/
lib.rs

1/*
2 * --------------------
3 * THIS FILE IS LICENSED UNDER THE FOLLOWING TERMS
4 *
5 * this code may not be used for any purpose. be gay, do crime
6 *
7 * THE FOLLOWING MESSAGE IS NOT A LICENSE
8 *
9 * <barrow@tilde.team> wrote this file.
10 * by reading this text, you are reading "TRANS RIGHTS".
11 * this file and the content within it is the gay agenda.
12 * if we meet some day, and you think this stuff is worth it,
13 * you can buy me a beer, tea, or something stronger.
14 * -Ezra Barrow
15 * --------------------
16 */
17
18#[macro_use]
19extern crate str_macro;
20use console::style;
21use std::cmp::Ordering;
22use std::fmt;
23
24fn green(t: &str) -> console::StyledObject<&str> {
25    style(t).green()
26}
27
28pub enum InsertResult {
29    Success,
30    SuccessBut(Vec<String>),
31    CollisionDetected,
32}
33
34pub enum FetchResult {
35    Success(String),
36    SuccessBut(String, Vec<String>),
37    Empty,
38}
39
40impl fmt::Display for InsertResult {
41    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42        match self {
43            InsertResult::Success => write!(f, "Successfully Inserted"),
44            InsertResult::SuccessBut(items) => {
45                for i in items.iter() {
46                    writeln!(f, "The {} was launched out of your sylladex!", green(i))?;
47                }
48                write!(f, "Successfully Inserted")
49            }
50            InsertResult::CollisionDetected => write!(f, "Collision Detected!"),
51        }
52    }
53}
54impl fmt::Display for FetchResult {
55    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56        match self {
57            FetchResult::Empty => write!(f, "Nothing to take!"),
58            FetchResult::Success(item) => write!(f, "Removed {} from sylladex", green(item)),
59            FetchResult::SuccessBut(item, items) => {
60                for i in items.iter() {
61                    writeln!(f, "The {} was launched out of your sylladex!", green(i))?;
62                }
63                write!(f, "Removed {} from sylladex", green(item))
64            }
65        }
66    }
67    //     match result {
68    //         FetchResult::Empty => println!("nothing to take"),
69    //         FetchResult::Success(item) => println!("Removed {} from sylladex", item),
70    //         FetchResult::SuccessBut(_, _) => panic!("this shouldn't happen"),
71    //     };
72}
73
74pub mod john {
75    use super::*;
76    pub enum Modi {
77        Queue,
78        Stack,
79        Array,
80        QueueStack,
81        ArrayQueueStack,
82    }
83    pub struct QueueStackModus {
84        pub items: Vec<String>,
85        pub size: usize,
86    }
87    pub struct ArrayQSModus {
88        pub array: Vec<QueueStackModus>,
89        pub size: usize,
90    }
91
92    impl ArrayQSModus {
93        pub fn new(size: usize) -> ArrayQSModus {
94            if size < 1 {
95                panic!("size < 1!!!!")
96            }
97            let mut vec = Vec::<QueueStackModus>::new();
98            for _ in 0..size {
99                vec.push(QueueStackModus::new(size));
100            }
101            ArrayQSModus { array: vec, size }
102        }
103        pub fn put(&mut self, index: usize, is_queue: bool, item: &str) -> InsertResult {
104            if index >= self.size {
105                InsertResult::CollisionDetected
106            } else {
107                let qs = self.array.get_mut(index).unwrap();
108                if is_queue {
109                    qs.queue_put(item)
110                } else {
111                    qs.stack_put(item)
112                }
113            }
114        }
115        pub fn get(&mut self, index: usize, is_queue: bool) -> FetchResult {
116            if index >= self.size {
117                FetchResult::Empty
118            } else {
119                let qs = self.array.get_mut(index).unwrap();
120                if is_queue {
121                    qs.queue_take()
122                } else {
123                    qs.stack_take()
124                }
125            }
126        }
127    }
128
129    impl QueueStackModus {
130        pub fn new(size: usize) -> QueueStackModus {
131            if size < 1 {
132                panic!("size < 1!!!!")
133            }
134            QueueStackModus {
135                items: vec![],
136                size,
137            }
138        }
139        pub fn new_array(size: usize) -> QueueStackModus {
140            if size < 1 {
141                panic!("size < 1!!!!")
142            }
143            let mut vec = Vec::<String>::new();
144            for _ in 0..size {
145                vec.push(str!(""));
146            }
147            QueueStackModus { items: vec, size }
148        }
149        pub fn queue_put(&mut self, item: &str) -> InsertResult {
150            self.items.insert(0, str!(item));
151            if self.items.len() > self.size {
152                InsertResult::SuccessBut(vec![self.items.pop().unwrap()])
153            } else {
154                InsertResult::Success
155            }
156        }
157        pub fn queue_take(&mut self) -> FetchResult {
158            match self.items.pop() {
159                Some(item) => FetchResult::Success(item),
160                None => FetchResult::Empty,
161            }
162        }
163        pub fn stack_put(&mut self, item: &str) -> InsertResult {
164            self.items.insert(0, str!(item));
165            if self.items.len() > self.size {
166                InsertResult::SuccessBut(vec![self.items.pop().unwrap()])
167            } else {
168                InsertResult::Success
169            }
170        }
171        pub fn stack_take(&mut self) -> FetchResult {
172            if self.items.is_empty() {
173                FetchResult::Empty
174            } else {
175                FetchResult::Success(self.items.remove(0))
176            }
177        }
178        pub fn array_put(&mut self, index: usize, item: &str) -> InsertResult {
179            if index > self.size {
180                return InsertResult::CollisionDetected;
181            }
182            let old = self.items.remove(index);
183            self.items.insert(index, str!(item));
184            if old.is_empty() {
185                InsertResult::Success
186            } else {
187                InsertResult::SuccessBut(vec![old])
188            }
189        }
190        pub fn array_take(&mut self, index: usize) -> FetchResult {
191            if index > self.size {
192                return FetchResult::Empty;
193            }
194            let old = self.items.remove(index);
195            self.items.insert(index, str!(""));
196            if old.is_empty() {
197                FetchResult::Success(old)
198            } else {
199                FetchResult::Empty
200            }
201        }
202    }
203
204    impl fmt::Display for QueueStackModus {
205        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
206            for index in 0..self.size {
207                let item = self.items.get(index);
208                if let Some(item) = item {
209                    if item.is_empty() {
210                        write!(f, " |_|")?;
211                    } else {
212                        write!(f, " |{}|", green(item))?;
213                    }
214                } else {
215                    write!(f, " |_|")?;
216                }
217            }
218            write!(f, "")
219        }
220    }
221
222    impl fmt::Display for ArrayQSModus {
223        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224            for index in 0..self.size {
225                let arr = self.array.get(index).unwrap();
226                writeln!(f, "{}: {}", index, arr)?;
227            }
228            write!(f, "")
229        }
230    }
231}
232
233pub mod rose {
234    use super::*;
235    pub struct TreeBranch {
236        pub trunk: String,
237        pub lbranch: Option<Box<TreeBranch>>,
238        pub rbranch: Option<Box<TreeBranch>>,
239    }
240    pub struct Modus {
241        pub root: TreeBranch,
242    }
243    enum TakeResult {
244        Return(String),
245        Found(bool),
246        Empty,
247    }
248
249    impl TreeBranch {
250        fn new(trunk: &str) -> TreeBranch {
251            TreeBranch {
252                trunk: str!(trunk),
253                lbranch: None,
254                rbranch: None,
255            }
256        }
257        fn size(&self) -> usize {
258            let mut rv = 1;
259            if self.rbranch.is_some() {
260                rv += self.rbranch.as_ref().unwrap().size();
261            }
262            if self.lbranch.is_some() {
263                rv += self.lbranch.as_ref().unwrap().size();
264            }
265            rv
266        }
267        fn flatten(&self) -> Vec<String> {
268            fn flatten_branch(
269                buffer: &mut Vec<String>,
270                delim: &str,
271                branch: &Option<Box<TreeBranch>>,
272            ) {
273                match branch {
274                    Some(b) => {
275                        let branch_vec: Vec<String> = b.flatten();
276                        for branch_item in &branch_vec {
277                            buffer.push(format!(" {} {}", delim, branch_item));
278                        }
279                    }
280                    None => (),
281                }
282            }
283            let mut strings = Vec::<String>::new();
284            strings.push(format!("-{}", self.trunk.clone()));
285            flatten_branch(&mut strings, "L", &self.lbranch);
286            flatten_branch(&mut strings, "R", &self.rbranch);
287            strings
288        }
289        fn compactify(&self) -> Vec<String> {
290            fn compactify_branch(buffer: &mut Vec<String>, branch: &Option<Box<TreeBranch>>) {
291                match branch {
292                    Some(b) => {
293                        let mut branch_vec: Vec<String> = b.compactify();
294                        while !branch_vec.is_empty() {
295                            buffer.push(branch_vec.remove(0));
296                        }
297                    }
298                    None => (),
299                }
300            }
301            let mut strings = Vec::<String>::new();
302            strings.push(self.trunk.clone());
303            compactify_branch(&mut strings, &self.lbranch);
304            compactify_branch(&mut strings, &self.rbranch);
305            strings
306        }
307        fn add(&mut self, item: &str) {
308            match str!(item).cmp(&self.trunk) {
309                Ordering::Less => {
310                    if let Some(lbranch) = &mut self.lbranch {
311                        lbranch.add(item)
312                    } else {
313                        self.lbranch = Some(Box::new(TreeBranch::new(item)));
314                    }
315                }
316                Ordering::Greater => {
317                    if let Some(rbranch) = &mut self.rbranch {
318                        rbranch.add(item)
319                    } else {
320                        self.rbranch = Some(Box::new(TreeBranch::new(item)));
321                    }
322                }
323                Ordering::Equal => {}
324            }
325        }
326        fn depths(&self) -> Vec<u32> {
327            fn depths_impl(branch: &TreeBranch, level: u32) -> Vec<u32> {
328                if branch.lbranch.is_none() && branch.rbranch.is_none() {
329                    return vec![level];
330                } else {
331                    let mut rtvl = Vec::<u32>::new();
332                    if branch.lbranch.is_some() {
333                        rtvl.append(&mut depths_impl(
334                            &branch.lbranch.as_ref().unwrap(),
335                            level + 1,
336                        ));
337                    }
338                    if branch.rbranch.is_some() {
339                        rtvl.append(&mut depths_impl(
340                            &branch.rbranch.as_ref().unwrap(),
341                            level + 1,
342                        ));
343                    }
344                    rtvl
345                }
346            }
347            depths_impl(self, 0)
348        }
349        fn leaves(&self) -> Vec<&str> {
350            if self.lbranch.is_none() && self.rbranch.is_none() {
351                return vec![&self.trunk[..]];
352            } else {
353                let mut vec: Vec<&str> = vec![];
354                if let Some(lb) = &self.lbranch {
355                    vec.append(&mut lb.leaves());
356                }
357                if let Some(rb) = &self.rbranch {
358                    vec.append(&mut rb.leaves());
359                }
360                vec
361            }
362        }
363        fn take(&mut self, item: &str, is_root: bool) -> TakeResult {
364            match str!(item).cmp(&self.trunk) {
365                Ordering::Less => {
366                    if let Some(branch) = &mut self.lbranch {
367                        match branch.take(item, false) {
368                            TakeResult::Found(_) => {
369                                let rstr = branch.trunk.clone();
370                                self.lbranch = None;
371                                TakeResult::Return(rstr)
372                            }
373                            TakeResult::Return(rstr) => TakeResult::Return(rstr),
374                            TakeResult::Empty => TakeResult::Empty,
375                        }
376                    } else {
377                        TakeResult::Empty
378                    }
379                }
380                Ordering::Greater => {
381                    if let Some(branch) = &mut self.rbranch {
382                        match branch.take(item, false) {
383                            TakeResult::Found(_) => {
384                                let rstr = branch.trunk.clone();
385                                self.rbranch = None;
386                                TakeResult::Return(rstr)
387                            }
388                            TakeResult::Return(rstr) => TakeResult::Return(rstr),
389                            TakeResult::Empty => TakeResult::Empty,
390                        }
391                    } else {
392                        TakeResult::Empty
393                    }
394                }
395                Ordering::Equal => TakeResult::Found(is_root),
396            }
397        }
398    }
399
400    impl Modus {
401        pub fn new(root: &str) -> Modus {
402            Modus {
403                root: TreeBranch::new(root),
404            }
405        }
406        pub fn add(&mut self, item: &str) -> InsertResult {
407            self.root.add(item);
408            InsertResult::Success
409        }
410        pub fn size(&self) -> usize {
411            self.root.size()
412        }
413        pub fn takeables(&self) -> Vec<&str> {
414            self.root.leaves()
415        }
416        pub fn take(&mut self, item: &str) -> FetchResult {
417            match self.root.take(item, true) {
418                TakeResult::Return(rstr) => FetchResult::Success(rstr),
419                _ => FetchResult::Empty,
420            }
421        }
422        pub fn take_root(&mut self) -> FetchResult {
423            let rv = FetchResult::SuccessBut(self.root.trunk.clone(), self.root.compactify());
424            self.root.lbranch = None;
425            self.root.rbranch = None;
426            self.root.trunk = String::from("");
427            rv
428        }
429        pub fn balance(&mut self) {
430            pub fn balance_impl(mut strings: Vec<String>) -> Vec<String> {
431                let mut len = strings.len();
432                if len < 2 {
433                    return strings;
434                }
435                if strings.len() % 2 == 1 {
436                    len -= 1;
437                }
438                let midpoint = len / 2;
439                let mut new_nodes = Vec::<String>::new();
440                new_nodes.push(strings.remove(midpoint));
441                let half2 = strings.split_off(midpoint);
442                new_nodes.append(&mut balance_impl(strings));
443                new_nodes.append(&mut balance_impl(half2));
444                new_nodes
445            }
446            let mut nodes = self.root.compactify();
447            nodes.sort();
448            let mut new_nodes = balance_impl(nodes);
449            let mut new_tree = TreeBranch::new(&new_nodes.remove(0));
450            for node in &new_nodes {
451                new_tree.add(node);
452            }
453            self.root = new_tree;
454        }
455        pub fn autobalance(&mut self) -> bool {
456            let mut depths = self.root.depths();
457            if depths.len() == 1 {
458                depths.insert(0, 0);
459            }
460            depths.sort();
461            if depths.last().unwrap() - depths.first().unwrap() > 1 {
462                self.balance();
463                true
464            } else {
465                false
466            }
467        }
468    }
469
470    impl fmt::Display for Modus {
471        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
472            write!(f, "Tree Modus")?;
473            let vec = self.root.flatten();
474            for v in &vec {
475                write!(f, "\n{}", v)?;
476            }
477            write!(f, "")
478        }
479    }
480}
481
482pub mod dave {
483    use super::*;
484    pub struct Modus<T>
485    where
486        T: Fn(&str) -> usize,
487    {
488        pub items: [Option<String>; 10],
489        pub hash_function: T,
490        pub detect_collisions: bool,
491    }
492
493    pub fn c2v1(key: &str) -> usize {
494        let mut total = 0;
495        for c in key.to_lowercase().chars() {
496            total += match c {
497                'a' | 'e' | 'i' | 'o' | 'u' | 'y' => 1,
498                ' ' => 0,
499                _ => 2,
500            }
501        }
502        total % 10
503    }
504
505    pub fn c1v2(key: &str) -> usize {
506        let mut total = 0;
507        for c in key.to_lowercase().chars() {
508            total += match c {
509                'a' | 'e' | 'i' | 'o' | 'u' | 'y' => 2,
510                ' ' => 0,
511                _ => 1,
512            }
513        }
514        total % 10
515    }
516
517    pub fn scrabble(key: &str) -> usize {
518        let mut total = 0;
519        for c in key.to_lowercase().chars() {
520            total += match c {
521                'a' | 'e' | 'i' | 'o' | 'u' | 'l' | 'n' | 's' | 't' | 'r' => 1,
522                'd' | 'g' => 2,
523                'b' | 'c' | 'm' | 'p' => 3,
524                'f' | 'h' | 'v' | 'w' | 'y' => 4,
525                'k' => 5,
526                'j' | 'x' => 8,
527                'q' | 'z' => 10,
528                _ => 0,
529            }
530        }
531        total % 10
532    }
533
534    impl<T> Modus<T>
535    where
536        T: Fn(&str) -> usize,
537    {
538        pub fn new(func: T) -> Modus<T> {
539            Modus {
540                items: [None, None, None, None, None, None, None, None, None, None],
541                hash_function: func,
542                detect_collisions: false,
543            }
544        }
545        pub fn toggle_collisions(&mut self) {
546            self.detect_collisions = !self.detect_collisions
547        }
548        pub fn add(&mut self, keystr: &str) -> InsertResult {
549            let key = (self.hash_function)(keystr);
550            if self.items[key].is_none() {
551                self.items[key] = Some(str!(keystr));
552                InsertResult::Success
553            } else if self.detect_collisions {
554                InsertResult::CollisionDetected
555            } else {
556                let old = vec![self.items[key].as_ref().unwrap().clone()];
557                self.items[key] = Some(str!(keystr));
558                InsertResult::SuccessBut(old)
559            }
560        }
561        pub fn get(&mut self, key: &str) -> FetchResult {
562            let key = (self.hash_function)(key);
563            if self.items[key].is_none() {
564                FetchResult::Empty
565            } else {
566                let val = self.items[key].as_ref().unwrap().clone();
567                self.items[key] = None;
568                FetchResult::Success(val)
569            }
570        }
571    }
572
573    impl<T> fmt::Display for Modus<T>
574    where
575        T: Fn(&str) -> usize,
576    {
577        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
578            writeln!(f, "Captchalogue Deck:")?;
579            for index in 0..10 {
580                let item = self.items[index].as_ref();
581                if let Some(item) = item {
582                    writeln!(f, "{} |{}|", index, item)?;
583                } else {
584                    writeln!(f, "{} |_|", index)?;
585                }
586            }
587            write!(f, "")
588        }
589    }
590}
591
592pub mod karkat {
593    use super::*;
594    pub struct Vault {
595        item: String,
596        pub code: u16,
597    }
598    #[derive(Default)]
599    pub struct Modus {
600        pub vaults: Vec<Vault>,
601    }
602
603    impl Vault {
604        pub fn new(item: &str) -> Self {
605            Self {
606                item: String::from(item),
607                code: Vault::checksum(item),
608            }
609        }
610        pub fn checksum(s: &str) -> u16 {
611            let mut sum: u16 = 0;
612            for c in s.chars() {
613                let mut buffer: [u16; 2] = [0, 0];
614                c.encode_utf16(&mut buffer);
615                sum = (sum >> 1) + ((sum & 1) << 15);
616                sum = sum.wrapping_add(buffer[0] ^ buffer[1]);
617            }
618            sum
619        }
620    }
621
622    impl Modus {
623        pub fn add(&mut self, name: &str) -> InsertResult {
624            self.vaults.push(Vault::new(name));
625            InsertResult::Success
626        }
627        pub fn size(&self) -> usize {
628            self.vaults.len()
629        }
630        pub fn from_arr(arr: [u16; 4]) -> u16 {
631            let mut r = 0;
632            r += arr[3] & 0x000F;
633            r += (arr[2] & 0x000F) << 4;
634            r += (arr[1] & 0x000F) << 8;
635            r += (arr[0] & 0x000F) << 12;
636            r
637        }
638        pub fn test(&self, index: usize, key: u16) -> [bool; 4] {
639            let mut rt: [bool; 4] = [false, false, false, false];
640            if let Some(item) = self.vaults.get(index) {
641                let code = item.code;
642                for (i, item) in rt.iter_mut().enumerate() {
643                    let mask = 0xF000 >> (i * 4);
644                    let c = code & mask;
645                    let k = key & mask;
646                    *item = c == k;
647                }
648                rt
649            } else {
650                rt
651            }
652        }
653        pub fn take(&mut self, index: usize, key: u16) -> FetchResult {
654            if let Some(item) = self.vaults.get(index) {
655                if item.code == key {
656                    FetchResult::Success(self.vaults.remove(index).item)
657                } else {
658                    FetchResult::Empty
659                }
660            } else {
661                FetchResult::Empty
662            }
663        }
664    }
665
666    impl fmt::Display for Modus {
667        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
668            for i in 0..self.vaults.len() {
669                write!(f, " |{}|", i)?;
670            }
671            write!(f, "")
672        }
673    }
674}