Permutation of withdrawing 2 balls out of 5

I hope if there is someone have the time to read and help me to solve this problem. I stopped doing programming for a very long time. I am a freelance C++ programmer. I am actually Auto Technician and Accountant.

If I have 5 balls. I want to see all the possibilities of having to withdraw 2 balls.
Which is:

12
13
14
15
23
24
25
34
35
45

I made this program:

#include <iostream>
using namespace std;

int main ()
{
int n = 0;

int m = 1;

for (int i = 0; i < 5; i++ )
{
for (int e = 0; e < 5; e++ )
{
cout << m << "." << ++n << "\n";
}
n = 0;
m = m + 1;
cout << endl;
}
}
Which gave me:
(1.2)
1.2
1.3
1.4
1.5

(2.1)
(2.2)
2.3
2.4
2.5

(3.1)
(3.2)
(3.3)
3.4
3.5

(4.1)
(4.2)
(4.3)
(4.4)
4.5

(5.1)
(5.2)

But I do not need the one between Brackets, because it will be repetition.
So now I need a program that would have no repeated numbers. I modified the program to read:

#include <iostream>
using namespace std;
int main ()
{
int n = 0;
int m = 1;
for (int i = 0; i < 5; i++ )
{
for (int e = 0; e < 5; e++ )
{
if (n == m || n > m)
continue;
cout << m << "." << ++n << "\n";
}
n = 0;
m = m + 1;
cout << endl;
}
}
But it gave the oppsit of what I want. It gave me:

(1.1)

2.1
(2.2)

3.1
3.2
(3.3)

4.1
4.2
4.3
(4.4)

5.1
5.2
5.3
5.4
(5.5)

Although I wanted them to be the smaller number at the beginning, but the program really did what I want except the following repeated numbers (between Brackets) 1.1, 2.2 3.3, 4.4, 5.5.


To help you ease back into C++ programming you might want to spend some time lurking around the free lessons at Learn C++.

https://www.learncpp.com/
A good way to approach a problem is simplifying:
1
2
3
4
5
6
7
8
9
10
11
12
int main ()
{
for (int i = 0; i < 5; i++ )
{
for (int e = i + 1; e < 5; e++ )
{
cout << i + 1 << "." << e + 1 << "\n";
}

cout << endl;
}
}
I.e. you don't need n or m.
1
2
3
4
5
6
7
#include <iostream>
int main()
{
   const int N = 5;
   for ( int first = 1; first < N; first++ )      // yes, " first < N ", but "second <= N"
      for ( int second = first + 1; second <= N; second++ ) std::cout << first << ", " << second << '\n';
}
Last edited on
[This question is almost the same as this one https://cplusplus.com/forum/beginner/285315/ ]

Last edited on
One loop!

1
2
3
4
5
6
7
#include <iostream>
int main()
{
   const int N = 5;
   for ( int i = 1, j = 2; i < N; i += ( j == N ), j = ( j == N ? i : j ) + 1 )
      std::cout << i << ", " << j << '\n';
}


or

1
2
3
4
5
6
7
#include <iostream>
int main()
{
   const int N = 5;
   for ( int c = 1, i = 1; i < N; i += ( c == i * ( 2 * N - i - 1 ) / 2 ), c++ )
      std::cout << i << ", " << c - N * ( i - 1 ) + i * ( i + 1 ) / 2 << '\n';
}


1, 2
1, 3
1, 4
1, 5
2, 3
2, 4
2, 5
3, 4
3, 5
4, 5

Last edited on
Nice! :) :)
Or you could let recursion hide the loops:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

void out( int i, int j, int N )
{
   if ( i >= N ) return;
   std::cout << i << ", " << j << '\n';
   j == N ? out( i + 1, i + 2, N ) : out( i, j + 1, N ); 
}

int main()
{
   out( 1, 2, 5 );
}
1, 2
1, 3
1, 4
1, 5
2, 3
2, 4
2, 5
3, 4
3, 5
4, 5
Last edited on
I like the recursive function form better than that "one loop and in the darkness bind them."

Just me, but that one loop version is hard to read and understand. YMMV.

And as seeplus pointed out this is a rehash of a previous topic that is virtually identical to this one. The previous topic had some most excellent suggestions for dealing with dual loops.
Well, the "previous" topic rather obscured the actual target - the permutations of two numbered balls. The danger of an XY-problem emerging is obvious.

If done as a real-world problem then write the most readable code: probably two nested loops. Less chance of bugs. Runs at least as fast.

If done as a divert-attention-from-real-work(!)-and-enjoy-playing-with-c++-type problem then challenge yourself to remove first one and then both loops.

Sure, one of the single-loop approaches is a bit obscure - but it does actually contain the permutation counter (c). It certainly does no harm to practise combinatorics.

Actually, both single-loop solutions contain two variables. It is just about possible to go down to the single counter (c) alone: but then the solution really does look obscure.
Heh, it isn't as if someone looking for help in the past hasn't generated multiple topics before, each one revealing a mere fractional snippet of new information, yet is still part of the same exercise.

I'm a self-taught programming hobbyist, my brain just isn't wired to read and write uber-compact code.

Not that there is anything inherently wrong with that approach, it just isn't "me" without a lot of unnecessarily (IMO) expended skull sweat. YMMV.

For me writing easy-to-read-and-understand code is easy-to-maintain code. I'm a hack, not an artiste. My code croaks like a toad, it does the job, but it never soars on swift wings and sings like a nightingale.

There have been times I've looked at older code I wrote after putting it aside for some time and even with my "easy-to-read" practices I was briefly stumped as to just what the hell I was doing and thinking when I wrote it originally.
Topic archived. No new replies allowed.