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

Can one zip one sequence several times and then sort zipped view? #1755

Closed
Fedr opened this issue Nov 27, 2022 · 1 comment
Closed

Can one zip one sequence several times and then sort zipped view? #1755

Fedr opened this issue Nov 27, 2022 · 1 comment

Comments

@Fedr
Copy link

Fedr commented Nov 27, 2022

In the following program, one sequence appears twice in zip-view: ( x, y, y )

#include <array>
#include <iostream>
#include <range/v3/all.hpp>

int main() {
   auto x = std::array{ 3,   2,   4,   1 };
   auto y = std::array{'A', 'B', 'C', 'D'};
   ranges::sort( ranges::views::zip( x, y, y ) );
   for ( auto c : y )
      std::cout << c << ' ';
}

Still the sorting is correct, the program prints D B A C.

Is it accidental, or it is always guaranteed to work if any of the sequences appear several times in zip-view?

@brevzin
Copy link
Collaborator

brevzin commented Nov 28, 2022

Accidental.

We have something like this:

auto e1 = std::tie(x[0], y[0], y[0]);
auto e2 = std::tie(x[1], y[1], y[1]);
std::swap(e1, e2);

What happens when we swap these tuples? We swap x[0] and x[1], then we swap y[0] and y[1], then we... swap y[0] and y[1] again. We ended up swapping the xs but not the ys.

In this case, the arrays are short enough that an insertion sort - which doesn't use swaps. If you made it long enough to necessitate swaps:

   auto x = std::array{ 3,   2,   4,   1,   0,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  -1};
   auto y = std::array{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q'};
   ranges::sort( ranges::views::zip( x, y, y ) );
   fmt::print("x={::3}\ny={}\n", x, y);

Then this fails:

x=[ -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15]
y=['A', 'C', 'D', 'B', 'Q', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']

Q should be first.

@brevzin brevzin closed this as completed Nov 28, 2022
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

No branches or pull requests

2 participants