Skip to content

Commit

Permalink
fixed seqlist
Browse files Browse the repository at this point in the history
  • Loading branch information
Abdul Haliq authored and Abdul Haliq committed Dec 4, 2023
1 parent ce2d828 commit f2b3fd9
Showing 1 changed file with 160 additions and 77 deletions.
237 changes: 160 additions & 77 deletions findatastructures/src/seqlist/mod.rs
Original file line number Diff line number Diff line change
@@ -1,88 +1,171 @@
use seq::Seq;
use seq::SeqIterator;

enum SeqRef<'a, T> {
Owned(Seq<'a, T>),
Borrowed(&'a Seq<'a, T>),
#[derive(Debug, Clone)]
pub struct SeqList<'a, T> {
seq: Seq<'a, T>,
}

impl<'a, T:Clone> SeqRef<'a, T> {
fn get_ref(&'a self) -> &'a Seq<'a, T> {
match self {
SeqRef::Owned(seq) => &seq,
SeqRef::Borrowed(seq) => seq,
}
}
fn push(&'a self, value: T) -> Self {
let seq = match &self {
SeqRef::Owned(seq) => Seq::ConsRef(value, &seq),
SeqRef::Borrowed(seq) => Seq::ConsRef(value, seq),
};
SeqRef::Owned(seq)
}
fn pop(&'a self) -> Option<(&T, Self)> {
self.get_ref().tail().map(|tail| {
(
self.get_ref().head().unwrap(),
SeqRef::Borrowed(tail),
)
})
}
impl<'a, T: Clone> SeqList<'a, T> {
pub fn new() -> Self {
SeqList { seq: Seq::Empty }
}

pub fn push(&'a self, value: T) -> Self {
SeqList {
seq: Seq::ConsRef(value, &self.seq),
}
}

pub fn pop(&'a self) -> Option<(&T, Self)> {
self.seq.head().map(|head| {
(
head,
SeqList {
seq: self.seq.tail().unwrap().clone(),
},
)
})
}

pub fn peek(&'a self) -> Option<&T> {
self.seq.head()
}

pub fn is_empty(&'a self) -> bool {
self.seq.head().is_none()
}

pub fn len(&'a self) -> usize {
self.seq.into_iter().count()
}

pub fn reverse(&'a self) -> Self {
SeqList {
seq: self.into_iter().fold(Seq::Empty, |acc, item| {
Seq::ConsOwn(item.clone(), Box::new(acc))
}),
}
}

pub fn map<U: Clone, F>(&self, f: F) -> SeqList<'a, U>
where
F: Fn(&T) -> U,
{
let mut seq = Seq::Empty;
for item in self.into_iter() {
seq = Seq::ConsOwn(f(item), Box::new(seq));
}
for item in seq.clone().into_iter() {
seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone()));
}
SeqList { seq: seq }
}

pub fn fold<U, F>(&self, init: U, f: F) -> U
where
F: Fn(U, &T) -> U,
{
let mut acc = init;
for item in self.into_iter() {
acc = f(acc, item);
}
acc
}

pub fn any<F>(&self, f: F) -> bool
where
F: Fn(&T) -> bool,
{
self.fold(false, |acc, item| acc || f(item))
}

pub fn all<F>(&self, f: F) -> bool
where
F: Fn(&T) -> bool,
{
self.fold(true, |acc, item| acc && f(item))
}

pub fn find<F>(&self, f: F) -> Option<&T>
where
F: FnMut(&&T) -> bool,
{
self.into_iter().find(f)
}

pub fn filter<F>(&self, f: F) -> Self
where
F: Fn(&T) -> bool,
{
let mut seq = Seq::Empty;
for item in self.into_iter() {
if f(item) {
seq = Seq::ConsOwn(item.clone(), Box::new(seq));
}
}
for item in seq.clone().into_iter() {
seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone()));
}
SeqList { seq: seq }
}
}

pub struct SeqList<'a, T> {
seq: SeqRef<'a, T>,
impl<'a, T: Clone + PartialEq> SeqList<'a, T> {
pub fn remove(&self, value: &T) -> Self {
self.filter(|x| *x != *value)
}

pub fn chain(&self, other: &Self) -> Self {
let mut seq = Seq::Empty;
for item in self.into_iter() {
seq = Seq::ConsOwn(item.clone(), Box::new(seq));
}
for item in other.into_iter() {
seq = Seq::ConsOwn(item.clone(), Box::new(seq));
}
for item in seq.clone().into_iter() {
seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone()));
}
SeqList { seq: seq }
}
}

impl<'a, T:Clone> SeqList<'a, T> {
pub fn new() -> Self {
SeqList { seq: SeqRef::Borrowed(&Seq::Empty) }
}

pub fn push(&'a self, value: T) -> Self {
SeqList { seq: self.seq.push(value) }
}

pub fn pop(&'a self) -> Option<(&T, Self)> {
self.seq.pop().map(|(head, tail)| {
(
head,
SeqList { seq: tail },
)
})
}

pub fn peek(&'a self) -> Option<&T> {
self.seq.get_ref().head()
}

pub fn is_empty(&'a self) -> bool {
self.seq.get_ref().head().is_none()
}

pub fn len(&'a self) -> usize {
self.seq.get_ref().into_iter().count()
}

pub fn into_iter(&'a self) -> SeqIterator<'a, T> {
self.seq.get_ref().into_iter()
}

pub fn reverse(&'a self) -> Self {
let mut new = SeqList::new();
for item in self.into_iter() {
new = new.push(item.clone());
}
new
}

pub fn from_iter(iter: SeqIterator<'a, T>) -> Self {
let new = SeqList::new();
for item in iter {
new = new.push(item.clone());
}
new = new.reverse();
new
}
impl<'a, T> IntoIterator for &'a SeqList<'a, T>
where
T: 'a,
{
type Item = &'a T;
type IntoIter = SeqIterator<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.seq.into_iter()
}
}

impl<'a, T: Clone> FromIterator<T> for SeqList<'a, T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut seq = Seq::Empty;
for item in iter {
seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone()));
}
for item in seq.clone().into_iter() {
seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone()));
}
SeqList { seq: seq }
}
}

impl<'a, T: PartialEq> SeqList<'a, T> {
pub fn contains(&self, v: &T) -> bool {
self.into_iter().any(|x| x == v)
}
}

impl<'a, T: Clone + PartialEq> PartialEq for SeqList<'a, T> {
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
self.into_iter().zip(other.into_iter()).all(|(a, b)| a == b)
}
}

0 comments on commit f2b3fd9

Please sign in to comment.