From 02481656966b0a8dfc95cf3c22bcc049660ff7d4 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Sat, 26 Dec 2020 17:48:38 +0000 Subject: Move Rust exercises in a subdirectory --- simple-linked-list/src/lib.rs | 109 ------------------------------------------ 1 file changed, 109 deletions(-) delete mode 100644 simple-linked-list/src/lib.rs (limited to 'simple-linked-list/src/lib.rs') diff --git a/simple-linked-list/src/lib.rs b/simple-linked-list/src/lib.rs deleted file mode 100644 index 75e82f5..0000000 --- a/simple-linked-list/src/lib.rs +++ /dev/null @@ -1,109 +0,0 @@ -use std::iter::FromIterator; - -#[derive(Debug)] -struct Node { - data: T, - next: Option>>, -} - -impl Node { - pub fn new(data: T, next: Option>>) -> Self { - Node { data, next } - } - - pub fn len(&self) -> usize { - 1 + self.next.as_ref().map(|n| n.len()).unwrap_or(0) - } -} - -#[derive(Debug)] -pub struct SimpleLinkedList { - head: Option>>, -} - -impl SimpleLinkedList { - pub fn new() -> Self { - SimpleLinkedList { head: None } - } - - // You may be wondering why it's necessary to have is_empty() - // when it can easily be determined from len(). - // It's good custom to have both because len() can be expensive for some types, - // whereas is_empty() is almost always cheap. - // (Also ask yourself whether len() is expensive for SimpleLinkedList) - pub fn is_empty(&self) -> bool { - self.head.is_none() - } - - pub fn len(&self) -> usize { - self.head.as_ref().map(|n| n.len()).unwrap_or(0) - } - - pub fn push(&mut self, _element: T) { - // let node = Box::new(Node::new(_element, self.head.take())); - // self.head.replace(node); - self.head = Some(Box::new(Node::new(_element, self.head.take()))); - } - - pub fn pop(&mut self) -> Option { - self.head.take().map(|n| { - // n.next.map(|n1| self.head.replace(n1)); - self.head = n.next; - n.data - }) - } - - pub fn peek(&self) -> Option<&T> { - self.head.as_ref().map(|n| &n.data) - } - - pub fn rev(self) -> SimpleLinkedList { - self.rev_aux(SimpleLinkedList::new()) - } - - pub fn rev_aux(mut self, mut acc: SimpleLinkedList) -> SimpleLinkedList { - if let Some(e) = self.pop() { - acc.push(e); - self.rev_aux(acc) - } else { - acc - } - } - - fn into_aux(mut self, mut acc: Vec) -> Vec { - if let Some(e) = self.pop() { - acc.push(e); - self.into_aux(acc) - } else { - acc - } - } -} - -impl FromIterator for SimpleLinkedList { - fn from_iter>(_iter: I) -> Self { - _iter - .into_iter() - .fold(SimpleLinkedList::new(), |mut acc, n| { - acc.push(n); - acc - }) - } -} - -// In general, it would be preferable to implement IntoIterator for SimpleLinkedList -// instead of implementing an explicit conversion to a vector. This is because, together, -// FromIterator and IntoIterator enable conversion between arbitrary collections. -// Given that implementation, converting to a vector is trivial: -// -// let vec: Vec<_> = simple_linked_list.into_iter().collect(); -// -// The reason this exercise's API includes an explicit conversion to Vec instead -// of IntoIterator is that implementing that interface is fairly complicated, and -// demands more of the student than we expect at this point in the track. - -impl Into> for SimpleLinkedList { - fn into(self) -> Vec { - self.rev().into_aux(Vec::new()) - } -} -- cgit v1.2.3