Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion exercises/doubly-linked-list/.meta/description.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private functions.

Implement the functionality for adding and removing elements (pushing and popping)
at the front and back. This is enough to use the list as a double-ended queue.
Also implement the `len` function.
Also implement the `len` and `is_empty` functions.

In the finished implementation, all modifications of the list should be done through the cursor struct
to minimize duplication. The `push_*` and `pop_*` methods on `LinkedList`
Expand Down
2 changes: 1 addition & 1 deletion exercises/doubly-linked-list/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private functions.

Implement the functionality for adding and removing elements (pushing and popping)
at the front and back. This is enough to use the list as a double-ended queue.
Also implement the `len` function.
Also implement the `len` and `is_empty` functions.

In the finished implementation, all modifications of the list should be done through the cursor struct
to minimize duplication. The `push_*` and `pop_*` methods on `LinkedList`
Expand Down
4 changes: 4 additions & 0 deletions exercises/doubly-linked-list/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ impl<T> LinkedList<T> {
}
}

pub fn is_empty(&self) -> bool {
self.len == 0
}

pub fn len(&self) -> usize {
self.len
}
Expand Down
9 changes: 9 additions & 0 deletions exercises/doubly-linked-list/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ impl<T> LinkedList<T> {
unimplemented!()
}

// 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 LinkedList)
pub fn is_empty(&self) -> bool {
unimplemented!()
}

pub fn len(&self) -> usize {
unimplemented!()
}
Expand Down
37 changes: 33 additions & 4 deletions exercises/doubly-linked-list/tests/doubly-linked-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fn is_generic() {
fn basics_empty_list() {
let list: LinkedList<i32> = LinkedList::new();
assert_eq!(list.len(), 0);
assert!(list.is_empty());
}

// push / pop at back ————————————————————————————————————————
Expand All @@ -25,7 +26,12 @@ fn basics_single_element_back() {
list.push_back(5);

assert_eq!(list.len(), 1);
assert!(!list.is_empty());

assert_eq!(list.pop_back(), Some(5));

assert_eq!(list.len(), 0);
assert!(list.is_empty());
}

#[test]
Expand All @@ -34,13 +40,16 @@ fn basics_push_pop_at_back() {
let mut list: LinkedList<i32> = LinkedList::new();
for i in 0..10 {
list.push_back(i);
assert_eq!(list.len(), i as usize + 1);
assert!(!list.is_empty());
}
assert_eq!(list.len(), 10);

for i in (0..10).rev() {
assert_eq!(list.len(), i as usize + 1);
assert!(!list.is_empty());
assert_eq!(i, list.pop_back().unwrap());
}
assert_eq!(list.len(), 0);
assert!(list.is_empty());
}

// push / pop at front ———————————————————————————————————————
Expand All @@ -51,7 +60,12 @@ fn basics_single_element_front() {
list.push_front(5);

assert_eq!(list.len(), 1);
assert!(!list.is_empty());

assert_eq!(list.pop_front(), Some(5));

assert_eq!(list.len(), 0);
assert!(list.is_empty());
}

#[test]
Expand All @@ -60,13 +74,16 @@ fn basics_push_pop_at_front() {
let mut list: LinkedList<i32> = LinkedList::new();
for i in 0..10 {
list.push_front(i);
assert_eq!(list.len(), i as usize + 1);
assert!(!list.is_empty());
}
assert_eq!(list.len(), 10);

for i in (0..10).rev() {
assert_eq!(list.len(), i as usize + 1);
assert!(!list.is_empty());
assert_eq!(i, list.pop_front().unwrap());
}
assert_eq!(list.len(), 0);
assert!(list.is_empty());
}

// push / pop at mixed sides —————————————————————————————————
Expand All @@ -76,10 +93,16 @@ fn basics_push_front_pop_back() {
let mut list: LinkedList<i32> = LinkedList::new();
for i in 0..10 {
list.push_front(i);
assert_eq!(list.len(), i as usize + 1);
assert!(!list.is_empty());
}
for i in 0..10 {
assert_eq!(list.len(), 10 - i as usize);
assert!(!list.is_empty());
assert_eq!(i, list.pop_back().unwrap());
}
assert_eq!(list.len(), 0);
assert!(list.is_empty());
}

#[test]
Expand All @@ -88,10 +111,16 @@ fn basics_push_back_pop_front() {
let mut list: LinkedList<i32> = LinkedList::new();
for i in 0..10 {
list.push_back(i);
assert_eq!(list.len(), i as usize + 1);
assert!(!list.is_empty());
}
for i in 0..10 {
assert_eq!(list.len(), 10 - i as usize);
assert!(!list.is_empty());
assert_eq!(i, list.pop_front().unwrap());
}
assert_eq!(list.len(), 0);
assert!(list.is_empty());
}

// ———————————————————————————————————————————————————————————
Expand Down
4 changes: 4 additions & 0 deletions exercises/simple-linked-list/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ impl<T> SimpleLinkedList<T> {
SimpleLinkedList { head: None, len: 0 }
}

pub fn is_empty(&self) -> bool {
self.len == 0
}

pub fn len(&self) -> usize {
self.len
}
Expand Down
9 changes: 9 additions & 0 deletions exercises/simple-linked-list/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ impl<T> SimpleLinkedList<T> {
unimplemented!()
}

// 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 {
unimplemented!()
}

pub fn len(&self) -> usize {
unimplemented!()
}
Expand Down
32 changes: 32 additions & 0 deletions exercises/simple-linked-list/tests/simple-linked-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,38 @@ fn test_pop_decrements_length() {
assert_eq!(list.len(), 0, "list's length must be 0");
}

#[test]
#[ignore]
fn test_is_empty() {
let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
assert!(list.is_empty(), "List wasn't empty on creation");
for inserts in 0..100 {
for i in 0..inserts {
list.push(i);
assert!(
!list.is_empty(),
"List was empty after having inserted {}/{} elements",
i,
inserts
);
}
for i in 0..inserts {
assert!(
!list.is_empty(),
"List was empty before removing {}/{} elements",
i,
inserts
);
list.pop();
}
assert!(
list.is_empty(),
"List wasn't empty after having removed {} elements",
inserts
);
}
}

#[test]
#[ignore]
fn test_pop_returns_head_element_and_removes_it() {
Expand Down