I need to write a program that takes the input of 3 positive integers. Then find their distinct permutations in increasing order. e.g.
{
{1 2 3}
{1 3 2}
{2 1 3}
{2 3 1}
{3 1 2}
{3 2 1}
}
Then, insert operators '+' or '-' between each two numbers to form an equation and print the result of
it. For each operation, both + and – should be considered. For example, for the permutation of 1 2 3,
we need to consider four cases: 1 + 2 + 3 = 6, 1 + 2 – 3 = 0, 1 – 2 + 3 = 2, and 1 – 2 – 3 = -4.
The output should display all possible equations and their calculation results in an increasing order
sorted by the result of the equation. If two equations have the same result, further sort the equations
in an increasing order of the permutations. For example, 1 + 2 + 3 = 6 should be output before
1 + 3 + 2 = 6 because permutation 1 2 3 is smaller than 1 3 2 according to the definition above.
The order of permutation is defined as follow:
• compare the number in the left-most place first. The permutation with the smaller leftmost number is said to be smaller, e.g., 1 3 2 is smaller than 2 1 3.
• If the left-most number are the same, compare the next one, e.g., 2 1 3 is smaller than 2 3 1
My code :
I wrote two functions.
permutation to find the distinct permutation of 3 integers.
sortPermutation to sort the permutation in an increasing order. But I am not sure if I am doing the right thing in this function.
I have no idea how to perform the + and - operation for the permutation, as well as to sort them in increasing order and display them afterwards. I have searched for resources online but still do not have an idea. Any help will be appreciated!!
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> sortPermutation(vector<int> &result);
vector<vector<int>> permutation(vector<int>num);
int main()
{
int a, b, c;
cout << "Enter three different positive numbers: ";
cin >> a >> b >> c;
vector<int> num = { a,b,c };
int size = num.size();
vector<vector<int>> result = permutation(num);
for (int i = 0; i < result.size(); i++)
{
for (int j = 0; j < result[i].size(); j++)
{
cout << result[i][j];
}
cout << endl;
}
}
vector<vector<int>> sortPermutation(vector<vector<int>>& result)
{
sort(result.begin(),
result.end(),
[](const std::vector<int>& a, const std::vector<int>& b)
{
return a[0] < b[0];
});
return result;
}
vector<vector<int>> permutation(vector<int>num)
{
vector<vector<int>> permu;
if (num.size() <= 1)
{
return { num };
}
for (int i = 0; i < num.size(); i++)
{
vector<int>v(num.begin(), num.end()); // 1,2,3
v.erase(v.begin() + i); //2,3 // 3 // 2
auto res = permutation(v);//3 // 2 // 1 // 3 // 1 // 2
for (int j = 0; j < res.size(); j++)
{
vector<int>_v = res[j];
_v.insert(_v.begin(), num[i]);
permu.push_back(_v);
}
}
return sortPermutation(permu);
}
This is a sample output for permutation 1 2 3
1 - 2 - 3 = -4
1 - 3 - 2 = -4
2 - 1 - 3 = -2
2 - 3 - 1 = -2
1 + 2 - 3 = 0
1 - 3 + 2 = 0
2 + 1 - 3 = 0
2 - 3 + 1 = 0
3 - 1 - 2 = 0
3 - 2 - 1 = 0
1 - 2 + 3 = 2
1 + 3 - 2 = 2
3 + 1 - 2 = 2
3 - 2 + 1 = 2
2 - 1 + 3 = 4
2 + 3 - 1 = 4
3 - 1 + 2 = 4
3 + 2 - 1 = 4
1 + 2 + 3 = 6
1 + 3 + 2 = 6
2 + 1 + 3 = 6
2 + 3 + 1 = 6
3 + 1 + 2 = 6
3 + 2 + 1 = 6
Related
void vectorDeduplicator(std::vector<std::string>& inputVector){
for(int i = 0; i < inputVector.size() - 1; i++){
for(int x = 1; x <= inputVector.size() - 1; x++)
if(inputVector.at(i) == inputVector.at(x) && i != x){
inputVector.erase(inputVector.begin() + x);
}
}
}
Input: 1 1 2 2 4 4 3 3 1 1 3 3 3 2 2
Output: [1,2,4,1,3,2]
You can see the function I'm trying to use to remove duplicates inside of a vector. It works when duplicates are adjacent. I wouldn't like to use a faster and an efficient method without knowing anything about it that already exists within the standard library or anything else. I'd like to learn the algorithm behind it as this is for learning purposes.
The problem is you ignore one value as you erase. You need to decrement x:
#include <vector>
#include <iostream>
void vectorDeduplicator(std::vector<int>& inputVector)
{
for(int i = 0; i < inputVector.size() - 1; i++)
{
for(int x = 1; x < inputVector.size(); x++)
{
if(inputVector.at(i) == inputVector.at(x) && i != x)
{
inputVector.erase(inputVector.begin() + x);
x--; // go one back because you erased one value
}
}
// to debug
for(const auto& x : inputVector)
std::cout << x << " ";
std::cout << std::endl;
}
}
int main(){
std::vector<int> vector{1, 1, 2, 2, 4, 4, 3, 3, 1, 1, 3, 3, 3, 2, 2};
vectorDeduplicator(vector);
// output
for(const auto& x : vector)
std::cout << x << " ";
return 0;
}
The output then is:
1 2 2 4 4 3 3 3 3 3 2 2
1 2 4 4 3 3 3 3 3
1 2 4 3 3 3 3 3
1 2 4 3
1 2 4 3
So for my current homework assignment, I have to determine whether the sum of all the rows in a square are equal, if they are all equal then the square is 'Awesome' otherwise 'Not Awesome'. In this program the first input is the number of squares you want to solve and then for each square you enter how many rows it will have, followed by a series of integers to represent each number in the 'square'. Below is my tried and tested code, for me, I cant seem to come up with a test case that breaks it, yet when I upload it for grading, the grading bot fails it. Any help is greatly appreciated.
At first I thought it was an overflow issue, so I changed the sum and temp variables to long long but it had no effect.
input examples:
3
4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
3
1 2 3
2 3 1
3 2 7
5
1 2 3 4 5
1 1 1 1 11
2 2 2 2 7
3 3 3 3 3
4 4 4 4 -1
output would be:
Awesome
Not Awesome
Awesome
#include <iostream>
using namespace std;
int main()
{
int numTests, numRows, i, col, row, firstRun;
long long sum, prevSum, temp;
cin >> numTests;
for (i = 0; i < numTests; i++)
{
firstRun = 1;
cin >> numRows;
for (row = 0; row < numRows; row++)
{
sum = 0;
for (col = 0; col < numRows; col++)
{
cin >> temp;
sum += temp;
}
if (!firstRun && prevSum != sum)
break;
firstRun = 0;
prevSum = sum;
}
if (row != numRows)
cout << "Not ";
cout << "Awesome" << endl;
}
return 0;
}
You are breaking the loop when you get the answer . But input may not finish .
1
4
1 2 3 4
1 2 3 1
1 2 3 4
1 2 3 4
Here , your loop will break after inputting second row . Thus the subsequent numbers are treating wrongly and causing WA . Consider the case
2
3
1 2 3
1 2 1
3 2 1
3
3 1 1
1 1 3
1 3 1
Your program will print
Not Awesome
Not Awesome
I have written this quick sort algorithm but it doesn't work properly for some reason, I need some help to find out the error.
I tried not to use built-in swap function however it didn't work out.
FindPivot function returns the median of three elements (start, half, end) of the array after swapping them so that the smallest one is at the start, the greatest at the middle and the median at the end of the array
#include <bits/stdc++.h>
using namespace std;
int pivotIdx, pivot, n;
int partitn(int* arr, int first, int last)
{
pivot = FindPivot(arr,first,last-1);
// pivot = arr[last-1];
cout << "Pivot: " << pivot << endl;
int L = first;
int R = last-2;
while(L<R)
{
while(arr[L]<=pivot)
L++;
while(arr[R]>=pivot)
R--;
swap(arr[L++],arr[R--]);
}
swap(arr[L],arr[last-1]);
return L;
}
void QuickSort(int* arr,int first,int last)
{
if(last-first < 6){
InsertionSort(arr,first,last);
}else{
pivotIdx = partitn(arr, first, last);
QuickSort(arr, first, pivotIdx);
QuickSort(arr, pivotIdx+1, last);
}
}
int main()
{
cin >> n;
int arr[100];
for(int i=0;i<n;i++)
cin>>arr[i];
QuickSort(arr,0,n);
for(int i=0;i<n;i++){
cout << arr[i] << " ";
}
return 0;
}
Input:
8
5 1 6 2 7 3 8 4
Output:
Pivot: 4
1 2 3 5 4 6 7 8
There may be other issues, but the current partition code could scan past the boundaries of the sub-array. Assuming the pivot is not at either end of the sub-array, the code can < instead of <= and > instead of >= and the scans will not run past the boundaries.
while(arr[L]<pivot) // not <=
L++;
while(arr[R]>pivot) // not >=
R--;
Input:
5 1 6 2 7 3 8 4
This becomes:
QuickSort([5 1 6 2 7 3 8 4], 0, 8)
partitn([5 1 6 2 7 3 8 4], 0, 8)
pivot = 4
L = 0 R = 6 [5 1 6 2 7 3 8 4]
// Enter Loop
L = 0 R = 5 swap [3 1 6 2 7 5 8 4]
L = 2 R = 3 swap [3 1 2 6 7 5 8 4]
L = 3 R = 2 swap [3 1 6 2 7 5 8 4]
// Exit Loop
L = 3 swap [3 1 6 4 7 5 8 2] This looks wrong.
The 2 and 6 are in the wrong place.
I am trying to generate a list of subsets from a set. For example, if I had n = 6, and r = 4, I would have 15 possible combinations which would be the following:
0 1 2 3
0 1 2 4
0 1 2 5
0 1 3 4
0 1 3 5
0 1 4 5
0 2 3 4
0 2 3 5
0 2 4 5
0 3 4 5
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5
My current code does work with the above subsets if n = 6 & r = 4. It also works if any other combination of n-r=2. It does not work for anything else and I'm having a bit of trouble debugging since my code makes perfect sense to me. The code I have is the following:
int array[r];
int difference = n-r;
for(int i = 0; i < r; i++){
array[i] = i;
}
while (array[0] < difference){
print (array, r);
for(int i = r-1; i >= 0; i--){
if ((array[i] - i) == 0){
array[i] = array[i] + 1;
for (int j = i+1; j < r; j++){
array[j] = j + 1;
}
i = r;
}
else{
array[i] = array[i] + 1;
}
print (array, r);
}
}
}
To give some context, when I plug in n=6 and r=3, I am supposed to have 20 combinations as the output. Only 14 are printed, however:
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
2 3 4
2 3 5
2 4 5
3 4 5
It does print the first and last output correctly, however I need to have all the outputs printed out and correct. I can see after the 3rd iteration, the code starts failing as it goes from 0 1 4 to 0 2 3 when it should go to 0 1 5 instead. Any suggestions as to what I'm doing wrong?
Here's what I think you are trying to do. As far as I can tell, your main problem is that the main for loop should start over after incrementing an array element to a valid value, rather than continuing.
So this version only calls print in one place and uses break to get out of the main for loop. It also counts the combinations found.
#include <iostream>
void print(int array[], int r) {
for(int i=0; i<r; ++i) {
std::cout << array[i] << ' ';
}
std::cout << '\n';
}
int main() {
static const int n = 6;
static const int r = 3;
static const int difference = n-r;
int array[r];
for(int i = 0; i < r; i++) {
array[i] = i;
}
int count = 0;
while(array[0] <= difference) {
++count;
print(array, r);
for(int i=r-1; i>=0; --i) {
++array[i];
if(array[i] <= difference + i) {
for(int j=i+1; j<r; ++j) {
array[j] = array[j-1] + 1;
}
break;
} } }
std::cout << "count: " << count << '\n';
}
Outputs
0 1 2
0 1 3
0 1 4
0 1 5
0 2 3
0 2 4
0 2 5
0 3 4
0 3 5
0 4 5
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
count: 20
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 0.0;
cout << i << endl;
}
}
Output:
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
...
If SIZE is initialized to a different value, the iterator will iterate until it is one short of that value and then reset back to zero. If the array of x is changed to data type int, the loop does not get stuck on itself. If the assignment value to x[i] is changed to any non-zero number, the value of is changed to garbage during the last run of the loop.
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 1;
cout << i << endl;
}
}
Output:
2
3
4
1072693248
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
int x[SIZE];
for(int i = 2; i <= SIZE; i++) {
x[i] = 1;
cout << i << endl;
}
}
Output:
2
3
4
5
You are writing past the end of the x array. x[] ranges from 0 to SIZE - 1 (or 4), and you let your index i == SIZE.
So, the behavior is undefined and coincidentally, you are overwriting i when you write x[5].
Use a debugger. It's your friend.
for(int i = 2; i < SIZE; i++) // i <= SIZE will write beyond the array
Your current array is of size 5. Arrays are 0 indexed:
1st element last element
0 1 2 3 4
You're iterating past the end of your array (i <= 5), which is undefined behavior.
Your end condition is wrong. Use i < SIZE
#include <iostream>
using namespace std;
int main() {
const int SIZE = 5;
double x[SIZE];
for(int i = 2; i < SIZE; i++) {
x[i] = 0.0;
cout << i << endl;
}
}