possible combinations and loops - c++

i have to make all possible combinations of a 2d array..for e.g. if i have a array of 4x3 ...i m using 4 loops,all runs up to 3.. to get all combinations...
for.e.g if i have a 4x3 array as given below..
1 2 3
4 5 6
7 8 9
10 11 12
i will have to make combinations like
1,4,7,10
1,4,7,11
1,4,7,12
1,4,8,10
1,4,8,11
1,4,8,12
1,4,9,10
1,4,9,11
1,4,9,12
1,5,8,10
1,5,8,11
1,5,8,12
...........
and so on....
in short all such combinations...the max number of possible combinations in this case will be 3 power 4....and if i have a array of nxm then maximum combinations will be m power n....can any one help creating it....i want help to solve it in generic .....i think recursive function shall be used...as i don't know the no of loop...it will be known during run time...

void buildArray(vector <int> build, vector< vector <int> > &arrays)
{
int position = build.size();
if (position == arrays.size()) { /* current build is one of the solutions*/}
else {
for (int i = 0; i < arrays[position].size(); i++)
{
build.push_back(arrays[position][i]);
buildArray(build, arrays);
build.pop_back();
}
}
}

Related

Populating a vector with numbers and conditions in C++

Working on a business class assignment where we're using Excel to solve a problem with the following setup and conditions, but I wanted to find solutions by writing some code in C++ which is what I'm most familiar from some school courses.
We have 4 stores where we need to invest 10 million dollars. The main conditions are:
It is necessary to invest at least 1mil per store.
The investments in the 4 stores must total 10 million.
Following the rules above, the most one can invest in a single store is 7 million
Each store has its own unique return of investment percentages based off the amount of money invested per store.
In other words, there is a large number of combinations that can be obtained by investing in each store. Repetition of numbers does not matter as long as the total is 10 per combination, but the order of the numbers does matter.
If my math is right, the total number of combinations is 7^4 = 2401, but the number of working solutions
is lesser due to the condition that each combination must equal 10 as a sum.
What I'm trying to do in C++ is use loops to populate each row with 4 numbers such that their sum equals 10 (millions), for example:
7 1 1 1
1 7 1 1
1 1 7 1
1 1 1 7
6 2 1 1
6 1 2 1
6 1 1 2
5 3 1 1
5 1 3 1
5 1 1 3
5 1 2 2
5 2 1 2
5 2 2 1
I'd appreciate advice on how to tackle this. Still not quite sure if using loops is a good idea whilst using an array (2D Array/Vector perhaps?) I've a vague idea that maybe recursive functions would facilitate a solution.
Thanks for taking some time to read, I appreciate any and all advice for coming up with solutions.
Edit:
Here's some code I worked on to just get 50 rows of numbers randomized. Still have to implement the conditions where valid row combinations must be the sum total of 10 between the 4;
int main(){
const int rows = 50;
int values[rows][4];
for (int i = 0; i < 50; i++) {
for (int j = 0; j <= 3; j++){
values[i][j]= (rand() % 7 + 1);
cout << values[i][j] << " ";
}
cout << endl;
}
}
You can calculate this recursively. For each level, you have:
A target sum
The number of elements in that level
The minimum value each individual element can have
First, we determine our return type. What's your final output? Looks like a vector of vectors to me. So our recursive function will return a the same.
Second, we determine the result of our degenerate case (at the "bottom" of the recursion), when the number of elements in this level is 1.
std::vector<std::vector<std::size_t>> recursive_combinations(std::size_t sum, std::size_t min_val, std::size_t num_elements)
{
std::vector<std::vector<std::size_t>> result {};
if (num_elements == 1)
{
result.push_back(std::vector<std::size_t>{sum});
return result;
}
...non-degenerate case goes here...
return result;
}
Next, we determine what happens when this level has more than 1 element in it. Split the sum into all possible pairs of the "first" element and the "remaining" group. e.g., if we have a target sum of 5, 3 num_elements, and a min_val of 1, we'd generate the pairs {1,4}, {2,3}, and {3,2}, where the first number in each pair is for the first element, and the second number in each pair is the remaining sum left over for the remaining group.
Recursively call the recursive_combinations function using this second number as the new sum, and num_elements - 1 as the new num_elements to find the vector of vectors for the remaining group, and for each vector in the return vector, append the first element from the above set.

finding whats wrong with my code,solving a easy competitive problem

QN;Here is the question.i dont know where my algorithm is wrong.help me find pls
Given an array A of N length. We need to calculate the next greater element for each element in given array. If next greater element is not available in given array then we need to fill ‘_’ at that index place.
Input:
The first line contains an integer T, the number of test cases. For each test case, the first line contains an integer n, the size of the array. Next line contains n space separated integers denoting the elements of the array.
Output:
For each test case, the output is an array that displays next greater element to element at that index.
Constraints:
1 <= T <= 100
1 <= N <= 100
-106 <= Ai <= 106
Example:
Input
2
9
6 3 9 8 10 2 1 15 7
4
13 6 7 12
Output:
7 6 10 9 15 3 2 _ 8
_ 7 12 13
Explanation:
Testcase 1: Here every element of the array has next greater element but at index 7, 15 is the greatest element of given array and no other element is greater from 15 so at the index of 15 we fill with ''.
Testcase 2: Here, at index 0, 13 is the greatest value in given array and no other array element is greater from 13 so at index 0 we fill ''.
My solution:
//NOT SOLVED YET
#include<iostream>
using namespace std;
int main()
{
int a[10]={6 ,3 ,9, 8 ,10, 2 ,1, 15, 7};
int b[10],flag=0,big=-1,i,j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
if(i==j)continue;
if((a[j]>a[i]) && (flag==0))
{
big=a[j];
flag=1;
}
else if(a[j]<big && big>a[i] && flag==1)
big=a[j];
}
if(big==-1)cout<<'_';
else cout<<big<<' ';
big=-1;
flag=0;
}
}
the output i get is:
2 2 2 2 7 1 0 _ 2 1
The condition should be:
else if(a[j] < big && a[j] > a[i] && flag == 1)
Indeed, if you use big > a[i], then that means you just check if the thus far next greater element was larger than a[i], but this thus makes it possible to select a value later in the process that is smaller than big, but smaller than a[i] as well. Here we thus want to check if a[j] is between a[i] and big.
That being said, the above approach is not very efficient. Indeed, for each element, you calculate the next element in linear time, making this a quadratic time algorithm. You might want to look at solutions where the list is sorted first. You can for example use min-heap here to move over the list in two passes.
To expand on what others have mentioned - that you currently have an O(N^2) algorithm, and this can be done more efficiently.
I don't think you can get O(N) here, but here is a plan for an O(N log N) algorithm:
For each test case:
Load the Ai values into two arrays, let's call them X and Y
Sort the Y array
Iterate over X and for each element of X do a binary search into Y to find the next larger value of Ai: use that as the output, or use _ if you did not find one
I recommend, for practice purposes, implementing this both using the C++ standard library, using https://en.cppreference.com/w/cpp/algorithm/sort and https://en.cppreference.com/w/cpp/algorithm/upper_bound , and implementing the above two functions yourself, see: https://en.wikipedia.org/wiki/Quicksort

Query based shifting elements in array

We are given two numbers n and m. n indicates the number of elements in the array and m indicates number of queries.We are given m queries.We need to perform two types of queries on the array.Queries can be of two types, type 1 and type 2.
TYPE 1 queries are represented as (1 i j ) : Modify the given array by removing elements between i to j position and adding them to the front.
TYPE 2 queries are represented as (2 i j ) : Modify the given array by removing elements between i to j position and adding them to the back.
Our task is to simply print the difference array[1]-array[n] after the execution of queries followed by printing the array.
INPUT FORMAT:
First line consists of two space-separated integers, n and m.
Second line contains n integers, which represent the elements of the array.
m queries follow. Each line contains a query of either type 1 or type 2 in the form (type i j).
OUTPUT FORMAT:
Print the absolute value a[0]-a[n] in the first line.
Print elements of the resulting array in the second line. Each element should be separated by a single space.
EXAMPLE:
Given array is [1,2,3,4,5,6,7,8].
After execution of query(1 2 4),the array becomes(2,3,4,1,5,6,7,8).
After execution of query(2 3 5),the array becomes(2,3,6,7,8,4,1,5).
After execution of query(1 4 7),the array becomes(7,8,4,1,2,3,6,5).
After execution of query(2 1 4),the array becomes(2,3,6,5,7,8,4,1).
For the problem,I wrote a program as follows:
int main()
{
int n,m;
cin>>n;
cin>>m;
int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
int count; // counter to control no of queries to accept
for(count=0;count<m;count++)
{
int type,start,end; // 3 parts of query
cin>>type;cin>>start;cin>>end;
if(type==1)
{
//calculated difference between (start,end) to find no of iterations
for(int i=0;i<=(start-end);i++)
{ // t is temporary variable
int t=arr[(start-1)+i]; //(start-1) as index starts from 0
arr[(start-1)+i]=arr[i];
arr[i]=t;
}
}
else
{
for(int i=0;i<=(start-end);i++)
{
int t=arr[(start-1)+i];
// elements inserted from end so we subtract (n)-(start-end)
arr[(start-1)+i]=arr[(n-1)-(start-end)+i];
arr[(n-1)-(start-end)+i]=t;
}
}
count++;
//increment count
}
int absolute=abs(arr[0]-arr[n-1]);
cout<<absolute<<"\n";
for(int i=0;i<n;i++)
{
cout<<arr[i]<<" "<<endl;
}
return 0;
}
I was expecting the code to work correctly,but surprisngly did not even display the output correctly as well.Here is the test case:
INPUT:
8 4
1 2 3 4 5 6 7 8
1 2 4
2 3 5
1 4 7
2 1 4
EXPECTED OUTPUT:
1
2 3 6 5 7 8 4 1
MY OUTPUT:
7
1
2
3
4
5
6
7
8
I had dry run the code many times but cannot seem to understand where the problem is coming from.Please look at the code and provide me suggestions.
The for loop condition is wrong.
CORRECT WAY : for ( int i = 0; i<=(end - start ) ; i++)

Getting rid of non-unique entries in an adjacency list

I'm currently working on a project for my upper-level C++ class, and we are building a program that makes a maze, then solves it, the makes a PNG of said maze. Pretty cool stuff. Anyways, I'm current on the bit where I need to make the maze.
My program makes valid mazes just fine, but I have to make each number output unique. The output just spits out two indicies in a 2d matrix that have walls between them, sample output for a 3X4 maze is as follows:
rjeffor1:hydra20 ~/cs302/labs/lab5> ./mazemake 3 4 <- 9:49AM
1 2
1 5
2 1
2 3
3 2
5 1
5 9
6 7
7 6
8 9
9 8
9 5
However, my last problem is that I need to get rid of duplicate walls, for example 1 2 and 2 1. EDIT: and by this I mean just get rid of the 2 1, I still need the wall and therefore the 1 2.
Here is my function in which I attempt to fix the problem:
void aL::make_unique()
{
vector<int>::iterator it, it0;
//need to iterate thru all but last index
for (int i=0; i<(int)adjList.size()-1; i++) {
for (int j=0; j<(int)adjList.size(); j++) {
//find it
if (i!=j) {
it0 = std::find(adjList[i].begin(), adjList[i].end(), j);
it = std::find(adjList[j].begin(), adjList[j].end(), i);
if (it!=adjList[j].end() && it!=adjList[j].end())
//erase it if anything is there
adjList[j].erase(it);
}
}
}
}
Help is appreciated, my brain is so done at this point
EDIT: here is how I populate the adjancency lists, based on indicies directly left right above and below each index
aL::aL (const int &rows, const int &cols)
{
adjList.resize(rows*cols);
//run thru and figure out where indicies AREN'T
//to fill in their adjacency list
for (int i=0; i<(int)adjList.size(); i++) {
//if not on the left edge
if (i%cols!=0)
adjList[i].push_back(i-1);
//not on the right edge
if ((i+1)%cols!=0)
adjList[i].push_back(i+1);
//not on the top edge
if (i>=cols)
adjList[i].push_back(i-cols);
//not on the bottom edge
if (i<(rows*cols)-cols)
adjList[i].push_back(i+cols);
}
}
You could remove the need to post-process and make it unique at the end if you check as you are adding to your list. Don't add "a b" if "b a" is already there.

C++ Matrix combinations

Firstly thanks for reading.I'm trying to make a "noob" program and i wanted to use a registration code.
For completing my encryption algorythm i need to generate all 4x4 matrices containing only numbers from 0 to 9 like in the following example:
4 4 6 8
5 2 4 3
8 5 2 9
2 7 2 6
I know there is a huge number of these combinations but it wont stop me.I tried myself to do it using "for" but i can't figure it out.
I would store the 4x4 digit matrix as char[16], interpreting the first four chars as the first row, the next four chars as the second row, etc. You can easily generate all possible values by recursion, with a for loop on each level.
void print_all_possible_matrices(char *matrix, int level) {
if(level == 16) {
print_matrix(matrix);
}
for(int i = 0; i < 10; ++i) {
matrix[level] = i;
print_all_possible_matrices(matrix, level + 1);
}
}
You would use this in the following way:
int main() {
char matrix[16];
print_all_possible_matrices(matrix, 0);
}
But this will take really loooong time to complete.