Skip to content

Commit 13aa10e

Browse files
committed
Fix combinations(0) and combinations_with_replacement(0)
The empty combination is always a valid combination of length 0. Fixes #361 while also simplifying the code. Signed-off-by: Anders Kaseorg <[email protected]>
1 parent 09403b3 commit 13aa10e

File tree

4 files changed

+20
-20
lines changed

4 files changed

+20
-20
lines changed

src/combinations.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,11 @@ impl<I> Iterator for Combinations<I>
5151
type Item = Vec<I::Item>;
5252
fn next(&mut self) -> Option<Self::Item> {
5353
let mut pool_len = self.pool.len();
54-
if self.pool.is_done() {
55-
if pool_len == 0 || self.k > pool_len {
56-
return None;
57-
}
58-
}
5954

6055
if self.first {
56+
if self.pool.is_done() {
57+
return None;
58+
}
6159
self.first = false;
6260
} else if self.k == 0 {
6361
return None;

src/combinations_with_replacement.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ where
6666
// If this is the first iteration, return early
6767
if self.first {
6868
// In empty edge cases, stop iterating immediately
69-
return if self.k == 0 || self.pool.is_done() {
69+
return if self.k != 0 && !self.pool.get_next() {
7070
None
7171
// Otherwise, yield the initial state
7272
} else {
@@ -77,8 +77,7 @@ where
7777

7878
// Check if we need to consume more from the iterator
7979
// This will run while we increment our first index digit
80-
if !self.pool.is_done() {
81-
self.pool.get_next();
80+
if self.pool.get_next() {
8281
self.max_index = self.pool.len() - 1;
8382
}
8483

src/lazy_buffer.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,10 @@ where
1212
I: Iterator,
1313
{
1414
pub fn new(it: I) -> LazyBuffer<I> {
15-
let mut it = it;
16-
let mut buffer = Vec::new();
17-
let done;
18-
if let Some(first) = it.next() {
19-
buffer.push(first);
20-
done = false;
21-
} else {
22-
done = true;
23-
}
2415
LazyBuffer {
2516
it: it,
26-
done: done,
27-
buffer: buffer,
17+
done: false,
18+
buffer: Vec::new(),
2819
}
2920
}
3021

tests/test_std.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,13 @@ fn combinations_of_too_short() {
599599
#[test]
600600
fn combinations_zero() {
601601
it::assert_equal((1..3).combinations(0), vec![vec![]]);
602+
it::assert_equal((0..0).combinations(0), vec![vec![]]);
603+
}
604+
605+
#[test]
606+
fn permutations_zero() {
607+
it::assert_equal((1..3).permutations(0), vec![vec![]]);
608+
it::assert_equal((0..0).permutations(0), vec![vec![]]);
602609
}
603610

604611
#[test]
@@ -620,7 +627,12 @@ fn combinations_with_replacement() {
620627
// Zero size
621628
it::assert_equal(
622629
(0..3).combinations_with_replacement(0),
623-
<Vec<Vec<_>>>::new(),
630+
vec![vec![]],
631+
);
632+
// Zero size on empty pool
633+
it::assert_equal(
634+
(0..0).combinations_with_replacement(0),
635+
vec![vec![]],
624636
);
625637
// Empty pool
626638
it::assert_equal(

0 commit comments

Comments
 (0)