How to loop over pairs and odds in the same loop?

Aug 3, 2018 at 3:24pm
Hey,

I question comes in mind is there any option to write a loop (for, while, do while)
that allows looping over pairs then impairs

something like this
1
2
3
4
5
6
for( ...)
  cout << i<< endl;

std output:
0 2 4 6 8 
1 3 5 7 9 
Last edited on Aug 3, 2018 at 3:26pm
Aug 3, 2018 at 3:31pm
There's something ugly like this.

1
2
3
4
5
6
7
8
9
10
11
    bool looped = false;
    for (int i = 0; i < 10; i+=2)
    {
        std::cout << i << '\n';
        
        if (!looped && (  i==limit - 2 || i == limit-1))
        {
            i = -1;
            looped = true;
        }
    }
Last edited on Aug 3, 2018 at 4:24pm
Aug 3, 2018 at 4:33pm
@Repeater

What is limit? It is undefined here.
Aug 3, 2018 at 5:14pm
you can load up a container with the values you want to loop over and do a range-based for loop. This is extra useful when there is no simple pattern to the values, eg 2 digit pairs of pi (31 41 59 ...)

or you can use a pattern if one exists to control a loop variable.

if you need to deal with pairs you can do that too, there is a pair container for that.

can you describe exactly what you want to DO here? We can make that output print a dozen ways, but if you need to do something with values in some way, we need a better understanding.
Last edited on Aug 3, 2018 at 5:16pm
Aug 3, 2018 at 5:59pm
What is limit? It is undefined here.

See if you can guess, based on the context at hand.
Aug 3, 2018 at 7:58pm
Repeater, yeah but then why hardcode the 10 then?

Anyway, here's my attempt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Example program
#include <iostream>

int unit_step(int n)
{
    return (n >= 0) ? 1 : 0;   
}

void print_sequence(int start, int end, int N)
{
    constexpr static auto u = unit_step;
    
    int offset = (N-1)/2 + 1;
    for (int n = start; n < end; n++)
    {
        std::cout << 2 * n * u(n) - (N-1) * u(n - offset) << "\t";
    }
    std::cout << "\n";
}

int main()
{    
    int N = 10;
    int cutoff = N;
    
    N = N + N % 2;

    print_sequence(0,   N/2,    N);
    print_sequence(N/2, cutoff, N);
}


Example output, N = 10
0	2	4	6	8	
1	3	5	7	9	


Example output, N = 11
0	2	4	6	8	10	
1	3	5	7	9	 
Last edited on Aug 3, 2018 at 8:12pm
Aug 3, 2018 at 8:36pm
Repeater, yeah but then why hardcode the 10 then?


Who knows. I expect I just threw down some code as an example. If you'd like to change it, please go ahead.
Aug 3, 2018 at 9:32pm
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
   const int limit = 10;
   stringstream ss[2];
   for( int i = 0, line = 0; i < limit; i++, line = 1 - line ) ss[line] << setw( 3 ) << i;
   cout << ss[0].str() << '\n' << ss[1].str() << '\n';
}
Aug 3, 2018 at 9:46pm
Ooh, alternating the line printed between 0 and 1, very succinct.
Aug 3, 2018 at 9:57pm
@lastchance, You can get rid of line and just use ss[i % 2]
Aug 3, 2018 at 10:04pm
In this instance, yes. But i might not always be running between 0 and 9.
Aug 3, 2018 at 10:37pm
Whatever.
Aug 5, 2018 at 2:03pm
I think the answers show that the cleanest solution is two loops.
1
2
3
4
for (size_t i=0; i<10; i+=2)  cout << i << ' ';
cout << '\n';
for (size_t i=1; i<10; i+=2)  cout << i << ' ';
cout << '\n';


If you're really pressed for space, you could put it in a function:
1
2
3
4
5
6
7
8
9
10
11
void printEveryOther(unsigned from, unsigned 10)
{
    for (size_t i=from; i<to; i+=2)  cout << i << ' ';
    cout << '\n';
}

int main()
{
    printEveryOther(0, 10);
    printEveryOther(1, 10);
}

Aug 6, 2018 at 1:04pm
Why not this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

using namespace std;


int main() {

	int a = 12;

	for (int i = 0; i <= a; i += 2) {
		cout << i << "\t";
	}

	cout << endl;

	for (int i = 1; i <= a; i += 2) {
		cout << i << "\t";
	}
	

	
	cin.get();
	
	return 0;
}
Aug 6, 2018 at 1:37pm
That's way too deconvoluted! :)
Last edited on Aug 6, 2018 at 1:37pm
Aug 6, 2018 at 2:19pm
it's definitely unusual to iterate over every other index but still care about the indices skipped.

Thus, as lastchance wrote, some form of storage is required. You could output the evens as you go (since this is the first line), storing just the odds, but take care on choosing your starting and ending points. A few ways to do that; for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <sstream>

using namespace std;

int main() 
{
    const int limit = 10;
    ostringstream oss;
    cout << "0 ";
    for (int i=2; i<=limit; i+=2)
    {
        cout << i << ' ';
        oss << (i-1) << ' ';
    }
    cout << '\n' << oss.str() << '\n';

    return 0;
}

0 2 4 6 8 10 
1 3 5 7 9 
Last edited on Aug 6, 2018 at 2:19pm
Aug 6, 2018 at 2:26pm
Hey, I could obfuscate with the best of em'. Don't push me. :P
Aug 6, 2018 at 2:38pm
Besides, here is the same in a single loop.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

using namespace std;


int main() {

	int a = 12;

	for (int i = 0; i <= a; i += 2) {
		cout << i << "\t";
		if (i + 2 > a && i % 2 == 0) {
			i = -1;
			cout << endl;
		}
	}


	
	cin.get();
	
	return 0;
}
Aug 6, 2018 at 3:42pm
manga wrote:
Hey, I could obfuscate with the best of em'. Don't push me. :P

I'm working on it ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>
using namespace std;

void output( int imin, int imax, int di, int nlines, int i, int line )
{
   if ( i > imax ) { line++;   cout << '\n';   i = imin + line * di; }
   if ( line == nlines ) return;
   cout << setw( 4 ) << i;
   output( imin, imax, di, nlines, i + nlines * di, line );
}


int main()
{
   output( 0, 11, 1, 2, 0, 0 );
}
   0   2   4   6   8  10
   1   3   5   7   9  11
Aug 6, 2018 at 4:22pm
@lastchance

I smell a bit of recursion in that one... nice. :)

Just remember to use function calls in your argument list.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <iomanip>
using namespace std;

void output(int imin, int imax, int di, int nlines, int i, int line)
{
	if (i > imax) { line++;   cout << '\n';   i = imin + line * di; }
	if (line == nlines) return;
	cout << setw(4) << i;
	output(imin, imax, di, nlines, i + nlines * di, line);
}

int fluxCap(int x) {
	x > 0 ? x = x - x: x = 0;
	return x;
}


int main()
{
	output(fluxCap(3), abs(-10 - 1), sizeof(true), sizeof(short), fluxCap(-1), fluxCap(18));
}
Last edited on Aug 6, 2018 at 5:29pm
Topic archived. No new replies allowed.