Reputation: 355
I'm trying to write a program to find a specific 4 digit number with the following conditions:
I'm struggling to write this program. I tried nested for loops iterating each digit until the conditions are met (when a break terminates the loops), as below:
int a = 1;
int b = 1;
int c = 1;
int d = 1;
for (a = 1; a < 9; a++) {
for (b = 1; b < 9; b++) {
for (c = 1; c < 9; c++) {
for (d = 1; d < 9; d++) {
if (a + b + c + d == 27 && a == 3 * c && a != b && a != c
&& a != d && b!= c && b != d && c != d && d % 2 != 0) {
break;
}
}
}
}
}
I expected the digits a, b, c, d to provide me with the number to fulfil all conditions in the if statement above and thus to break. Instead, abcd is always 9999. Why is this happening? How am I misusing break?
Upvotes: 1
Views: 623
Reputation: 735
The break
in your code only breaks the for
loop that it's in. One solution would be to place the calculation into a function, exit the function when the conditions are met with return
, and return the value that you build from each digit. Also, you must test digits 0 through 9, but in your code, you only test values 1 through 8. So, the solution is as follows:
#include <iostream>
using namespace std;
int find_number(){
int a, b, c, d, result;
for (a = 0; a <= 9; a++) {
for (b = 0; b <= 9; b++) {
for (c = 0; c <= 9; c++) {
for (d = 0; d <= 9; d++) {
if (a + b + c + d == 27 && a == 3 * c && a != b && a != c &&
a != d && b != c && b != d && c != d && d % 2 != 0) {
result = a*1000 + b*100 + c*10 + d;
return result;
} // end if
} // end for
} // end for
} // end for
} // end for
return 0;
} // end find_number()
int main()
{
cout << find_number() << endl;
return 0;
} // end main()
My Suggested Improvements
Below is a solution assuming you know a few things about numbers and you want to optimize for efficiency (minimize the number of times the for
loops are executed).
a
, only 3, 6, and 9 must be tested (1*3=3
, 2*3=6
, 3*3=9
).c
can be derived from a
, so you can eliminate the for loop testing c
values.d
loop.b
and d
loop so that code in outer loop runs less times.a
will never equal c
, so no need to check.a
and c
don't equal d
right inside d
loop.b
doesn't equal other digits before adding digits and checking they equal 27.if
statement conditions into different lines so that it's easier to read. This also enables a debugger to be able to step through the conditions line-by-line, and compilers will identify potential errors on which line/condition produced the error.#include <iostream>
using namespace std;
int find_number(){
int a, b, c, d, result;
for(a = 3; a <= 9; a += 3){ // Only runs 3 times
c = a/3;
for(d = 1; d <= 9; d += 2){ // Skip even numbers
if(d != a
&& d != c){
for(b = 0; b <= 9; b++){
if(b != a
&& b != c
&& b != d
&& a + b + c + d == 27){
result = a*1000 + b*100 + c*10 + d;
return result;
} // end if
} // end for
} // end if
} // end for
} // end for
} // end find_number()
int main()
{
cout << find_number() << endl;
return 0;
} // end main()
Upvotes: 0
Reputation: 31
break
only breaks the inner loop. If you want to come out of all the loops, either use return
, or a variable, like flag
.
int a = 1;
int b = 1;
int c = 1;
int d = 1;
int flag = 0;
for (a = 1; a < 9; a++) {
for (b = 1; b < 9; b++) {
for (c = 1; c < 9; c++) {
for (d = 1; d < 9; d++) {
if (a + b + c + d == 27 && a == 3 * c && a != b && a != c
&& a != d && b!= c && b != d && c != d && d % 2 != 0) {
flag = 1;
break; // breaks d loop
}
}
if(flag == 1)
break; // breaks c loop
}
if(flag == 1)
break; // breaks b loop
}
if(flag == 1)
break; // breaks a loop
}
This is a bad practice, but will give correct output. I would prefer using a return
statement, or you can use a goto
statement to jump out of the loop.
Upvotes: 1
Reputation: 1320
#include<stdio.h>
int findNum();
int main()
{
int num;
num = findNum();
printf("%d is the required number.\n\n",num);
return 0;
}
int findNum()
{
int a, b, c, d;
for (a = 1; a <= 9; a++)
{
for (b = 0; b <= 9; b++)
{
for (c = 0; c <= 9; c++)
{
for (d = 0; d <= 9; d++)
{
if (a+b+c+d==27 && a==(3*c) && a!=b && a!=c && a!=d && b!=c && b!=d && c!=d && (d%2)!=0)
{
return (1000*a)+(100*b)+(10*c)+d;
}
}
}
}
}
}
Upvotes: 2
Reputation: 4099
break
will only break out of the inner most loop. So when you hit your condition, you just go into the next iteration of the c
value.
Upvotes: 4