Last active
November 5, 2022 12:37
-
-
Save shubhamkumar13/a2c145f48094b5505701a97dde8ffbe1 to your computer and use it in GitHub Desktop.
Trying to implement algorithm design in rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::VecDeque; | |
use std::panic; | |
trait FP<T> { | |
fn cons(self, x : T) -> VecDeque<T>; | |
fn snoc(self, x : T) -> VecDeque<T>; | |
fn tail(self) -> Option<VecDeque<T>>; | |
fn init(self) -> Option<VecDeque<T>>; | |
fn head(self) -> Option<T>; | |
fn last(self) -> Option<T>; | |
} | |
#[derive(Debug, Clone)] | |
struct SymList<T : Clone> (VecDeque<T>, VecDeque<T>); | |
impl<T : Clone> FP<T> for VecDeque<T> { | |
fn cons(self, x : T) -> VecDeque<T> { | |
let mut v = self; | |
v.push_front(x); | |
v | |
} | |
fn snoc(self, x : T) -> VecDeque<T> { | |
let mut v = self; | |
v.push_back(x); | |
v | |
} | |
fn tail(self) -> Option<VecDeque<T>> { | |
let mut v = self; | |
if !v.is_empty() { | |
Some(v.split_off(0)) | |
} else { | |
None | |
} | |
} | |
fn init(self) -> Option<VecDeque<T>> { | |
let mut v = self; | |
if !v.is_empty() { | |
let _ = v.split_off(v.len() - 1); | |
Some(v) | |
} else { | |
None | |
} | |
} | |
fn head(self) -> Option<T> { | |
let mut v = self; | |
v.pop_front() | |
} | |
fn last(self) -> Option<T> { | |
let mut v = self; | |
v.pop_back() | |
} | |
} | |
impl<T : Clone> SymList<T> { | |
fn new(arr : Vec<T>) -> Self { | |
let mut v = VecDeque::from(arr.clone()); | |
let mut ys = v.split_off(v.len() / 2); | |
ys.make_contiguous().reverse(); | |
SymList(v, ys) | |
} | |
fn from_sl(self) -> VecDeque<T> { | |
let mut v1 = self.0.clone(); | |
let mut v2 = self.1.clone(); | |
v2.make_contiguous().reverse(); | |
v1.append(&mut v2); | |
v1 | |
} | |
fn snoc_sl (self, x : T) -> Self { | |
let mut v1 = self.0.clone(); | |
let mut v2 = self.1.clone(); | |
if v1.is_empty() { | |
SymList(v2, VecDeque::from(vec![x])) | |
} else { | |
v2.push_front(x); | |
SymList(v1, v2) | |
} | |
} | |
fn cons_sl (self, x : T) -> Self { | |
let mut v1 = self.0.clone(); | |
let mut v2 = self.1.clone(); | |
if v2.is_empty() { | |
SymList(VecDeque::from(vec![x]), v2) | |
} else { | |
v1.push_front(x); | |
SymList(v1, v2) | |
} | |
} | |
fn head_sl (self) -> Option<T> { | |
let mut v1 = self.0.clone(); | |
let mut v2 = self.1.clone(); | |
match (v1.is_empty(), v2.is_empty()) { | |
(true, true) => None, | |
(true, false) => v2.head(), | |
(false, _) => v1.head() | |
} | |
} | |
fn last_sl(self) -> Option<T> { | |
let mut v1 = self.0.clone(); | |
let mut v2 = self.1.clone(); | |
match (v2.is_empty(), v1.is_empty()) { | |
(true, true) => None, | |
(true, false) => v1.head(), | |
(false, _) => v2.head() | |
} | |
} | |
fn tail_sl(self) -> Self { | |
let mut v1 = self.0.clone(); | |
let mut v2 = self.1.clone(); | |
match v1.len() { | |
0 => { | |
if v2.is_empty() { | |
panic!("empty symmetric list") | |
} else { | |
SymList(VecDeque::new(), VecDeque::new()) | |
} | |
}, | |
1 => { | |
let (vs, us) = { | |
let vs = v2.split_off(v2.len() / 2); | |
v2.make_contiguous().reverse(); | |
let us = v2; | |
(vs, us) | |
}; | |
SymList(vs, us) | |
}, | |
_ => { | |
if let Some(xs) = v1.tail() { | |
SymList(xs, v2) | |
} else { | |
panic!("cannot get a tail value") | |
} | |
} | |
} | |
} | |
} | |
// cons adds elements at the end | |
// eq1 lst x = cons x $ from_sl lst | |
// eq2 lst x = from_sl $ cons_sl lst | |
// eq1 = eq2 | |
// snoc adds element at the end of a list | |
// eq1 lst x = snoc x $ from_sl lst | |
// eq2 lst x = from_sl $ snoc_sl lst | |
// eq1 = eq2 | |
fn main () { | |
let s = SymList::<i32>::new(vec![1,2,3]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment