Query based shifting elements in array - c++

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++)

Related

Tell me the Input in which this code will give incorrect Output

There's a problem, which I've to solve in c++. I've written the whole code and it's working in the given test cases but when I'm submitting it, It's saying wrong answer. I can't understand that why is it showing wrong answer.
I request you to tell me an input for the given code, which will give incorrect output so I can modify my code further.
Shrink The Array
You are given an array of positive integers A[] of length L. If A[i] and A[i+1] both are equal replace them by one element with value A[i]+1. Find out the minimum possible length of the array after performing such operation any number of times.
Note:
After each such operation, the length of the array will decrease by one and elements are renumerated accordingly.
Input format:
The first line contains a single integer L, denoting the initial length of the array A.
The second line contains L space integers A[i] − elements of array A[].
Output format:
Print an integer - the minimum possible length you can get after performing the operation described above any number of times.
Example:
Input
7
3 3 4 4 4 3 3
Output
2
Sample test case explanation
3 3 4 4 4 3 3 -> 4 4 4 4 3 3 -> 4 4 4 4 4 -> 5 4 4 4 -> 5 5 4 -> 6 4.
Thus the length of the array is 2.
My code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
bool end = false;
int l;
cin >> l;
int arr[l];
for(int i = 0; i < l; i++){
cin >> arr[i];
}
int len = l, i = 0;
while(i < len - 1){
if(arr[i] == arr[i + 1]){
arr[i] = arr[i] + 1;
if((i + 1) <= (len - 1)){
for(int j = i + 1; j < len - 1; j++){
arr[j] = arr[j + 1];
}
}
len--;
i = 0;
}
else{
i++;
}
}
cout << len;
return 0;
}
THANK YOU
As noted in the comments: Just picking the first two neighbours that have the same value and combining those will lead to suboptimal results.
You will need to investigate which two neighbours you should combine somehow. When you have combined two neighbours you then need to investigate which neighbours to combine on the next level. The number of combinations may become plentiful.
One way to solve this is through recursion.
If you've followed the advice in the comments, you now have all your input data in std::vector<unsigned> A(L).
You can now do std::cout << solve(A) << '\n'; where solve has the signature size_t solve(const std::vector<unsigned>& A) and is described below:
Find the indices of all neighbour pairs in A that has the same values and put the indices in a std::vector<size_t> neighbours. Example: If A contains 2 2 2 3, put 0 and 1 in neighbours.
If no neighbours are found (neighbours.empty() == true), return A.size().
Define a minimum variable and initialize it with A.size() - 1 which is the worst result you know you can get at this point. So, size_t minimum = A.size() - 1;
Loop over all indices stored in neighbours (for(size_t idx : neighbours))
Copy A into a new std::vector<unsigned>. Let's call it cpy.
Increase cpy[idx] by one and remove cpy[idx+1].
Call size_t result = solve(cpy). This is where recursion comes in.
Is result less than minimum? If so assign result to minimum.
Return minimum.
I don't think I ruined the programming exercise by providing one algorithm for solving this. It should still have plenty of things to deal with. Recursion won't be possible with big data etc.

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.

Merging numbers to form a big number

If I have an int array with elements {1,2,3,4}
and I do not want to add the ints inside it but instead I want to have an int variable that holds the first 3 digits of the array for it to be int x = 123; and 123 being the first 3 elements{1,2,3} of the array, any ideas?
Basically instead of having 1 2 3 as separate digits in 3 separate indexes of the array I'd like to have 1 index OR variable that will be 123 as an actual 3 digit number.
You can use this approch. First of all assign the first digit of array (stored at array[0]) to the variable x. Then multiply it with 10 and then add the next digit of array into it, and do it one more time to insert first three digits into variable x.
Here is the code and hope it helps
#include<iostream>
int main()
{
int array[] = {1,2,3,4}, x = 0, i;
for(i=0;i<3;i++)
{
x = (x * 10) + array[i];
}
cout<<x;
return 0;
}

Incorrect output using array as counter

I'm trying to teach myself programming by attempting problems from codeabbey.com.
I'm not getting the correct output on this question.
Question:
Here is an array of length M with numbers in the range 1 ... N, where N is less than or equal to 20. You are to go through it and count how many times each number is encountered.
Input data contain M and N in the first line.
The second (rather long) line will contain M numbers separated by spaces.
Answer should contain exactly N values, separated by spaces. First should give amount of 1-s, second - amount of 2-s and so on.
Data input:
10 3
1 2 3 2 3 1 1 1 1 3
Correct Output:
5 2 3
My Output:
7 3 4
You can check here
My Code:
#include <iostream>
using namespace std;
int main()
{
int arrayLength,range,a;
cin>>arrayLength>>range;
int array[20];
array[20]={0};
for(int i=0; i<arrayLength; i++)
{
cin>>a;
++array[a-1];
}
for(a=0; a<range; a++)
{
cout<<array[a]<<" ";
}
return 0;
}
There aren't any error messages or warnings. Also, if you have any suggestions for improving the code, that'd be nice.
int array[20];
array[20]={0};
is wrong, since it leave the array un-initialized and tries to initialize the 21st element (which is undefined behaviour btw, since your array has only 20 elements, remember that indexing starts from 0). Use
int array[20] = {0}; // this will initialize all elements to 0
and your code will work as expected. See here for more details regarding aggregate initialization in C++.
array[20]={0}; initializes the 21st element(non-existing) to 0.
So you have to use int array[20] = {0}; which will initialize all 20 elements to zero.
Also from your code, you are not storing the elements to an array. You are just incrementing the corresponding count when an input is read. If so, what is the need of initializing an array to max limit. Just declare the array as you need it. In your case,
int array[range] = {0};
It will initialize an array of three (range =3 here) elements.

calculating each line in 2d arrays c++

I'm trying to create an array loop using pointers. For example,
2 3 1 2
3 1 2 2
4 3 2 2
The number of lines are undetermined so we don't know how many lines of integers there will be. I have these data of integers stored into a pointer variable called "scores". So if I want to access them,
scores[0][0] = 2
scores[0][2] = 1
I'm trying to create a for loop where it will add each integer divide it by 2 and then add the sum up. So if I implement a function where it does this, i'd expect the value to be
4 // (2/2) + (3/2) + (1/2) + (2/2) = 4
4
5.5
This is what I have so far, but it's not working.
int *total;
int lines;
total = new int[lines]; //lines: how many lines there are (assume it is passed through a parameter)
for (int i=0;i<lines;i++)
{
for (int j=0;j<howmany;j++) //howmany is how many integers there are per line (assume it is passed again)
{
total[i] = scores[i][j] //not sure how to divide it then accumulate the sum per line and store it
Assume that "scores" already hold the data of integers and we're extracting the data of integers elsewhere so the user does not input anything.
I would want to access the calculated sum by doing total[0], total[1], etc..
For integer division
// (2/2) + (3/2) + (1/2) + (2/2) = 4
this will give 3, not 4
this will give you 4
// (2 + 3 + 1 + 2 ) / 2 = 4
And you are expecting value such as 5.5, so you should define the result as float or double
float *result;
int lines = 3; // need to initialize local variable before new. for this case, we set the lines to 3.
int total;
result = new float[lines]; //lines: how many lines there are (assume it is passed through a parameter)
for (int i=0;i<lines;i++)
{
total = 0;
for (int j=0;j<howmany;j++) //howmany is how many integers there are per line (assume it is passed again)
{
total += scores[i][j];
}
result[i] = (float)total/2;
}