Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing permutation of small lists, such that [], [x] -> [[]], [[x]] #13783

Merged
merged 1 commit into from
Apr 27, 2014
Merged

Fixing permutation of small lists, such that [], [x] -> [[]], [[x]] #13783

merged 1 commit into from
Apr 27, 2014

Conversation

wackywendell
Copy link
Contributor

I filed bugs #13734 and #13759 recently, and then realized I could probably fix them myself. This does exactly that, with a couple additional modifications and additions to the test-suite to pick up on that.

I've never done this before, so please feel free to tell me all the things I'm doing wrong or could be doing better.

@@ -388,6 +398,7 @@ impl<T: Clone> Iterator<~[T]> for Permutations<T> {
fn next(&mut self) -> Option<~[T]> {
match self.swaps.next() {
None => None,
Some((0,0)) => Some(self.v.clone()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you find it necessary to have this case? I think that swap handles the case where the two indices are the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexcrichton: I had two reasons:

  1. For an empty list, there is no item 0, and that would be bad.
  2. (Not as important) For a non-empty list, AFAICT there is no code in either slice::swap or ptr::swap stopping it from actually performing the swap, i.e. copying item 0 to a temporary value, moving item 0 to item 0, and then copying the temp value back in. That seemed unnecessary...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, of course!

@wackywendell
Copy link
Contributor Author

Note that there aren't necessarily always N! permutations.

There aren't necessarily N! unique permutations, but the current implementation does not worry about uniqueness.

// However, we don't know how many are left, so the lower bound is 0.
let n = range(2, self.v.len() + 1).product();
(0, Some(n))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the size hint possibly be defined on ElementSwaps instead, and have Permutations::size_hint just call through to that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kballard: Sure, it could; is there a reason to do so?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ElementSwaps is a public type. If someone wants to use it independently of Permutations it would be nice to have a size_hint().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll work on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kballard: Question: when I commit that, should I rebase that again (wiping out the old commit), or just leave it on top of the given commit?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amend the commit and force-push. There's no benefit to keeping it around as a separate commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks, that's now done!

@exscape
Copy link
Contributor

exscape commented Apr 26, 2014

@wackywendell Ah, you're very much right. That's another difference between the current implementation and my proposed one; since it works with lexicographic permutations, it returns unique ones only.
(I am not proposing to replace the current one, however; both methods probably have their uses.)

@wackywendell
Copy link
Contributor Author

Sorry about that, hit the wrong button...

else {
return None;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me this block should be removed and instead put later in the match max block (line 373 of this current patch).

Something like:

    None => if self.emit_reset {
        self.emit_reset = false;
        if self.sdir.len() > 1 { Some((0, 1)) } else { Some((0, 0)) }
    } else {
        None
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why? I'm not sure I see why it matters much either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wackywendell Not only is it simpler code, but it avoids the unnecessary branch on calls to next() for lists of size larger than 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! You're right, it is simpler.

@lilyball
Copy link
Contributor

r=me once my last few comments are addressed. I think it makes sense to make size_hint() accurate but I'm willing to r+ even if you decide not to do that.

@wackywendell
Copy link
Contributor Author

@kballard I just added both - a counter in ElementSwaps to make size_hint() accurate, and tests of size_hint() for vectors of size 0 and 1. Thanks!

bors added a commit that referenced this pull request Apr 27, 2014
I filed bugs #13734 and #13759 recently, and then realized I could probably fix them myself. This does exactly that, with a couple additional modifications and additions to the test-suite to pick up on that.

I've never done this before, so please feel free to tell me all the things I'm doing wrong or could be doing better.
@bors bors closed this Apr 27, 2014
@bors bors merged commit b7d0feb into rust-lang:master Apr 27, 2014
@wackywendell wackywendell deleted the permfix branch May 27, 2014 23:31
arcnmx pushed a commit to arcnmx/rust that referenced this pull request Dec 17, 2022
Add parentheses for binding mode hints when they attach to an Or-pattern
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants