Skip to content

Commit 53acb5e

Browse files
authored
Merge pull request #1028 from petertseng/isempty
simple-linked-list, doubly-linked-list: Add is_empty doubly-linked-list: Test len in more places
2 parents 82f0447 + 553d2c1 commit 53acb5e

File tree

8 files changed

+93
-6
lines changed

8 files changed

+93
-6
lines changed

exercises/doubly-linked-list/.meta/description.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ private functions.
3333

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

3838
In the finished implementation, all modifications of the list should be done through the cursor struct
3939
to minimize duplication. The `push_*` and `pop_*` methods on `LinkedList`

exercises/doubly-linked-list/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ private functions.
3535

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

4040
In the finished implementation, all modifications of the list should be done through the cursor struct
4141
to minimize duplication. The `push_*` and `pop_*` methods on `LinkedList`

exercises/doubly-linked-list/example.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ impl<T> LinkedList<T> {
7777
}
7878
}
7979

80+
pub fn is_empty(&self) -> bool {
81+
self.len == 0
82+
}
83+
8084
pub fn len(&self) -> usize {
8185
self.len
8286
}

exercises/doubly-linked-list/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ impl<T> LinkedList<T> {
1414
unimplemented!()
1515
}
1616

17+
// You may be wondering why it's necessary to have is_empty()
18+
// when it can easily be determined from len().
19+
// It's good custom to have both because len() can be expensive for some types,
20+
// whereas is_empty() is almost always cheap.
21+
// (Also ask yourself whether len() is expensive for LinkedList)
22+
pub fn is_empty(&self) -> bool {
23+
unimplemented!()
24+
}
25+
1726
pub fn len(&self) -> usize {
1827
unimplemented!()
1928
}

exercises/doubly-linked-list/tests/doubly-linked-list.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ fn is_generic() {
1515
fn basics_empty_list() {
1616
let list: LinkedList<i32> = LinkedList::new();
1717
assert_eq!(list.len(), 0);
18+
assert!(list.is_empty());
1819
}
1920

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

2728
assert_eq!(list.len(), 1);
29+
assert!(!list.is_empty());
30+
2831
assert_eq!(list.pop_back(), Some(5));
32+
33+
assert_eq!(list.len(), 0);
34+
assert!(list.is_empty());
2935
}
3036

3137
#[test]
@@ -34,13 +40,16 @@ fn basics_push_pop_at_back() {
3440
let mut list: LinkedList<i32> = LinkedList::new();
3541
for i in 0..10 {
3642
list.push_back(i);
43+
assert_eq!(list.len(), i as usize + 1);
44+
assert!(!list.is_empty());
3745
}
38-
assert_eq!(list.len(), 10);
39-
4046
for i in (0..10).rev() {
47+
assert_eq!(list.len(), i as usize + 1);
48+
assert!(!list.is_empty());
4149
assert_eq!(i, list.pop_back().unwrap());
4250
}
4351
assert_eq!(list.len(), 0);
52+
assert!(list.is_empty());
4453
}
4554

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

5362
assert_eq!(list.len(), 1);
63+
assert!(!list.is_empty());
64+
5465
assert_eq!(list.pop_front(), Some(5));
66+
67+
assert_eq!(list.len(), 0);
68+
assert!(list.is_empty());
5569
}
5670

5771
#[test]
@@ -60,13 +74,16 @@ fn basics_push_pop_at_front() {
6074
let mut list: LinkedList<i32> = LinkedList::new();
6175
for i in 0..10 {
6276
list.push_front(i);
77+
assert_eq!(list.len(), i as usize + 1);
78+
assert!(!list.is_empty());
6379
}
64-
assert_eq!(list.len(), 10);
65-
6680
for i in (0..10).rev() {
81+
assert_eq!(list.len(), i as usize + 1);
82+
assert!(!list.is_empty());
6783
assert_eq!(i, list.pop_front().unwrap());
6884
}
6985
assert_eq!(list.len(), 0);
86+
assert!(list.is_empty());
7087
}
7188

7289
// push / pop at mixed sides —————————————————————————————————
@@ -76,10 +93,16 @@ fn basics_push_front_pop_back() {
7693
let mut list: LinkedList<i32> = LinkedList::new();
7794
for i in 0..10 {
7895
list.push_front(i);
96+
assert_eq!(list.len(), i as usize + 1);
97+
assert!(!list.is_empty());
7998
}
8099
for i in 0..10 {
100+
assert_eq!(list.len(), 10 - i as usize);
101+
assert!(!list.is_empty());
81102
assert_eq!(i, list.pop_back().unwrap());
82103
}
104+
assert_eq!(list.len(), 0);
105+
assert!(list.is_empty());
83106
}
84107

85108
#[test]
@@ -88,10 +111,16 @@ fn basics_push_back_pop_front() {
88111
let mut list: LinkedList<i32> = LinkedList::new();
89112
for i in 0..10 {
90113
list.push_back(i);
114+
assert_eq!(list.len(), i as usize + 1);
115+
assert!(!list.is_empty());
91116
}
92117
for i in 0..10 {
118+
assert_eq!(list.len(), 10 - i as usize);
119+
assert!(!list.is_empty());
93120
assert_eq!(i, list.pop_front().unwrap());
94121
}
122+
assert_eq!(list.len(), 0);
123+
assert!(list.is_empty());
95124
}
96125

97126
// ———————————————————————————————————————————————————————————

exercises/simple-linked-list/example.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ impl<T> SimpleLinkedList<T> {
1515
SimpleLinkedList { head: None, len: 0 }
1616
}
1717

18+
pub fn is_empty(&self) -> bool {
19+
self.len == 0
20+
}
21+
1822
pub fn len(&self) -> usize {
1923
self.len
2024
}

exercises/simple-linked-list/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ impl<T> SimpleLinkedList<T> {
1111
unimplemented!()
1212
}
1313

14+
// You may be wondering why it's necessary to have is_empty()
15+
// when it can easily be determined from len().
16+
// It's good custom to have both because len() can be expensive for some types,
17+
// whereas is_empty() is almost always cheap.
18+
// (Also ask yourself whether len() is expensive for SimpleLinkedList)
19+
pub fn is_empty(&self) -> bool {
20+
unimplemented!()
21+
}
22+
1423
pub fn len(&self) -> usize {
1524
unimplemented!()
1625
}

exercises/simple-linked-list/tests/simple-linked-list.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,38 @@ fn test_pop_decrements_length() {
2828
assert_eq!(list.len(), 0, "list's length must be 0");
2929
}
3030

31+
#[test]
32+
#[ignore]
33+
fn test_is_empty() {
34+
let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
35+
assert!(list.is_empty(), "List wasn't empty on creation");
36+
for inserts in 0..100 {
37+
for i in 0..inserts {
38+
list.push(i);
39+
assert!(
40+
!list.is_empty(),
41+
"List was empty after having inserted {}/{} elements",
42+
i,
43+
inserts
44+
);
45+
}
46+
for i in 0..inserts {
47+
assert!(
48+
!list.is_empty(),
49+
"List was empty before removing {}/{} elements",
50+
i,
51+
inserts
52+
);
53+
list.pop();
54+
}
55+
assert!(
56+
list.is_empty(),
57+
"List wasn't empty after having removed {} elements",
58+
inserts
59+
);
60+
}
61+
}
62+
3163
#[test]
3264
#[ignore]
3365
fn test_pop_returns_head_element_and_removes_it() {

0 commit comments

Comments
 (0)