Related
"The question comes under a broad category of "Array Transformation". This category is the meat of tech interviews. Mostly because arrays are such a simple and easy to use data structure. Traversal or representation doesn't require any boilerplate code and most of your code will look like the Pseudocode itself.
The 2 requirements of the question are:
Move all the 0's to the end of array.
All the non-zero elements must retain their original order."
My thinking:
to find the zeros and exchange their positions with the last numbers
/* int swap;
int n=nums.size()-1;
for(int i=0;i<nums.size();i--){
if(nums[i]==0){
swap = nums[i];
nums[i] = nums[n];
nums[n] = swap;
n--;
}
}
My input
[0,1,0,3,12]
Output
[1,3,12,0,0]
Diff
Expected
[1,3,12,0,0]
And I did not know why the correct answer(the part) is :
(int n = 0, cur = 0; cur < nums.size(); cur++) {
if (nums[cur] != 0) {
swap(nums[n++], nums[cur]);
}
}
}
Can you use the standard library? std::stable_partition() makes it trivial. Something like
std::stable_partition(nums.begin(), nums.end(),
[](const auto &n){ return n != 0; });
For the question of how the solution in your post works:
At the start of the first iteration, n is 0, cur is 0, and nums is [0,1,0,3,12]. nums[cur] is 0, so nothing happens. At the start of the second iteration, cur is 1, and nums[cur] is 1, so the swap and increment of n happens.
Now n is 1, cur is 2, and nums is [1,0,0,3,12]. nums[cur] is 0, so nothing happens in the third iteration. In the fourth iteration, with cur now 3, a swap happens. So at the start of the the fifth iteration, n is 2, cur is 4, and nums is [1,3,0,0,12]. I'll leave it to you to work out what happens in that step.
Basically, when n is not equal to cur, it's the index of a 0 element that can be swapped with a non-0 element that cur is the index of. This swapping eventually moves all 0's to the end.
My take on the problem, minimal std library usage. Probably not the most efficient, but it does the trick.
#include "stdafx.h"
#include <iostream>
int main()
{
int src[] = { 0, 1, 0, 3, 0, 12 }; // Output: 1 3 12 0 0 0 check
// = { 0, 3, 0, 1, 0, 0, 12, 0, 5 }; // Output: 3 1 12 5 0 0 0 0 0 check
int n = sizeof(src) / sizeof(src[0]);
for (int x = 0; x < n; x++) {
for (int y = x + 1; y < n; y++) {
if (src[x] == 0 && src[y] != 0) {
int swap = src[x];
src[x] = src[y];
src[y] = swap;
}
}
}
for (int i = 0; i < n; i++) {
std::cout << src[i] << " ";
}
return 0;
}
I am trying to work on homework. I have tried to run this code multiple different ways. Here is the sitrep from the assignment -
Design an algorithm (using pseudocode) that takes in as an input, two 2-D int arrays that are assumed to be 2 black-and-white images: initialImage x, whose dimensions are IxJ, and finalImage y, whose dimensions are IxK. The algorithm will compare x to the y, row-by-row, as defined below. Your algorithm will employ a dynamic programming scheme to compare X to Y identifying the minimal difference between each row.
Because you are working with black-and-white images only, you should assume that each image is a 2-D int array consisting of 2 possible values: 0 or 1, where 0 represents black and 1 represents white. Thus, this 2-D grid of 0 and 1 values comprise a 2-D black-and-white image. Each row of this image is then simply a 1-D int array filled with either 0s or 1s. Therefore, you must define how you will measure the difference between the strings of 0s and 1s in each row.
Remember that you will do the comparison one row in the images at a time.
First, compare X1,* to Y1,. (Here X1, is the first row in image X and Y1,* is the first row in image Y ). Next, compare X2 to Y2... Each one of these comparisons will require the construction of a D (distance) matrix.
In the following example, the first row of X is X1,, and the first row of Y is Y1, = 00110.
*Sorry picture wont load but it is two tables. The first is
X 1 2 3 4 5 Y 1 2 3 4 5
1 0 0 1 1 0 1 0 0 1 1 0
2 1 1 0 0 1 2 0 1 0 0 1
3 0 0 1 1 1 3 1 0 1 1 1
After the D matrix is completed, the minimum number in the bottom row is the minimal mismatch for this row. You will assign this value to the variable minVali. This number tells how different row X1,* is from row Y1,* . You will then repeat this comparison for all rows i and aggregate the difference when complete into variable totalDifference = Si minVali.
As a result, the algorithm will compare the total difference to a threshold value called thresh. If total value is above the threshold, the images are declared different; otherwise, they are declared to be similar images. You can assume that the thresh variable is supplied as an input to your algorithm.
// C++ implementation to find the uncommon
// characters of the two strings
#include <bits/stdc++.h>
using namespace std;
// size of the hash table
const int MAX_CHAR = 30;
// function to find the uncommon characters
// of the 6 strings
void findAndPrintUncommonChars(string str1, string str2, string str3, string str4, string str5, string str6)
{
// mark presence of each character as 0
// in the hash table 'present[]'
int present[MAX_CHAR];
for (int i=0; i<MAX_CHAR; i++)
present[i] = 0;
int l1 = str1.size();
int l2 = str2.size();
int l3 = str3.size();
int l4 = str4.size();
int l5 = str5.size();
int l6 = str6.size();
// for each character of str, mark its
// presence as 1 in 'present[]'
for (int i=0; i<l1; i++)
present[str1[i] - 'a'] = 1;
for (int i=0; i<l1; i++)
present[str2[i] - 'a'] = 1;
for (int i=0; i<l1; i++)
present[str3[i] - 'a'] = 1;
// for each character of str
for (int i=0; i<l4; i++)
for (int i=0; i<l5; i++)
for (int i=0; i<l6; i++)
{
// if a character of str2 is also present
// in str1, then mark its presence as -1
if (present[str4[i] - 'a'] == 1
|| present[str4[i] - 'a'] == -1)
present[str4[i] - 'a'] = -1;
else
present[str4[i] - 'a'] = 2;
if (present[str5[i] - 'a'] == 1
|| present[str5[i] - 'a'] == -1)
present[str5[i] - 'a'] = -1;
else
present[str5[i] - 'a'] = 2;
if (present[str6[i] - 'a'] == 1
|| present[str6[i] - 'a'] == -1)
present[str6[i] - 'a'] = -1;
else
present[str6[i] - 'a'] = 2;
}
// print all the uncommon characters
for (int i=0; i<MAX_CHAR; i++)
if (present[i] == 1 || present[i] == 2 )
cout << (char(i + 'a')) << " ";
}
// Driver program to test above
int main()
{
string str1 = {0, 0, 1, 0, 0};
string str2 = {1, 1, 0, 0, 1};
string str3 = {0, 0, 1, 1, 1};
string str4 = {0, 0, 1, 1, 0};
string str5 = {0, 1, 0, 0, 1};
string str6 = {1, 0, 1, 1, 1};
findAndPrintUncommonChars(str1, str4)
findAndPrintUncommonChars(str2, str5)
findAndPrintUncommonChars(str3, str6)
return 1;
}
I'm trying to figure out how I can use recursion to do n-level nested for loops.
For example, if n=3, there would be 3 'levels'
for(z=0;z<6;z++){
for(y=0;y<6;y++){
for(x=0;x<6;x++){
if (z+y+x==f){
//do something
}
}
}
}
and so on.
I can't seem to figure out how I would be able to place the if loop in the last for loop and how I can access the variables of previous for loops from the if statement. I know that the question of variable nested loops has been asked alot of times, and I have looked through all of them. But none seem to help me.
Could someone present an easy way of using recursion to achieve this, keeping in mind that I'm still a beginner in c++, to point me in the right direction?
The use case is as follows:
Write a program to input the number of dice m. The program will output the total number of possible cases, the number of possible cases for each possible n and the n with the highest probability. Note: only one input m is read in. n is computed by the program
Example if user enters m=2 then program should output
The total number of possible cases is 36.
The possibilities are
2 1
3 2
4 3
.
.
.
12 1
For efficiency, I've avoided recursion. Also, it doesn't use any specific c++ stuff - it will work fine on C as well.
We're trying to create N nested "for" loops.
Instead of using
for(int i = 0; i<max; i++)
for (int j = 0; j<max; j++)
...
I'll be replacing i, j, ... with an array: i[0], i[1], ..., i[n-1].
Here's my solution:
const int n = /*Insert N here: how many loops do you need?*/;
int i[n+1]; // if "n" is not known before hand, then this array will need to be created dynamically.
//Note: there is an extra element at the end of the array, in order to keep track of whether to exit the array.
for (int a=0; a<n+1; a++) {
i[a]=0;
}
int MAX = 79; //That's just an example, if all of the loops are identical: e.g. "for(int i=0; i<79; i++)". If the value of MAX changes for each loop, then make MAX an array instead: (new) int MAX [n]; MAX[0]=10; MAX[1]=20;...;MAX[n-1]=whatever.
int p = 0; //Used to increment all of the indicies correctly, at the end of each loop.
while (i[n]==0) {//Remember, you're only using indicies i[0], ..., i[n-1]. The (n+1)th index, i[n], is just to check whether to the nested loop stuff has finished.
//DO STUFF HERE. Pretend you're inside your nested for loops. The more usual i,j,k,... have been replaced here with i[0], i[1], ..., i[n-1].
//Now, after you've done your stuff, we need to increment all of the indicies correctly.
i[0]++;
// p = 0;//Commented out, because it's replaced by a more efficient alternative below.
while(i[p]==MAX) {//(or "MAX[p]" if each "for" loop is different. Note that from an English point of view, this is more like "if(i[p]==MAX". (Initially i[0]) If this is true, then i[p] is reset to 0, and i[p+1] is incremented.
i[p]=0;
i[++p]++; //increase p by 1, and increase the next (p+1)th index
if(i[p]!=MAX)
p=0;//Alternatively, "p=0" can be inserted above (currently commented-out). This one's more efficient though, since it only resets p when it actually needs to be reset!
}
}
There, that's all. Hopefully the comments make it clear what it's meant to be doing. I think it should be pretty efficient - almost as much as real nested for-loops. Most of the overhead is a one-off at the beginning, so this should be more efficient that using recursive functions etc
The basic structure of a recursive algorithm with multiple loops is as follows:
void recursiveLoops(vector<int>& indexes, const vector<int>& endPerIndex, int currentIndex) {
if (currentIndex == indexes.size()) {
// This is where the real logic goes.
// indexes[i] contain the value of the i-th index.
} else {
for (indexes[pos] = 0 ; indexes[pos] != endPerIndex[pos] ; indexes[pos]++) {
// Recurse for the next level
recursiveLoops(indexes, endPerIndex, pos+1);
}
}
}
The setup for calling recursiveLoops from the top level requires two vectors - one for the indexes, and one for the number of iterations at each level. The example below sets up three nested loops, iterating 5, 6, and 9 times at each level:
vector<int> indexes(3, 0);
vector<int> endPerIndex;
endPerIndex.push_back(5);
endPerIndex.push_back(6);
endPerIndex.push_back(9);
recursiveLoops(indexes, endPerIndex, 0);
Here's an example in plain old C++. First I make a vector of the ranges for each dimension called maxes. if the sum of all indices are 2 then I print did something.
In the example I loop z from 0 to 1, y from 0 to 2, x from 0 to 3
You can for sure make this more neat.
Here goes:
#include <iostream>
#include <vector>
using namespace std;
int f(){
return 2 ;
}
void inner(int depth,vector<int> & numbers,vector<int> & maxes){
if (depth>0){
for(int i=0;i<maxes[depth-1];i++){
numbers[depth-1]=i;
inner(depth-1, numbers,maxes) ;
}
}else{
// calculate sum of x,y,z:
cout << "values are ";
for(int i=0;i<numbers.size();i++){
cout <<numbers[i]<<" ";
}
int thesum(0);
for(int i=0;i<numbers.size();i++){
thesum+=numbers[i];
}
if (thesum==f()){
cout << "did something! ";
}
cout<<endl;
}
}
void donest(){
vector<int> numbers;
numbers.resize(3);
vector<int> maxes;
maxes.push_back(4);
maxes.push_back(3);
maxes.push_back(2);
inner(numbers.size(),numbers,maxes);
}
int main(){
donest();
}
result:
values are 0 0 0
values are 1 0 0
values are 2 0 0 did something!
values are 3 0 0
values are 0 1 0
values are 1 1 0 did something!
values are 2 1 0
values are 3 1 0
values are 0 2 0 did something!
values are 1 2 0
values are 2 2 0
values are 3 2 0
values are 0 0 1
values are 1 0 1 did something!
values are 2 0 1
values are 3 0 1
values are 0 1 1 did something!
values are 1 1 1
values are 2 1 1
values are 3 1 1
values are 0 2 1
values are 1 2 1
values are 2 2 1
values are 3 2 1
just count the depth for each recursion function, and count to f..
void myRecursiveFunc(int depth){
if(depth == f)
//do something
return;
else{
myRecursiveFunc(depth + 1);
}
}
if you really want you can use three different functions for x,y and z.
You are very vague about why you want this. For a starter a possible solution is to replace each for loop with a recursive function.
void recursiveX(int zVal, int yVal, int xVal)
{
if(zVal+yVal+xVal == f)...
if(xVal != 0)
recursiveX(zVal, yVal, xVal -1);
}
void recursiveY(int zVal, int yVal)
{
recursiveX(zVal, yVal, 6);
if(yVal != 0)
recursiveY(zVal, yVal-1);
}
void recursiveZ(int val)
{
recursiveY(val, 6);
if(val != 0)
recursiveZ(val-1);
}
...
recursiveZ(6);
And in the end you can merge this all into one function. Nevertheless using recursion just because it is possible is never a good Idea.
You could write it like this, but... I wouldn't. It's confusing code and doesn't give you any benefits. If you want it because your true use case has a high number of nested loops, consider just not doing that, instead; it's a serious design smell.
void nested_loop(const int levels, const int comparator, const int level = 0, const int accumulator = 0)
{
if (level < levels) {
for (int i = 0; i < 6; i++) {
nested_loop(levels, comparator, level + 1, accumulator + i);
}
}
else {
if (accumulator == comparator) { // your if (z+y+x==f)
//do something
}
}
}
int main() {
const int levels = 3;
const int f = 42;
nested_loop(levels, f);
}
Live demo.
Variable loop using while loop in "C".
Concept
Creating a 2-dimensional array (arr[level][2]) in which first element is starting, and second element is end.
x[3][2] = {{0, 10}, {5, 20}, {2, 60}};
Creating another array with starting elements.
y[3] = {0, 5, 2};
We created a second array, because during the loop we will change the first element of "x" array.
Code
#include <stdio.h>
int main(){
// bruteforce
int level = 10;
int start[10] = {0, 0, 0, 0};
int x[10][2] = {{0, 5}, {0, 5}, {0, 5}, {0, 5}};
for (int i = 1;i < level; ++i){
x[i][1] = x[i][1] + 1;
}
while(3>2){
// Your code here
//
printf("%d %d %d %d\n", x[0][0], x[1][0], x[2][0], x[3][0]);
// variable loop code
// ==== Not To Modify ====
int a = 0;
int b = 0;
for(int i = 0;i < level; ++i){
if (x[i][0] >= x[i][1])
{
if(i != level-1){
x[i][0] = start[i];
x[i+1][0] = x[i+1][0] + 1;
}else{
a = 1;
}
b = 1;
}else{
if(b == 0){
x[0][0] = x[0][0] + 1;
b = 1;
}
}
}
if(a == 1){
break;
}
}
return 0;
}
This is a late answer, but maybe it will help someone.
Here is my solution in c++ without recursive function.:
int n_loops{3}; //number of nested for loops
int loops_idx[n_loops]; //like i,j,k but in an array
for (int i = 0; i < n_loops; i++)
loops_idx[i]=0;
int max_idx[n_loops]{3,2,4}; // like in for(; i < counter ;), but the counters in an array
bool is_finished = false;
int debug_n_of_execution{0};
while (!is_finished)
{
for (; loops_idx[0]<max_idx[0]; loops_idx[0]++)
{
/*
some code with loops_idx array as i,j,k...
*/
++debug_n_of_execution;
for (int i = 0; i < n_loops; i++)
std::cout<<loops_idx[i]<<" ";
std::cout << "\n";
}
--loops_idx[0]; //to cancel last increment
//Here it will increment the last loop_idx which isn't equal to max_idx[i]-1
//eg. after first above for loop loops_idx will be (max-1, 0, 0)
//So it will be after this loop (0, 1, 0) and start from the beginning...
for (int i = 0; i < n_loops+1; i++) //+1 to know if all loops are finished
{
if (i == n_loops)
{is_finished= true; break;}
if(loops_idx[i]==max_idx[i]-1)
continue;
++loops_idx[i];
for (int j = 0; j < i; j++) //make any previous loop = 0
loops_idx[j]=0;
break;
}
}
//just to check
int debug_perfect_n_of_execution{max_idx[0]};
for (int i = 1; i < n_loops; i++)
debug_perfect_n_of_execution*= max_idx[i];
std::cout<<"Number of execution: "<<debug_n_of_execution<<" = "<<debug_perfect_n_of_execution;
assert(debug_n_of_execution==debug_perfect_n_of_execution);
std::cout << "\nTests Finished";
And here is the result:
0 0 0
1 0 0
2 0 0
0 1 0
1 1 0
2 1 0
0 0 1
1 0 1
2 0 1
0 1 1
1 1 1
2 1 1
0 0 2
1 0 2
2 0 2
0 1 2
1 1 2
2 1 2
0 0 3
1 0 3
2 0 3
0 1 3
1 1 3
2 1 3
Number of execution: 24 = 24
Tests Finished
I want to ask your help, I want to display a two dimensional array in c++, whose every second two rows are changing periodically between 0 and 1.
For example n = 5, m = 4 the program will write this:
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
0 0 0 0
I'm still a beginner in C++. I tried it myself to see if I could do it.
The only thing you need to know is, when to assign 1 to your row and when to assign 0.
These are the the rows where you have to give every number the value 0:
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
again:
0,1,4,5,8,9,12,13,16,17
If you look at them like this, they don't make much sense. But if you divide them into two lists like this:
0,4,8,12,16
and
1,5,9,13,17
you can see that the first list consist of numbers, that are the result of n * 4, and the second list is the result of n * 4 + 1
So you just have to make an if-statement where the requirement is
(i%4 == 0 || i%4 == 1)
Here is my complete code. It's probably not the best solution:
#include <iostream>
using namespace std;
int main()
{
const int n = 20, m = 4;
int array[n][m];
int i = 0, j = 0;
while ( i < n)
{
if (j < 4)
{
if (i%4 == 0 || i%4 == 1)
array[i][j] = 0;
else
array[i][j] = 1;
cout << array[i][j] << ", ";
j++;
}
else {
j = 0;
i++;
cout << endl;
}
}
}
I'm trying to figure out how I can use recursion to do n-level nested for loops.
For example, if n=3, there would be 3 'levels'
for(z=0;z<6;z++){
for(y=0;y<6;y++){
for(x=0;x<6;x++){
if (z+y+x==f){
//do something
}
}
}
}
and so on.
I can't seem to figure out how I would be able to place the if loop in the last for loop and how I can access the variables of previous for loops from the if statement. I know that the question of variable nested loops has been asked alot of times, and I have looked through all of them. But none seem to help me.
Could someone present an easy way of using recursion to achieve this, keeping in mind that I'm still a beginner in c++, to point me in the right direction?
The use case is as follows:
Write a program to input the number of dice m. The program will output the total number of possible cases, the number of possible cases for each possible n and the n with the highest probability. Note: only one input m is read in. n is computed by the program
Example if user enters m=2 then program should output
The total number of possible cases is 36.
The possibilities are
2 1
3 2
4 3
.
.
.
12 1
For efficiency, I've avoided recursion. Also, it doesn't use any specific c++ stuff - it will work fine on C as well.
We're trying to create N nested "for" loops.
Instead of using
for(int i = 0; i<max; i++)
for (int j = 0; j<max; j++)
...
I'll be replacing i, j, ... with an array: i[0], i[1], ..., i[n-1].
Here's my solution:
const int n = /*Insert N here: how many loops do you need?*/;
int i[n+1]; // if "n" is not known before hand, then this array will need to be created dynamically.
//Note: there is an extra element at the end of the array, in order to keep track of whether to exit the array.
for (int a=0; a<n+1; a++) {
i[a]=0;
}
int MAX = 79; //That's just an example, if all of the loops are identical: e.g. "for(int i=0; i<79; i++)". If the value of MAX changes for each loop, then make MAX an array instead: (new) int MAX [n]; MAX[0]=10; MAX[1]=20;...;MAX[n-1]=whatever.
int p = 0; //Used to increment all of the indicies correctly, at the end of each loop.
while (i[n]==0) {//Remember, you're only using indicies i[0], ..., i[n-1]. The (n+1)th index, i[n], is just to check whether to the nested loop stuff has finished.
//DO STUFF HERE. Pretend you're inside your nested for loops. The more usual i,j,k,... have been replaced here with i[0], i[1], ..., i[n-1].
//Now, after you've done your stuff, we need to increment all of the indicies correctly.
i[0]++;
// p = 0;//Commented out, because it's replaced by a more efficient alternative below.
while(i[p]==MAX) {//(or "MAX[p]" if each "for" loop is different. Note that from an English point of view, this is more like "if(i[p]==MAX". (Initially i[0]) If this is true, then i[p] is reset to 0, and i[p+1] is incremented.
i[p]=0;
i[++p]++; //increase p by 1, and increase the next (p+1)th index
if(i[p]!=MAX)
p=0;//Alternatively, "p=0" can be inserted above (currently commented-out). This one's more efficient though, since it only resets p when it actually needs to be reset!
}
}
There, that's all. Hopefully the comments make it clear what it's meant to be doing. I think it should be pretty efficient - almost as much as real nested for-loops. Most of the overhead is a one-off at the beginning, so this should be more efficient that using recursive functions etc
The basic structure of a recursive algorithm with multiple loops is as follows:
void recursiveLoops(vector<int>& indexes, const vector<int>& endPerIndex, int currentIndex) {
if (currentIndex == indexes.size()) {
// This is where the real logic goes.
// indexes[i] contain the value of the i-th index.
} else {
for (indexes[pos] = 0 ; indexes[pos] != endPerIndex[pos] ; indexes[pos]++) {
// Recurse for the next level
recursiveLoops(indexes, endPerIndex, pos+1);
}
}
}
The setup for calling recursiveLoops from the top level requires two vectors - one for the indexes, and one for the number of iterations at each level. The example below sets up three nested loops, iterating 5, 6, and 9 times at each level:
vector<int> indexes(3, 0);
vector<int> endPerIndex;
endPerIndex.push_back(5);
endPerIndex.push_back(6);
endPerIndex.push_back(9);
recursiveLoops(indexes, endPerIndex, 0);
Here's an example in plain old C++. First I make a vector of the ranges for each dimension called maxes. if the sum of all indices are 2 then I print did something.
In the example I loop z from 0 to 1, y from 0 to 2, x from 0 to 3
You can for sure make this more neat.
Here goes:
#include <iostream>
#include <vector>
using namespace std;
int f(){
return 2 ;
}
void inner(int depth,vector<int> & numbers,vector<int> & maxes){
if (depth>0){
for(int i=0;i<maxes[depth-1];i++){
numbers[depth-1]=i;
inner(depth-1, numbers,maxes) ;
}
}else{
// calculate sum of x,y,z:
cout << "values are ";
for(int i=0;i<numbers.size();i++){
cout <<numbers[i]<<" ";
}
int thesum(0);
for(int i=0;i<numbers.size();i++){
thesum+=numbers[i];
}
if (thesum==f()){
cout << "did something! ";
}
cout<<endl;
}
}
void donest(){
vector<int> numbers;
numbers.resize(3);
vector<int> maxes;
maxes.push_back(4);
maxes.push_back(3);
maxes.push_back(2);
inner(numbers.size(),numbers,maxes);
}
int main(){
donest();
}
result:
values are 0 0 0
values are 1 0 0
values are 2 0 0 did something!
values are 3 0 0
values are 0 1 0
values are 1 1 0 did something!
values are 2 1 0
values are 3 1 0
values are 0 2 0 did something!
values are 1 2 0
values are 2 2 0
values are 3 2 0
values are 0 0 1
values are 1 0 1 did something!
values are 2 0 1
values are 3 0 1
values are 0 1 1 did something!
values are 1 1 1
values are 2 1 1
values are 3 1 1
values are 0 2 1
values are 1 2 1
values are 2 2 1
values are 3 2 1
just count the depth for each recursion function, and count to f..
void myRecursiveFunc(int depth){
if(depth == f)
//do something
return;
else{
myRecursiveFunc(depth + 1);
}
}
if you really want you can use three different functions for x,y and z.
You are very vague about why you want this. For a starter a possible solution is to replace each for loop with a recursive function.
void recursiveX(int zVal, int yVal, int xVal)
{
if(zVal+yVal+xVal == f)...
if(xVal != 0)
recursiveX(zVal, yVal, xVal -1);
}
void recursiveY(int zVal, int yVal)
{
recursiveX(zVal, yVal, 6);
if(yVal != 0)
recursiveY(zVal, yVal-1);
}
void recursiveZ(int val)
{
recursiveY(val, 6);
if(val != 0)
recursiveZ(val-1);
}
...
recursiveZ(6);
And in the end you can merge this all into one function. Nevertheless using recursion just because it is possible is never a good Idea.
You could write it like this, but... I wouldn't. It's confusing code and doesn't give you any benefits. If you want it because your true use case has a high number of nested loops, consider just not doing that, instead; it's a serious design smell.
void nested_loop(const int levels, const int comparator, const int level = 0, const int accumulator = 0)
{
if (level < levels) {
for (int i = 0; i < 6; i++) {
nested_loop(levels, comparator, level + 1, accumulator + i);
}
}
else {
if (accumulator == comparator) { // your if (z+y+x==f)
//do something
}
}
}
int main() {
const int levels = 3;
const int f = 42;
nested_loop(levels, f);
}
Live demo.
Variable loop using while loop in "C".
Concept
Creating a 2-dimensional array (arr[level][2]) in which first element is starting, and second element is end.
x[3][2] = {{0, 10}, {5, 20}, {2, 60}};
Creating another array with starting elements.
y[3] = {0, 5, 2};
We created a second array, because during the loop we will change the first element of "x" array.
Code
#include <stdio.h>
int main(){
// bruteforce
int level = 10;
int start[10] = {0, 0, 0, 0};
int x[10][2] = {{0, 5}, {0, 5}, {0, 5}, {0, 5}};
for (int i = 1;i < level; ++i){
x[i][1] = x[i][1] + 1;
}
while(3>2){
// Your code here
//
printf("%d %d %d %d\n", x[0][0], x[1][0], x[2][0], x[3][0]);
// variable loop code
// ==== Not To Modify ====
int a = 0;
int b = 0;
for(int i = 0;i < level; ++i){
if (x[i][0] >= x[i][1])
{
if(i != level-1){
x[i][0] = start[i];
x[i+1][0] = x[i+1][0] + 1;
}else{
a = 1;
}
b = 1;
}else{
if(b == 0){
x[0][0] = x[0][0] + 1;
b = 1;
}
}
}
if(a == 1){
break;
}
}
return 0;
}
This is a late answer, but maybe it will help someone.
Here is my solution in c++ without recursive function.:
int n_loops{3}; //number of nested for loops
int loops_idx[n_loops]; //like i,j,k but in an array
for (int i = 0; i < n_loops; i++)
loops_idx[i]=0;
int max_idx[n_loops]{3,2,4}; // like in for(; i < counter ;), but the counters in an array
bool is_finished = false;
int debug_n_of_execution{0};
while (!is_finished)
{
for (; loops_idx[0]<max_idx[0]; loops_idx[0]++)
{
/*
some code with loops_idx array as i,j,k...
*/
++debug_n_of_execution;
for (int i = 0; i < n_loops; i++)
std::cout<<loops_idx[i]<<" ";
std::cout << "\n";
}
--loops_idx[0]; //to cancel last increment
//Here it will increment the last loop_idx which isn't equal to max_idx[i]-1
//eg. after first above for loop loops_idx will be (max-1, 0, 0)
//So it will be after this loop (0, 1, 0) and start from the beginning...
for (int i = 0; i < n_loops+1; i++) //+1 to know if all loops are finished
{
if (i == n_loops)
{is_finished= true; break;}
if(loops_idx[i]==max_idx[i]-1)
continue;
++loops_idx[i];
for (int j = 0; j < i; j++) //make any previous loop = 0
loops_idx[j]=0;
break;
}
}
//just to check
int debug_perfect_n_of_execution{max_idx[0]};
for (int i = 1; i < n_loops; i++)
debug_perfect_n_of_execution*= max_idx[i];
std::cout<<"Number of execution: "<<debug_n_of_execution<<" = "<<debug_perfect_n_of_execution;
assert(debug_n_of_execution==debug_perfect_n_of_execution);
std::cout << "\nTests Finished";
And here is the result:
0 0 0
1 0 0
2 0 0
0 1 0
1 1 0
2 1 0
0 0 1
1 0 1
2 0 1
0 1 1
1 1 1
2 1 1
0 0 2
1 0 2
2 0 2
0 1 2
1 1 2
2 1 2
0 0 3
1 0 3
2 0 3
0 1 3
1 1 3
2 1 3
Number of execution: 24 = 24
Tests Finished