Adding Integers In A Vector - c++
Ok, I have another challenge. I have a question that asks me to "Read a set of integers into a vector. Print the sum of each pair of adjacent elements . Change your program so that it prints out the sum of the first and last elements, followed by the sum of the second and second-to-last, and so on."
Currently I have managed to get it to add consecutive numbers, not exactly in pairs, but as close as I can get it.
The only operators I have learnt thus far for vectors, and what the question wants me to use are: v.empty(); v.size(); v.push_back(t); v[n]; v1 = v2; v1 = {a,b,c...}; v1 == v2; v1 != v2; <, <=, >, >=
Here is my code as it stands now:
#include <iostream>
#include <string>
#include <vector>
using std::string; using std::vector; using std::cout; using std::cin; using std::endl;
int main ()
{
vector<unsigned> numbers {5, 6, 7, 8, 9, 10, 11};
unsigned sum;
decltype(numbers.size()) count;
for (count = 0; count < numbers.size(); ++count){
sum = (numbers[count]++) + (numbers[count]);
cout << sum << " ";
}
}
So I can get it to add 5+6; 6+7; 7+8 etc... but as for each pair and all the rest, not 100% sure where to start. Any guidance will be greatly appreciated!
To print the sum of each pair of adjacent elements.
auto count = numbers.size();
for (auto i = 0; i < numbers.size()-1; i++)
{
std::cout << (numbers[i] + numbers[i+1]) << "\t";
}
prints out the sum of the first and last elements, followed by the sum of the second and second-to-last, and so on
for (auto i = 0; i < count/2; ++i)
{
std::cout << (numbers[i] + numbers[count - i -1]) << "\t";
}
Note: if vector has odd number, the middle one won't be calculated in second print
See sample output
Below two loops that print (1) sum of adjacent pairs and (2) the sum of opposite elements.
#include <cstddef>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main ()
{
vector<unsigned> numbers {5, 6, 7, 8, 9, 10, 11};
auto N = numbers.size();
std::cout << "first part\n";
for (size_t i = 1; i < N; ++i) {
std::cout << numbers[i-1] + numbers[i] << "\n";
}
std::cout << "second part\n";
for (size_t i = 0; i < (N - 1 - i); ++i) {
std::cout << numbers[i] + numbers[N - 1 - i] << "\n";
}
// in case you have an odd number of elements
if (N % 2 == 1) std::cout << numbers[N / 2] << "\n";
}
Output on LiveWorkSpace
I think your current code won't work for different examples. You need to change numbers[count]++ to numbers[count+1] for it to work, and change the loop's end condition to size()-1.
As for your other question, you should be able to do it if you only loop through half the vector and add the numbers of v[i] + v[v.size() - i - 1]
Edit: Added -1 to v[v.size() - i - 1] as suggested by borisbn in the comments
Hi I tried this on VS and it worked
vector <int> num;
num.push_back(5);
num.push_back(6);
num.push_back(7);
num.push_back(8);
num.push_back(9);
num.push_back(10);
int count = 0;
for(;count < (num.size()-1);count++)
{
int sum =0;
sum = num[count] + num[count+1];
cout<<sum<<endl;
}
for(int c =0; c < (num.size()-1);c++)
{
int altrsum = num[c]+ num[(num.size()-1)-c];
cout<<altrsum<<endl;
}
Hope this helps.
Related
C++: I don't know how to solve the timeout in the problem of comparing coordinates in the coordinate plane
Up to 100,000 coordinates are entered. Only coordinates corresponding to specific conditions should be output. If there are coordinates with larger x values and smaller y values than each coordinate, the corresponding coordinates are excluded from the output list. My English is not good, so I'm giving some examples. [input] First enter the number of coordinates N to be input. and enter the coordinates. [output] The coordinate numbers corresponding to the condition are output in ascending order. p2 is not correct p4 is correct [input example] 6 1 3 6 6 7 3 8 2 8 6 2 1 [output example] 4 5 6 The time limit is 500ms. [timeout input example] 50000 1 1 1 2 1 3 ... skip 1 49999 1 50000 [timeout output example] 1 1 1 2 1 3 ... skip 1 49999 1 50000 coordinates image: The following problem was solved with a simple loop, but a timeout occurs when 100,000 values are entered. I don't know which algorithm to use. I also attach the C++ source code I wrote. Also, I tried using the sort function, but when the number of N is small, it works fine, and when the number of N is large, it cannot be compared properly. I guess I couldn't write the compare function properly. So I tried writing the source code without using sort. I thought and corrected it over two days, but I couldn't solve it, so I seek help. thanks for reading. #include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { int N; cin >> N; bool* visible = new bool[N]; for (int i = 0; i < N; i++)visible[i] = true; vector<pair<int,pair<int, int>>> v; for (int i = 0; i < N; i++) { int a, b; cin >> a >> b; v.push_back(make_pair(i,make_pair(a, b))); } for (int i = 0; i < v.size(); i++) { if (visible[i] == false) continue; for (int j = 0; j < v.size(); j++) { if (visible[i] == true &&visible[j]==true && v[i].second.first < v[j].second.first && v[i].second.second > v[j].second.second) { visible[i] = false; break; } else if (visible[i] == true && visible[j] == true && v[i].second.first > v[j].second.first && v[i].second.second < v[j].second.second) { visible[j] = false; continue; } } } for (int i = 0; i < v.size(); i++) { if (visible[i] == true) cout << v[i].first + 1 << endl; } return 0; } [Source code that tried to sort but failed] #include <iostream> #include <algorithm> #include <vector> #include <tuple> using namespace std; bool* visible; int compare(pair<int, pair<int, int>> n1, pair<int, pair<int, int>> n2) { pair<int, int> a = n1.second, b = n2.second; bool swap = false; if (a.first > b.first && a.second < b.second) { visible[n2.first - 1] = false; swap = true; } else if (a.first < b.first && a.second > b.second) { visible[n1.first - 1] = false; //swap = true; } cout << "[" << n1.first << "]" << a.first << ", " << a.second << " vb : " << visible[n1.first - 1] << " :\t[" << n2.first << "]" << b.first << ", " << b.second << "vb : " << visible[n2.first - 1] << "\t"; cout << "swap: " << swap << endl; return swap; } int main() { int N; cin >> N; visible = new bool[N]; for (int i = 0; i < N; i++)visible[i] = true; vector<pair<int, pair<int, int>>> v; for (int i = 0; i < N; i++) { int a, b; cin >> a >> b; v.push_back(make_pair(i+1, make_pair(a, b))); } sort(v.begin(), v.end(), compare); for (int i = 0; i < v.size(); i++) cout << "p" << v[i].first << " : " << v[i].second.first << ", " << v[i].second.second <<"\t"<< visible[v[i].first-1]<< endl; return 0; } In this case, p4 moves to (4,2). In this case, p3,4,5,6 becomes the correct answer.
I'm not totally sure this works for every corner case, but the idea is here. It took me a while to nail it down, probably because the problem description wasn't exactly clear. Basically you want to mark as not visible the points for which it is possible to find another one with a larger x and a smaller y, i.e. the points which have another on their lower right. If you sort your points on x, then you only need to check those with a larger index. In fact, we are interested only in the one with the minimum y, because it will dominate all others. That value can only decrease while moving from right to left, so we just need to keep track of the minimum y. The only problem is how to deal with points that have the same x, because they could have a lower y before a higher one, rendering valid points non visible. The trick is to make sure that when browsed from right to left (higher indices to lower ones) the y will decrease. So when sorting, if x is equal we will sort on y. #include <iostream> #include <algorithm> #include <vector> int main() { struct point { int x, y; bool visible = true; }; size_t N; std::cin >> N; std::vector<point> v(N); std::vector<size_t> idx(N); for (size_t i = 0; i < N; ++i) { auto& p = v[i]; idx[i] = i; std::cin >> p.x >> p.y; } sort(idx.begin(), idx.end(), [&v](const size_t& a, const size_t& b) { if (v[a].x == v[b].x) return v[a].y < v[b].y; return v[a].x < v[b].x; }); int miny = INT_MAX; for (size_t i = N; i-- > 0;) { auto& p = v[idx[i]]; miny = std::min(miny, p.y); if (p.y > miny) { p.visible = false; } } for (size_t i = 0; i < N; ++i) { auto& p = v[i]; if (p.visible) { std::cout << i + 1 << '\n'; } } return 0; }
Given two points A and B, there are three possible configurations: A makes B invisible B makes A invisible None of the above The "makes-invisible" relation between the points is not strict weak ordering required by std::sort, so calling std::sort with a comparison function that implements this relation is undefined.
I understood two things from your code, so I'll list both the solutions: I: This is a basic example of a modified 'Longest Increasing Subsequence'. Let's first consider the coordinates as something different, let's say , the coordinate (x,y), would become the ractangle with height (x) and width (y) (consider this as if we were making rectangles with corners (0,0) (x,0) (0,y) (x,y)). If we need 'ascending' points, it means that their areas overlap. More formally, if the list of point we need is A(1),A(2),A(3),...,A(k), then for each i in range 1..k-1, A(i).x<A(i+1).x and A(i).y<A(i+1).y. You can find an optimal solution using this Note: the coordinates should be sorted. By what criteria? Well, as long as the longest increasing subsequence would appear after a sorting of that criteria, then it's correct. II: This is a basic example of finding the convex hull. The convex hull of a polygon would be the convex polygon (with the most nodes) , whose set of coordinates is included in the set of the coordinates of the original polygon. I recommend reading this . After finding the upper half, you can apply a mentality as described in the previous example, although you must find a substring instead of a subsequence, so that would make the complexity O(nlog+n) Hope this was helpful
Wierd combination
I have an array of 3 integers {1,2,3}. I need to print combinations in the form of- 1 1+2 1+3 1+2+3 2 2+3 3 for(int i = 0; i < array.size(); ++i) { for(int j = 0; (i + j) < array.size(); ++j) { sum += my[i + j]; cout << sum << " "; c++; } cout << endl; } In above, 1+3 is being skipped. Please help me with that.
Given a set S the power set P(S) is the set of all subsets of S. What you are trying to do is essentially enumerate all of the non-empty elements of x ∈ P(S). From there, you can iterate over all of the elements of each non-empty x in P(S). What does this mean for you? Well for starters for a set S containing n elements the number of possible elements of P(S) is 2^n, so the size of the power set scales exponentially with the size of its generating set. But, where this may be useful for small values of n (in particular n < 64) you can use unsigned long long variables to act as a kind of index. In particular, each bit corresponds to one of your array elements. Bits with a value of 0 exclude its associated element in the sum, while bits with a 1 would include the element. To do something like this try the following: #include <vector> #include <iostream> void print_sum(const std::vector<int>& array, unsigned long long i) { int sum = 0; for (int index=0; i > 0; i=i>>1, ++index) { if (i % 2 == 1) { std::cout << array[index] << (i>1 ? "+" : "="); sum += array[index]; } } std::cout << sum << std::endl; } void printer(const std::vector<int>& array) { if (array.size() < sizeof(unsigned long long) * 8) { unsigned long long n = 1 << array.size(); for (unsigned long long i = 1; i < n; ++i) { print_sum(array, i); } } } int main(int argc, char** argv) { std::vector<int> sample {1, 2, 3, 4}; printer(sample); return 0; } This program has output: 1=1 2=2 1+2=3 3=3 1+3=4 2+3=5 1+2+3=6 4=4 1+4=5 2+4=6 1+2+4=7 3+4=7 1+3+4=8 2+3+4=9 1+2+3+4=10
Power set of large set
I have to calculate power set of set which may have more elements upto 10^5. I tried an algo and the code below but it failed (I think cause large value of pow(2, size)). void printPowerSet(int *set, int set_size) { unsigned int pow_set_size = pow(2, set_size); int counter, j,sum=0; for(counter = 0; counter < pow_set_size; counter++) { for(j = 0; j < set_size; j++) { if(counter & (1<<j)) std::cout<<set[i]<<" "; } std::cout<<sum; sum=0; printf("\n"); } } Is there any other algorithm or how can I fix this one (if it is possible)?? OR Can you suggest me how to do it i.e. finding subset of large set. As pointed out in an answer it seems I'm stuck in X-Y problem. Basically, I need sum of all subsets of any set. Now if you can suggest me any other approach to solve the problem. Thank you.
Here is an algorithm which will print out the power set of any set that will fit in your computer's memory. Given enough time, it will print the power set of a set of length 10^5. However, "enough time" will be something like several trillion billion gazillion years. c++14 #include <iostream> #include <vector> #include <algorithm> using namespace std; #include <iostream> void printPowerset (const vector<int>& original_set) { auto print_set = [&original_set](auto first, auto last) -> ostream& { cout << '('; auto sep = ""; for ( ; first != last ; ++first, sep = ",") { cout << sep << original_set[(*first) - 1]; } return cout << ')'; }; const int n = original_set.size(); std::vector<int> index_stack(n + 1, 0); int k = 0; while(1){ if (index_stack[k]<n){ index_stack[k+1] = index_stack[k] + 1; k++; } else{ index_stack[k-1]++; k--; } if (k==0) break; print_set(begin(index_stack) + 1, begin(index_stack) + 1 + k); } print_set(begin(index_stack), begin(index_stack)) << endl; } int main(){ auto nums = vector<int> { 2, 4, 6, 8 }; printPowerset(nums); nums = vector<int> { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; printPowerset(nums); return 0; } expected results: first power set (4 items): (2)(2,4)(2,4,6)(2,4,6,8)(2,4,8)(2,6)(2,6,8)(2,8)(4)(4,6)(4,6,8)(4,8)(6)(6,8)(8)() second power set (10 items) (2)(2,4)(2,4,6)(2,4,6,8)(2,4,6,8,10)(2,4,6,8,10,12)(2,4,6,8,10,12,14)(2,4,6,8,10,12,14,16)(2,4,6,8,10,12,14,16,18)(2,4,6,8,10,12,14,16,18,20)(2,4,6,8,10,12,14,16,20)(2,4,6,8,10,12,14,18)(2,4,6,8,10,12,14,18,20)(2,4,6,8,10,12,14,20)(2,4,6,8,10,12,16)(2,4,6,8,10,12,16,18)(2,4,6,8,10,12,16,18,20)(2,4,6,8,10,12,16,20)(2,4,6,8,10,12,18)(2,4,6,8,10,12,18,20)(2,4,6,8,10,12,20)(2,4,6,8,10,14)(2,4,6,8,10,14,16)(2,4,6,8,10,14,16,18)(2,4,6,8,10,14,16,18,20)(2,4,6,8,10,14,16,20)(2,4,6,8,10,14,18)(2,4,6,8,10,14,18,20)(2,4,6,8,10,14,20)(2,4,6,8,10,16)(2,4,6,8,10,16,18)(2,4,6,8,10,16,18,20)(2,4,6,8,10,16,20)(2,4,6,8,10,18)(2,4,6,8,10,18,20)(2,4,6,8,10,20)(2,4,6,8,12)(2,4,6,8,12,14)(2,4,6,8,12,14,16)(2,4,6,8,12,14,16,18)(2,4,6,8,12,14,16,18,20)(2,4,6,8,12,14,16,20)(2,4,6,8,12,14,18)(2,4,6,8,12,14,18,20)(2,4,6,8,12,14,20)(2,4,6,8,12,16)(2,4,6,8,12,16,18)(2,4,6,8,12,16,18,20)(2,4,6,8,12,16,20)(2,4,6,8,12,18)(2,4,6,8,12,18,20)(2,4,6,8,12,20)(2,4,6,8,14)(2,4,6,8,14,16)(2,4,6,8,14,16,18)(2,4,6,8,14,16,18,20)(2,4,6,8,14,16,20)(2,4,6,8,14,18)(2,4,6,8,14,18,20)(2,4,6,8,14,20)(2,4,6,8,16)(2,4,6,8,16,18)(2,4,6,8,16,18,20)(2,4,6,8,16,20)(2,4,6,8,18)(2,4,6,8,18,20)(2,4,6,8,20)(2,4,6,10)(2,4,6,10,12)(2,4,6,10,12,14)(2,4,6,10,12,14,16)(2,4,6,10,12,14,16,18)(2,4,6,10,12,14,16,18,20)(2,4,6,10,12,14,16,20)(2,4,6,10,12,14,18)(2,4,6,10,12,14,18,20)(2,4,6,10,12,14,20)(2,4,6,10,12,16)(2,4,6,10,12,16,18)(2,4,6,10,12,16,18,20)(2,4,6,10,12,16,20)(2,4,6,10,12,18)(2,4,6,10,12,18,20)(2,4,6,10,12,20)(2,4,6,10,14)(2,4,6,10,14,16)(2,4,6,10,14,16,18)(2,4,6,10,14,16,18,20)(2,4,6,10,14,16,20)(2,4,6,10,14,18)(2,4,6,10,14,18,20)(2,4,6,10,14,20)(2,4,6,10,16)(2,4,6,10,16,18)(2,4,6,10,16,18,20)(2,4,6,10,16,20)(2,4,6,10,18)(2,4,6,10,18,20)(2,4,6,10,20)(2,4,6,12)(2,4,6,12,14)(2,4,6,12,14,16)(2,4,6,12,14,16,18)(2,4,6,12,14,16,18,20)(2,4,6,12,14,16,20)(2,4,6,12,14,18)(2,4,6,12,14,18,20)(2,4,6,12,14,20)(2,4,6,12,16)(2,4,6,12,16,18)(2,4,6,12,16,18,20)(2,4,6,12,16,20)(2,4,6,12,18)(2,4,6,12,18,20)(2,4,6,12,20)(2,4,6,14)(2,4,6,14,16)(2,4,6,14,16,18)(2,4,6,14,16,18,20)(2,4,6,14,16,20)(2,4,6,14,18)(2,4,6,14,18,20)(2,4,6,14,20)(2,4,6,16)(2,4,6,16,18)(2,4,6,16,18,20)(2,4,6,16,20)(2,4,6,18)(2,4,6,18,20)(2,4,6,20)(2,4,8)(2,4,8,10)(2,4,8,10,12)(2,4,8,10,12,14)(2,4,8,10,12,14,16)(2,4,8,10,12,14,16,18)(2,4,8,10,12,14,16,18,20)(2,4,8,10,12,14,16,20)(2,4,8,10,12,14,18)(2,4,8,10,12,14,18,20)(2,4,8,10,12,14,20)(2,4,8,10,12,16)(2,4,8,10,12,16,18)(2,4,8,10,12,16,18,20)(2,4,8,10,12,16,20)(2,4,8,10,12,18)(2,4,8,10,12,18,20)(2,4,8,10,12,20)(2,4,8,10,14)(2,4,8,10,14,16)(2,4,8,10,14,16,18)(2,4,8,10,14,16,18,20)(2,4,8,10,14,16,20)(2,4,8,10,14,18)(2,4,8,10,14,18,20)(2,4,8,10,14,20)(2,4,8,10,16)(2,4,8,10,16,18)(2,4,8,10,16,18,20)(2,4,8,10,16,20)(2,4,8,10,18)(2,4,8,10,18,20)(2,4,8,10,20)(2,4,8,12)(2,4,8,12,14)(2,4,8,12,14,16)(2,4,8,12,14,16,18)(2,4,8,12,14,16,18,20)(2,4,8,12,14,16,20)(2,4,8,12,14,18)(2,4,8,12,14,18,20)(2,4,8,12,14,20)(2,4,8,12,16)(2,4,8,12,16,18)(2,4,8,12,16,18,20)(2,4,8,12,16,20)(2,4,8,12,18)(2,4,8,12,18,20)(2,4,8,12,20)(2,4,8,14)(2,4,8,14,16)(2,4,8,14,16,18)(2,4,8,14,16,18,20)(2,4,8,14,16,20)(2,4,8,14,18)(2,4,8,14,18,20)(2,4,8,14,20)(2,4,8,16)(2,4,8,16,18)(2,4,8,16,18,20)(2,4,8,16,20)(2,4,8,18)(2,4,8,18,20)(2,4,8,20)(2,4,10)(2,4,10,12)(2,4,10,12,14)(2,4,10,12,14,16)(2,4,10,12,14,16,18)(2,4,10,12,14,16,18,20)(2,4,10,12,14,16,20)(2,4,10,12,14,18)(2,4,10,12,14,18,20)(2,4,10,12,14,20)(2,4,10,12,16)(2,4,10,12,16,18)(2,4,10,12,16,18,20)(2,4,10,12,16,20)(2,4,10,12,18)(2,4,10,12,18,20)(2,4,10,12,20)(2,4,10,14)(2,4,10,14,16)(2,4,10,14,16,18)(2,4,10,14,16,18,20)(2,4,10,14,16,20)(2,4,10,14,18)(2,4,10,14,18,20)(2,4,10,14,20)(2,4,10,16)(2,4,10,16,18)(2,4,10,16,18,20)(2,4,10,16,20)(2,4,10,18)(2,4,10,18,20)(2,4,10,20)(2,4,12)(2,4,12,14)(2,4,12,14,16)(2,4,12,14,16,18)(2,4,12,14,16,18,20)(2,4,12,14,16,20)(2,4,12,14,18)(2,4,12,14,18,20)(2,4,12,14,20)(2,4,12,16)(2,4,12,16,18)(2,4,12,16,18,20)(2,4,12,16,20)(2,4,12,18)(2,4,12,18,20)(2,4,12,20)(2,4,14)(2,4,14,16)(2,4,14,16,18)(2,4,14,16,18,20)(2,4,14,16,20)(2,4,14,18)(2,4,14,18,20)(2,4,14,20)(2,4,16)(2,4,16,18)(2,4,16,18,20)(2,4,16,20)(2,4,18)(2,4,18,20)(2,4,20)(2,6)(2,6,8)(2,6,8,10)(2,6,8,10,12)(2,6,8,10,12,14)(2,6,8,10,12,14,16)(2,6,8,10,12,14,16,18)(2,6,8,10,12,14,16,18,20)(2,6,8,10,12,14,16,20)(2,6,8,10,12,14,18)(2,6,8,10,12,14,18,20)(2,6,8,10,12,14,20)(2,6,8,10,12,16)(2,6,8,10,12,16,18)(2,6,8,10,12,16,18,20)(2,6,8,10,12,16,20)(2,6,8,10,12,18)(2,6,8,10,12,18,20)(2,6,8,10,12,20)(2,6,8,10,14)(2,6,8,10,14,16)(2,6,8,10,14,16,18)(2,6,8,10,14,16,18,20)(2,6,8,10,14,16,20)(2,6,8,10,14,18)(2,6,8,10,14,18,20)(2,6,8,10,14,20)(2,6,8,10,16)(2,6,8,10,16,18)(2,6,8,10,16,18,20)(2,6,8,10,16,20)(2,6,8,10,18)(2,6,8,10,18,20)(2,6,8,10,20)(2,6,8,12)(2,6,8,12,14)(2,6,8,12,14,16)(2,6,8,12,14,16,18)(2,6,8,12,14,16,18,20)(2,6,8,12,14,16,20)(2,6,8,12,14,18)(2,6,8,12,14,18,20)(2,6,8,12,14,20)(2,6,8,12,16)(2,6,8,12,16,18)(2,6,8,12,16,18,20)(2,6,8,12,16,20)(2,6,8,12,18)(2,6,8,12,18,20)(2,6,8,12,20)(2,6,8,14)(2,6,8,14,16)(2,6,8,14,16,18)(2,6,8,14,16,18,20)(2,6,8,14,16,20)(2,6,8,14,18)(2,6,8,14,18,20)(2,6,8,14,20)(2,6,8,16)(2,6,8,16,18)(2,6,8,16,18,20)(2,6,8,16,20)(2,6,8,18)(2,6,8,18,20)(2,6,8,20)(2,6,10)(2,6,10,12)(2,6,10,12,14)(2,6,10,12,14,16)(2,6,10,12,14,16,18)(2,6,10,12,14,16,18,20)(2,6,10,12,14,16,20)(2,6,10,12,14,18)(2,6,10,12,14,18,20)(2,6,10,12,14,20)(2,6,10,12,16)(2,6,10,12,16,18)(2,6,10,12,16,18,20)(2,6,10,12,16,20)(2,6,10,12,18)(2,6,10,12,18,20)(2,6,10,12,20)(2,6,10,14)(2,6,10,14,16)(2,6,10,14,16,18)(2,6,10,14,16,18,20)(2,6,10,14,16,20)(2,6,10,14,18)(2,6,10,14,18,20)(2,6,10,14,20)(2,6,10,16)(2,6,10,16,18)(2,6,10,16,18,20)(2,6,10,16,20)(2,6,10,18)(2,6,10,18,20)(2,6,10,20)(2,6,12)(2,6,12,14)(2,6,12,14,16)(2,6,12,14,16,18)(2,6,12,14,16,18,20)(2,6,12,14,16,20)(2,6,12,14,18)(2,6,12,14,18,20)(2,6,12,14,20)(2,6,12,16)(2,6,12,16,18)(2,6,12,16,18,20)(2,6,12,16,20)(2,6,12,18)(2,6,12,18,20)(2,6,12,20)(2,6,14)(2,6,14,16)(2,6,14,16,18)(2,6,14,16,18,20)(2,6,14,16,20)(2,6,14,18)(2,6,14,18,20)(2,6,14,20)(2,6,16)(2,6,16,18)(2,6,16,18,20)(2,6,16,20)(2,6,18)(2,6,18,20)(2,6,20)(2,8)(2,8,10)(2,8,10,12)(2,8,10,12,14)(2,8,10,12,14,16)(2,8,10,12,14,16,18)(2,8,10,12,14,16,18,20)(2,8,10,12,14,16,20)(2,8,10,12,14,18)(2,8,10,12,14,18,20)(2,8,10,12,14,20)(2,8,10,12,16)(2,8,10,12,16,18)(2,8,10,12,16,18,20)(2,8,10,12,16,20)(2,8,10,12,18)(2,8,10,12,18,20)(2,8,10,12,20)(2,8,10,14)(2,8,10,14,16)(2,8,10,14,16,18)(2,8,10,14,16,18,20)(2,8,10,14,16,20)(2,8,10,14,18)(2,8,10,14,18,20)(2,8,10,14,20)(2,8,10,16)(2,8,10,16,18)(2,8,10,16,18,20)(2,8,10,16,20)(2,8,10,18)(2,8,10,18,20)(2,8,10,20)(2,8,12)(2,8,12,14)(2,8,12,14,16)(2,8,12,14,16,18)(2,8,12,14,16,18,20)(2,8,12,14,16,20)(2,8,12,14,18)(2,8,12,14,18,20)(2,8,12,14,20)(2,8,12,16)(2,8,12,16,18)(2,8,12,16,18,20)(2,8,12,16,20)(2,8,12,18)(2,8,12,18,20)(2,8,12,20)(2,8,14)(2,8,14,16)(2,8,14,16,18)(2,8,14,16,18,20)(2,8,14,16,20)(2,8,14,18)(2,8,14,18,20)(2,8,14,20)(2,8,16)(2,8,16,18)(2,8,16,18,20)(2,8,16,20)(2,8,18)(2,8,18,20)(2,8,20)(2,10)(2,10,12)(2,10,12,14)(2,10,12,14,16)(2,10,12,14,16,18)(2,10,12,14,16,18,20)(2,10,12,14,16,20)(2,10,12,14,18)(2,10,12,14,18,20)(2,10,12,14,20)(2,10,12,16)(2,10,12,16,18)(2,10,12,16,18,20)(2,10,12,16,20)(2,10,12,18)(2,10,12,18,20)(2,10,12,20)(2,10,14)(2,10,14,16)(2,10,14,16,18)(2,10,14,16,18,20)(2,10,14,16,20)(2,10,14,18)(2,10,14,18,20)(2,10,14,20)(2,10,16)(2,10,16,18)(2,10,16,18,20)(2,10,16,20)(2,10,18)(2,10,18,20)(2,10,20)(2,12)(2,12,14)(2,12,14,16)(2,12,14,16,18)(2,12,14,16,18,20)(2,12,14,16,20)(2,12,14,18)(2,12,14,18,20)(2,12,14,20)(2,12,16)(2,12,16,18)(2,12,16,18,20)(2,12,16,20)(2,12,18)(2,12,18,20)(2,12,20)(2,14)(2,14,16)(2,14,16,18)(2,14,16,18,20)(2,14,16,20)(2,14,18)(2,14,18,20)(2,14,20)(2,16)(2,16,18)(2,16,18,20)(2,16,20)(2,18)(2,18,20)(2,20)(4)(4,6)(4,6,8)(4,6,8,10)(4,6,8,10,12)(4,6,8,10,12,14)(4,6,8,10,12,14,16)(4,6,8,10,12,14,16,18)(4,6,8,10,12,14,16,18,20)(4,6,8,10,12,14,16,20)(4,6,8,10,12,14,18)(4,6,8,10,12,14,18,20)(4,6,8,10,12,14,20)(4,6,8,10,12,16)(4,6,8,10,12,16,18)(4,6,8,10,12,16,18,20)(4,6,8,10,12,16,20)(4,6,8,10,12,18)(4,6,8,10,12,18,20)(4,6,8,10,12,20)(4,6,8,10,14)(4,6,8,10,14,16)(4,6,8,10,14,16,18)(4,6,8,10,14,16,18,20)(4,6,8,10,14,16,20)(4,6,8,10,14,18)(4,6,8,10,14,18,20)(4,6,8,10,14,20)(4,6,8,10,16)(4,6,8,10,16,18)(4,6,8,10,16,18,20)(4,6,8,10,16,20)(4,6,8,10,18)(4,6,8,10,18,20)(4,6,8,10,20)(4,6,8,12)(4,6,8,12,14)(4,6,8,12,14,16)(4,6,8,12,14,16,18)(4,6,8,12,14,16,18,20)(4,6,8,12,14,16,20)(4,6,8,12,14,18)(4,6,8,12,14,18,20)(4,6,8,12,14,20)(4,6,8,12,16)(4,6,8,12,16,18)(4,6,8,12,16,18,20)(4,6,8,12,16,20)(4,6,8,12,18)(4,6,8,12,18,20)(4,6,8,12,20)(4,6,8,14)(4,6,8,14,16)(4,6,8,14,16,18)(4,6,8,14,16,18,20)(4,6,8,14,16,20)(4,6,8,14,18)(4,6,8,14,18,20)(4,6,8,14,20)(4,6,8,16)(4,6,8,16,18)(4,6,8,16,18,20)(4,6,8,16,20)(4,6,8,18)(4,6,8,18,20)(4,6,8,20)(4,6,10)(4,6,10,12)(4,6,10,12,14)(4,6,10,12,14,16)(4,6,10,12,14,16,18)(4,6,10,12,14,16,18,20)(4,6,10,12,14,16,20)(4,6,10,12,14,18)(4,6,10,12,14,18,20)(4,6,10,12,14,20)(4,6,10,12,16)(4,6,10,12,16,18)(4,6,10,12,16,18,20)(4,6,10,12,16,20)(4,6,10,12,18)(4,6,10,12,18,20)(4,6,10,12,20)(4,6,10,14)(4,6,10,14,16)(4,6,10,14,16,18)(4,6,10,14,16,18,20)(4,6,10,14,16,20)(4,6,10,14,18)(4,6,10,14,18,20)(4,6,10,14,20)(4,6,10,16)(4,6,10,16,18)(4,6,10,16,18,20)(4,6,10,16,20)(4,6,10,18)(4,6,10,18,20)(4,6,10,20)(4,6,12)(4,6,12,14)(4,6,12,14,16)(4,6,12,14,16,18)(4,6,12,14,16,18,20)(4,6,12,14,16,20)(4,6,12,14,18)(4,6,12,14,18,20)(4,6,12,14,20)(4,6,12,16)(4,6,12,16,18)(4,6,12,16,18,20)(4,6,12,16,20)(4,6,12,18)(4,6,12,18,20)(4,6,12,20)(4,6,14)(4,6,14,16)(4,6,14,16,18)(4,6,14,16,18,20)(4,6,14,16,20)(4,6,14,18)(4,6,14,18,20)(4,6,14,20)(4,6,16)(4,6,16,18)(4,6,16,18,20)(4,6,16,20)(4,6,18)(4,6,18,20)(4,6,20)(4,8)(4,8,10)(4,8,10,12)(4,8,10,12,14)(4,8,10,12,14,16)(4,8,10,12,14,16,18)(4,8,10,12,14,16,18,20)(4,8,10,12,14,16,20)(4,8,10,12,14,18)(4,8,10,12,14,18,20)(4,8,10,12,14,20)(4,8,10,12,16)(4,8,10,12,16,18)(4,8,10,12,16,18,20)(4,8,10,12,16,20)(4,8,10,12,18)(4,8,10,12,18,20)(4,8,10,12,20)(4,8,10,14)(4,8,10,14,16)(4,8,10,14,16,18)(4,8,10,14,16,18,20)(4,8,10,14,16,20)(4,8,10,14,18)(4,8,10,14,18,20)(4,8,10,14,20)(4,8,10,16)(4,8,10,16,18)(4,8,10,16,18,20)(4,8,10,16,20)(4,8,10,18)(4,8,10,18,20)(4,8,10,20)(4,8,12)(4,8,12,14)(4,8,12,14,16)(4,8,12,14,16,18)(4,8,12,14,16,18,20)(4,8,12,14,16,20)(4,8,12,14,18)(4,8,12,14,18,20)(4,8,12,14,20)(4,8,12,16)(4,8,12,16,18)(4,8,12,16,18,20)(4,8,12,16,20)(4,8,12,18)(4,8,12,18,20)(4,8,12,20)(4,8,14)(4,8,14,16)(4,8,14,16,18)(4,8,14,16,18,20)(4,8,14,16,20)(4,8,14,18)(4,8,14,18,20)(4,8,14,20)(4,8,16)(4,8,16,18)(4,8,16,18,20)(4,8,16,20)(4,8,18)(4,8,18,20)(4,8,20)(4,10)(4,10,12)(4,10,12,14)(4,10,12,14,16)(4,10,12,14,16,18)(4,10,12,14,16,18,20)(4,10,12,14,16,20)(4,10,12,14,18)(4,10,12,14,18,20)(4,10,12,14,20)(4,10,12,16)(4,10,12,16,18)(4,10,12,16,18,20)(4,10,12,16,20)(4,10,12,18)(4,10,12,18,20)(4,10,12,20)(4,10,14)(4,10,14,16)(4,10,14,16,18)(4,10,14,16,18,20)(4,10,14,16,20)(4,10,14,18)(4,10,14,18,20)(4,10,14,20)(4,10,16)(4,10,16,18)(4,10,16,18,20)(4,10,16,20)(4,10,18)(4,10,18,20)(4,10,20)(4,12)(4,12,14)(4,12,14,16)(4,12,14,16,18)(4,12,14,16,18,20)(4,12,14,16,20)(4,12,14,18)(4,12,14,18,20)(4,12,14,20)(4,12,16)(4,12,16,18)(4,12,16,18,20)(4,12,16,20)(4,12,18)(4,12,18,20)(4,12,20)(4,14)(4,14,16)(4,14,16,18)(4,14,16,18,20)(4,14,16,20)(4,14,18)(4,14,18,20)(4,14,20)(4,16)(4,16,18)(4,16,18,20)(4,16,20)(4,18)(4,18,20)(4,20)(6)(6,8)(6,8,10)(6,8,10,12)(6,8,10,12,14)(6,8,10,12,14,16)(6,8,10,12,14,16,18)(6,8,10,12,14,16,18,20)(6,8,10,12,14,16,20)(6,8,10,12,14,18)(6,8,10,12,14,18,20)(6,8,10,12,14,20)(6,8,10,12,16)(6,8,10,12,16,18)(6,8,10,12,16,18,20)(6,8,10,12,16,20)(6,8,10,12,18)(6,8,10,12,18,20)(6,8,10,12,20)(6,8,10,14)(6,8,10,14,16)(6,8,10,14,16,18)(6,8,10,14,16,18,20)(6,8,10,14,16,20)(6,8,10,14,18)(6,8,10,14,18,20)(6,8,10,14,20)(6,8,10,16)(6,8,10,16,18)(6,8,10,16,18,20)(6,8,10,16,20)(6,8,10,18)(6,8,10,18,20)(6,8,10,20)(6,8,12)(6,8,12,14)(6,8,12,14,16)(6,8,12,14,16,18)(6,8,12,14,16,18,20)(6,8,12,14,16,20)(6,8,12,14,18)(6,8,12,14,18,20)(6,8,12,14,20)(6,8,12,16)(6,8,12,16,18)(6,8,12,16,18,20)(6,8,12,16,20)(6,8,12,18)(6,8,12,18,20)(6,8,12,20)(6,8,14)(6,8,14,16)(6,8,14,16,18)(6,8,14,16,18,20)(6,8,14,16,20)(6,8,14,18)(6,8,14,18,20)(6,8,14,20)(6,8,16)(6,8,16,18)(6,8,16,18,20)(6,8,16,20)(6,8,18)(6,8,18,20)(6,8,20)(6,10)(6,10,12)(6,10,12,14)(6,10,12,14,16)(6,10,12,14,16,18)(6,10,12,14,16,18,20)(6,10,12,14,16,20)(6,10,12,14,18)(6,10,12,14,18,20)(6,10,12,14,20)(6,10,12,16)(6,10,12,16,18)(6,10,12,16,18,20)(6,10,12,16,20)(6,10,12,18)(6,10,12,18,20)(6,10,12,20)(6,10,14)(6,10,14,16)(6,10,14,16,18)(6,10,14,16,18,20)(6,10,14,16,20)(6,10,14,18)(6,10,14,18,20)(6,10,14,20)(6,10,16)(6,10,16,18)(6,10,16,18,20)(6,10,16,20)(6,10,18)(6,10,18,20)(6,10,20)(6,12)(6,12,14)(6,12,14,16)(6,12,14,16,18)(6,12,14,16,18,20)(6,12,14,16,20)(6,12,14,18)(6,12,14,18,20)(6,12,14,20)(6,12,16)(6,12,16,18)(6,12,16,18,20)(6,12,16,20)(6,12,18)(6,12,18,20)(6,12,20)(6,14)(6,14,16)(6,14,16,18)(6,14,16,18,20)(6,14,16,20)(6,14,18)(6,14,18,20)(6,14,20)(6,16)(6,16,18)(6,16,18,20)(6,16,20)(6,18)(6,18,20)(6,20)(8)(8,10)(8,10,12)(8,10,12,14)(8,10,12,14,16)(8,10,12,14,16,18)(8,10,12,14,16,18,20)(8,10,12,14,16,20)(8,10,12,14,18)(8,10,12,14,18,20)(8,10,12,14,20)(8,10,12,16)(8,10,12,16,18)(8,10,12,16,18,20)(8,10,12,16,20)(8,10,12,18)(8,10,12,18,20)(8,10,12,20)(8,10,14)(8,10,14,16)(8,10,14,16,18)(8,10,14,16,18,20)(8,10,14,16,20)(8,10,14,18)(8,10,14,18,20)(8,10,14,20)(8,10,16)(8,10,16,18)(8,10,16,18,20)(8,10,16,20)(8,10,18)(8,10,18,20)(8,10,20)(8,12)(8,12,14)(8,12,14,16)(8,12,14,16,18)(8,12,14,16,18,20)(8,12,14,16,20)(8,12,14,18)(8,12,14,18,20)(8,12,14,20)(8,12,16)(8,12,16,18)(8,12,16,18,20)(8,12,16,20)(8,12,18)(8,12,18,20)(8,12,20)(8,14)(8,14,16)(8,14,16,18)(8,14,16,18,20)(8,14,16,20)(8,14,18)(8,14,18,20)(8,14,20)(8,16)(8,16,18)(8,16,18,20)(8,16,20)(8,18)(8,18,20)(8,20)(10)(10,12)(10,12,14)(10,12,14,16)(10,12,14,16,18)(10,12,14,16,18,20)(10,12,14,16,20)(10,12,14,18)(10,12,14,18,20)(10,12,14,20)(10,12,16)(10,12,16,18)(10,12,16,18,20)(10,12,16,20)(10,12,18)(10,12,18,20)(10,12,20)(10,14)(10,14,16)(10,14,16,18)(10,14,16,18,20)(10,14,16,20)(10,14,18)(10,14,18,20)(10,14,20)(10,16)(10,16,18)(10,16,18,20)(10,16,20)(10,18)(10,18,20)(10,20)(12)(12,14)(12,14,16)(12,14,16,18)(12,14,16,18,20)(12,14,16,20)(12,14,18)(12,14,18,20)(12,14,20)(12,16)(12,16,18)(12,16,18,20)(12,16,20)(12,18)(12,18,20)(12,20)(14)(14,16)(14,16,18)(14,16,18,20)(14,16,20)(14,18)(14,18,20)(14,20)(16)(16,18)(16,18,20)(16,20)(18)(18,20)(20)()
Since number of elements in the set can go upto 10^5 and hence the size of the set will go upto 2^(10^5) which is huge. You can just either print it or if you want to store it , store it in a file.
It is not possible, as you pointed out yourself power set contains pow(2, size) no of elements. You need to print the entire set that can only be done by generating the set using backtracking, there is nothing better. To find sum of all subsets of a given set is however a simpler problem. If the no of elements is n, then each element in the array occurs 2^(n-1) times in the power set. Pseudo code : int sum = 0; for(int i = 0;i < n;i++){ sum += ( set[i] * ( 1 << (n-1) ) ); //pow(2, n-1) == 1 << (n-1) } cout << sum << endl; You would need a Big Integer Library for larger values of n.
C++, moving a NaN to the end of the array, when output
So, i've made a program which is able to sort arrays, and i'm trying to sort an array containing double FP's, including 2-3 random ones i enter, pos inf, neg inf and a single NaN. so for this purpose i wish to sort the NaN. So my code works, however when trying to sort the NaN, i'm unable to do so. What i'd like to do is sort it to the end, or have it put at the end of the sorted array. Is there anyway I can actually do this? Thanks in advance!!! code is as follows: int main() { int start_s = clock(); int n, k = 4, j; // k is number of elements double x = -0.0; double i = 0; double swap = 0;//used in the function as a place holder and used for swapping between other variables double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN //(1 / i) * 0 for (n = 0; n < (k - 1); n++) // for loop consists of variables and statements in order to arrange contents of array { for (j = 0; j < k - n - 1; j++) { if (a[j] > a[j + 1]) { swap = a[j]; a[j] = a[j + 1]; a[j + 1] = swap; } } } cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */ for (int i = 0; i < k; i++)// Loop up to number of elements within the array { cout << a[i] << " ";/* Output contents of array */ } cout << endl; //new line int stop_s = clock(); cout << "The execution time of this sort, is equal to: " << (stop_s - start_s) / double(CLOCKS_PER_SEC) * 1000 << " milliseconds" << endl; return 0;
Since you're in C++ land anyway, why not use it to the full. First, indeed, move the NaN's and then sort. I've taken out 'noise' from your code and produced this, it compiles and runs (edit: on gcc-4.4.3). The main difference is that the NaN's are at the beginning but they're easily skipped since you will get a pointer to the start of non-NaN's. #include <iostream> #include <algorithm> #include <math.h> int main() { int n, k = 4, j; // k is number of elements double x = -0.0; double i = 0; double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN] double *ptr; // will point at first non-NaN double // divide the list into two parts: NaN's and non-NaN's ptr = std::partition(a, a+k, isnan); // and sort 'm // EDIT: of course, start sorting _after_ the NaNs ... std::sort(ptr, a+k); cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */ for (int i = 0; i < k; i++)// Loop up to number of elements within the array { cout << a[i] << " ";/* Output contents of array */ } cout << endl; //new line return 0; }
Do a linear scan, find the NaNs, and move them to the end - by swapping. Then sort the rest. You can also fix your comparator, and check for NaN there. For the actual check see: Checking if a double (or float) is NaN in C++
you can use isnan() in cmath to check for NaNs. So, you can just change your comparison line from: if (a[j] > a[j + 1]) to: if (!std::isnan(a[j + 1]) && std::isnan(a[j]) || (a[j] > a[j + 1])) just a reminder, you need to have: #include <cmath> at the top of your code.
How to produce random numbers so that their sum is equal to given number?
I want to produce X random numbers, each from the interval <0; Y> (given Y as a maximum of each number), but there is restriction that the sum of these numbers must be equal to Z. Example: 5 Randoms numbers, each max 6 and the sum must be equal to 14, e.g: 0, 2, 6, 4, 2 Is there already a C/C++ function that could do something like that? Personally I couldn't come up with more than some ugly if-else-constucts.
Since you don't need the generated sequence to be uniform, this could be one of the possible solutions: #include <iostream> #include <vector> #include <cstdlib> int irand(int min, int max) { return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min; } int main() { int COUNT = 5, // X MAX_VAL = 6, // Y MAX_SUM = 14; // Z std::vector<int> buckets(COUNT, 0); srand(time(0)); int remaining = MAX_SUM; while (remaining > 0) { int rndBucketIdx = irand(0, COUNT-1); if (buckets[rndBucketIdx] == MAX_VAL) continue; // this bucket is already full buckets[rndBucketIdx]++; remaining--; } std::cout << "Printing sequence: "; for (size_t i = 0; i < COUNT; ++i) std::cout << buckets[i] << ' '; } which just simply divides the total sum to bunch of buckets until it's gone :) Example of output: Printing sequence: 4 4 1 0 5
NOTE: this solution was written when the question specified a "MAX SUM" parameter, implying a sum of less than that amount was equally acceptable. The question's now been edited based on the OP's comment that they meant the cumulative sum must actually hit that target. I'm not going to update this answer, but clearly it could trivially discard lesser totals at the last level of recursion. This solution does a one-time population of a vector<vector<int>> with all the possible combinations of numbers solving the input criterion, then each time a new solution is wanted it picks one of those at random and shuffles the numbers into a random order (thereby picking a permutation of the combination). It's a bit heavy weight - perhaps not suitable for the actual use that you mentioned after I'd started writing it ;-P - but it produces an even-weighted distribution, and you can easily do things like guarantee a combination won't be returned again until all other combinations have been returned (with a supporting shuffled vector of indices into the combinations). #include <iostream> #include <vector> #include <algorithm> using std::min; using std::max; using std::vector; // print solutions... void p(const vector<vector<int>>& vvi) { for (int i = 0; i < vvi.size(); ++i) { for (int j = 0; j < vvi[i].size(); ++j) std::cout << vvi[i][j] << ' '; std::cout << '\n'; } } // populate results with solutions... void f(vector<vector<int>>& results, int n, int max_each, int max_total) { if (n == 0) return; if (results.size() == 0) { for (int i = 0; i <= min(max_each, max_total); ++i) results.push_back(vector<int>(2, i)); f(results, n - 1, max_each, max_total); return; } vector<vector<int>> new_results; for (int r = 0; r < results.size(); ++r) { int previous = *(results[r].rbegin() + 1); int current_total = results[r].back(); int remaining = max_total - current_total; for (int i = 0; i <= min(previous,min(max_each, remaining)); ++i) { vector<int> v = results[r]; v.back() = i; v.push_back(current_total + i); new_results.push_back(v); } } results = new_results; f(results, n - 1, max_each, max_total); } const vector<int>& once(vector<vector<int>>& solutions) { int which = std::rand() % solutions.size(); vector<int>& v = solutions[which]; std::random_shuffle(v.begin(), v.end() - 1); return v; } int main() { vector<vector<int>> solutions; f(solutions, 5, 6, 14); std::cout << "All solution combinations...\n"; p(solutions); std::cout << "------------------\n"; std::cout << "A few sample permutations...\n"; for (int n = 1; n <= 100; ++n) { const vector<int>& o = once(solutions); for (int i = 0; i < o.size() - 1; ++i) std::cout << o[i] << ' '; std::cout << '\n'; } }
#include<iostream> #include <cstdlib> //rand () using namespace std; void main() { int random ,x=5; int max , totalMax=0 , sum=0; cout<<"Enter the total maximum number : "; cin>>totalMax; cout<<"Enter the maximum number: "; cin>>max; srand(0); for( int i=0; i<x ; i++) { random=rand()%max+1; //range from 0 to max sum+=random; if(sum>=totalMax) { sum-=random; i--; } else cout<<random<<' '; } cout<<endl<<"Reached total maximum number "<<totalMax<<endl; } I wrote this simple code I tested it using totalMax=14 and max=3 and it worked with me hope it's what you asked for
LiHo's answer looks pretty similar to my second suggestion, so I'll leave that, but here's an example of the first. It could probably be improved, but it shouldn't have any tragic bugs. Here's a live sample. #include <algorithm> #include <array> #include <random> std::random_device rd; std::mt19937 gen(rd()); constexpr int MAX = 14; constexpr int LINES = 5; int sum{}; int maxNum = 6; int minNum{}; std::array<int, LINES> nums; for (int i = 0; i < LINES; ++i) { maxNum = std::min(maxNum, MAX - sum); // e.g., after 0 0, min is 2 because only 12/14 can be filled after int maxAfterThis = maxNum * (LINES - i - 1); minNum = std::min(maxNum, std::max(minNum, MAX - sum - maxAfterThis)); std::uniform_int_distribution<> dist(minNum, maxNum); int num = dist(gen); nums[i] = num; sum += num; } std::shuffle(std::begin(nums), std::end(nums), gen); Creating that ditribution every time could potentially slow it down (I don't know), but the range has to go in the constructor, and I'm not one to say how well distributed these numbers are. However, the logic is pretty simple. Aside from that, it uses the nice, shiny C++11 <random> header. We just make sure no remaining number goes over MAX (14) and that MAX is reached by the end. minNum is the odd part, and that's due to how it progresses. It starts at zero and works its way up as needed (the second part to std::max is figuring out what would be needed if we got 6s for the rest), but we can't let it surpass maxNum. I'm open to a simpler method of calculating minNum if it exists.
Since you know how many numbers you need, generate them from the given distribution but without further conditions, store them, compute the actual sum, and scale them all up/down to get the desired sum.