Creating all possible k combinations of n items in C++ - c++

There are n people numbered from 1 to n. I have to write a code which produces and print all different combinations of k people from these n. Please explain the algorithm used for that.

I assume you're asking about combinations in combinatorial sense (that is, order of elements doesn't matter, so [1 2 3] is the same as [2 1 3]). The idea is pretty simple then, if you understand induction / recursion: to get all K-element combinations, you first pick initial element of a combination out of existing set of people, and then you "concatenate" this initial element with all possible combinations of K-1 people produced from elements that succeed the initial element.
As an example, let's say we want to take all combinations of 3 people from a set of 5 people. Then all possible combinations of 3 people can be expressed in terms of all possible combinations of 2 people:
comb({ 1 2 3 4 5 }, 3) =
{ 1, comb({ 2 3 4 5 }, 2) } and
{ 2, comb({ 3 4 5 }, 2) } and
{ 3, comb({ 4 5 }, 2) }
Here's C++ code that implements this idea:
#include <iostream>
#include <vector>
using namespace std;
vector<int> people;
vector<int> combination;
void pretty_print(const vector<int>& v) {
static int count = 0;
cout << "combination no " << (++count) << ": [ ";
for (int i = 0; i < v.size(); ++i) { cout << v[i] << " "; }
cout << "] " << endl;
}
void go(int offset, int k) {
if (k == 0) {
pretty_print(combination);
return;
}
for (int i = offset; i <= people.size() - k; ++i) {
combination.push_back(people[i]);
go(i+1, k-1);
combination.pop_back();
}
}
int main() {
int n = 5, k = 3;
for (int i = 0; i < n; ++i) { people.push_back(i+1); }
go(0, k);
return 0;
}
And here's output for N = 5, K = 3:
combination no 1: [ 1 2 3 ]
combination no 2: [ 1 2 4 ]
combination no 3: [ 1 2 5 ]
combination no 4: [ 1 3 4 ]
combination no 5: [ 1 3 5 ]
combination no 6: [ 1 4 5 ]
combination no 7: [ 2 3 4 ]
combination no 8: [ 2 3 5 ]
combination no 9: [ 2 4 5 ]
combination no 10: [ 3 4 5 ]

From Rosetta code
#include <algorithm>
#include <iostream>
#include <string>
void comb(int N, int K)
{
std::string bitmask(K, 1); // K leading 1's
bitmask.resize(N, 0); // N-K trailing 0's
// print integers and permute bitmask
do {
for (int i = 0; i < N; ++i) // [0..N-1] integers
{
if (bitmask[i]) std::cout << " " << i;
}
std::cout << std::endl;
} while (std::prev_permutation(bitmask.begin(), bitmask.end()));
}
int main()
{
comb(5, 3);
}
output
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
Analysis and idea
The whole point is to play with the binary representation of numbers
for example the number 7 in binary is 0111
So this binary representation can also be seen as an assignment list as such:
For each bit i if the bit is set (i.e is 1) means the ith item is assigned else not.
Then by simply computing a list of consecutive binary numbers and exploiting the binary representation (which can be very fast) gives an algorithm to compute all combinations of N over k.
The sorting at the end (of some implementations) is not needed. It is just a way to deterministicaly normalize the result, i.e for same numbers (N, K) and same algorithm same order of combinations is returned
For further reading about number representations and their relation to combinations, permutations, power sets (and other interesting stuff), have a look at Combinatorial number system , Factorial number system
PS: You may want to check out my combinatorics framework Abacus which computes many types of combinatorial objects efficiently and its routines (originaly in JavaScript) can be adapted easily to many other languages.

If the number of the set would be within 32, 64 or a machine native primitive size, then you can do it with a simple bit manipulation.
template<typename T>
void combo(const T& c, int k)
{
int n = c.size();
int combo = (1 << k) - 1; // k bit sets
while (combo < 1<<n) {
pretty_print(c, combo);
int x = combo & -combo;
int y = combo + x;
int z = (combo & ~y);
combo = z / x;
combo >>= 1;
combo |= y;
}
}
this example calls pretty_print() function by the dictionary order.
For example. You want to have 6C3 and assuming the current 'combo' is 010110.
Obviously the next combo MUST be 011001.
011001 is :
010000 | 001000 | 000001
010000 : deleted continuously 1s of LSB side.
001000 : set 1 on the next of continuously 1s of LSB side.
000001 : shifted continuously 1s of LSB to the right and remove LSB bit.
int x = combo & -combo;
this obtains the lowest 1.
int y = combo + x;
this eliminates continuously 1s of LSB side and set 1 on the next of it (in the above case, 010000 | 001000)
int z = (combo & ~y)
this gives you the continuously 1s of LSB side (000110).
combo = z / x;
combo >> =1;
this is for 'shifted continuously 1s of LSB to the right and remove LSB bit'.
So the final job is to OR y to the above.
combo |= y;
Some simple concrete example :
#include <bits/stdc++.h>
using namespace std;
template<typename T>
void pretty_print(const T& c, int combo)
{
int n = c.size();
for (int i = 0; i < n; ++i) {
if ((combo >> i) & 1)
cout << c[i] << ' ';
}
cout << endl;
}
template<typename T>
void combo(const T& c, int k)
{
int n = c.size();
int combo = (1 << k) - 1; // k bit sets
while (combo < 1<<n) {
pretty_print(c, combo);
int x = combo & -combo;
int y = combo + x;
int z = (combo & ~y);
combo = z / x;
combo >>= 1;
combo |= y;
}
}
int main()
{
vector<char> c0 = {'1', '2', '3', '4', '5'};
combo(c0, 3);
vector<char> c1 = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
combo(c1, 4);
return 0;
}
result :
1 2 3
1 2 4
1 3 4
2 3 4
1 2 5
1 3 5
2 3 5
1 4 5
2 4 5
3 4 5
a b c d
a b c e
a b d e
a c d e
b c d e
a b c f
a b d f
a c d f
b c d f
a b e f
a c e f
b c e f
a d e f
b d e f
c d e f
a b c g
a b d g
a c d g
b c d g
a b e g
a c e g
b c e g
a d e g
b d e g
c d e g
a b f g
a c f g
b c f g
a d f g
b d f g
c d f g
a e f g
b e f g
c e f g
d e f g

In Python, this is implemented as itertools.combinations
https://docs.python.org/2/library/itertools.html#itertools.combinations
In C++, such combination function could be implemented based on permutation function.
The basic idea is to use a vector of size n, and set only k item to 1 inside, then all combinations of nchoosek could obtained by collecting the k items in each permutation.
Though it might not be the most efficient way require large space, as combination is usually a very large number. It's better to be implemented as a generator or put working codes into do_sth().
Code sample:
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
int main(void) {
int n=5, k=3;
// vector<vector<int> > combinations;
vector<int> selected;
vector<int> selector(n);
fill(selector.begin(), selector.begin() + k, 1);
do {
for (int i = 0; i < n; i++) {
if (selector[i]) {
selected.push_back(i);
}
}
// combinations.push_back(selected);
do_sth(selected);
copy(selected.begin(), selected.end(), ostream_iterator<int>(cout, " "));
cout << endl;
selected.clear();
}
while (prev_permutation(selector.begin(), selector.end()));
return 0;
}
and the output is
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
This solution is actually a duplicate with
Generating combinations in c++

Here is an algorithm i came up with for solving this problem. You should be able to modify it to work with your code.
void r_nCr(const unsigned int &startNum, const unsigned int &bitVal, const unsigned int &testNum) // Should be called with arguments (2^r)-1, 2^(r-1), 2^(n-1)
{
unsigned int n = (startNum - bitVal) << 1;
n += bitVal ? 1 : 0;
for (unsigned int i = log2(testNum) + 1; i > 0; i--) // Prints combination as a series of 1s and 0s
cout << (n >> (i - 1) & 1);
cout << endl;
if (!(n & testNum) && n != startNum)
r_nCr(n, bitVal, testNum);
if (bitVal && bitVal < testNum)
r_nCr(startNum, bitVal >> 1, testNum);
}
You can see an explanation of how it works here.

I have written a class in C# to handle common functions for working with the binomial coefficient, which is the type of problem that your problem falls under. It performs the following tasks:
Outputs all the K-indexes in a nice format for any N choose K to a file. The K-indexes can be substituted with more descriptive strings or letters. This method makes solving this type of problem quite trivial.
Converts the K-indexes to the proper index of an entry in the sorted binomial coefficient table. This technique is much faster than older published techniques that rely on iteration. It does this by using a mathematical property inherent in Pascal's Triangle. My paper talks about this. I believe I am the first to discover and publish this technique.
Converts the index in a sorted binomial coefficient table to the corresponding K-indexes. I believe it is also faster than the other solutions.
Uses Mark Dominus method to calculate the binomial coefficient, which is much less likely to overflow and works with larger numbers.
The class is written in .NET C# and provides a way to manage the objects related to the problem (if any) by using a generic list. The constructor of this class takes a bool value called InitTable that when true will create a generic list to hold the objects to be managed. If this value is false, then it will not create the table. The table does not need to be created in order to perform the 4 above methods. Accessor methods are provided to access the table.
There is an associated test class which shows how to use the class and its methods. It has been extensively tested with 2 cases and there are no known bugs.
To read about this class and download the code, see Tablizing The Binomial Coeffieicent.
It should be pretty straight forward to port the class over to C++.
The solution to your problem involves generating the K-indexes for each N choose K case. For example:
int NumPeople = 10;
int N = TotalColumns;
// Loop thru all the possible groups of combinations.
for (int K = N - 1; K < N; K++)
{
// Create the bin coeff object required to get all
// the combos for this N choose K combination.
BinCoeff<int> BC = new BinCoeff<int>(N, K, false);
int NumCombos = BinCoeff<int>.GetBinCoeff(N, K);
int[] KIndexes = new int[K];
BC.OutputKIndexes(FileName, DispChars, "", " ", 60, false);
// Loop thru all the combinations for this N choose K case.
for (int Combo = 0; Combo < NumCombos; Combo++)
{
// Get the k-indexes for this combination, which in this case
// are the indexes to each person in the problem set.
BC.GetKIndexes(Loop, KIndexes);
// Do whatever processing that needs to be done with the indicies in KIndexes.
...
}
}
The OutputKIndexes method can also be used to output the K-indexes to a file, but it will use a different file for each N choose K case.

This templated function works with the vector of any type as an input.
Combinations are returned as a vector of vectors.
/*
* Function return all possible combinations of k elements from N-size inputVector.
* The result is returned as a vector of k-long vectors containing all combinations.
*/
template<typename T> std::vector<std::vector<T>> getAllCombinations(const std::vector<T>& inputVector, int k)
{
std::vector<std::vector<T>> combinations;
std::vector<int> selector(inputVector.size());
std::fill(selector.begin(), selector.begin() + k, 1);
do {
std::vector<int> selectedIds;
std::vector<T> selectedVectorElements;
for (int i = 0; i < inputVector.size(); i++) {
if (selector[i]) {
selectedIds.push_back(i);
}
}
for (auto& id : selectedIds) {
selectedVectorElements.push_back(inputVector[id]);
}
combinations.push_back(selectedVectorElements);
} while (std::prev_permutation(selector.begin(), selector.end()));
return combinations;
}

You can use the "count_each_combination" and "for_each_combination" functions from the combinations library from Howard Hinnant to generate all the combinations for take k from n.
#include <vector>
#include "combinations.h"
std::vector<std::vector<u_int8_t> >
combinationsNoRepetitionAndOrderDoesNotMatter (long int subsetSize, std::vector<uint8_t> setOfNumbers)
{
std::vector<std::vector<u_int8_t> > subsets{};
subsets.reserve (count_each_combination (setOfNumbers.begin (), setOfNumbers.begin () + subsetSize, setOfNumbers.end ()));
for_each_combination (setOfNumbers.begin (), setOfNumbers.begin () + subsetSize, setOfNumbers.end (), [&subsets] (auto first, auto last) {
subsets.push_back (std::vector<uint8_t>{ first, last });
return false;
});
return subsets;
}
int main(){
combinationsNoRepetitionAndOrderDoesNotMatter (6, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 });
}
Benchmark on a Intel(R) Core(TM) i5-8600K CPU # 3.60GHz:
g++
benchmark name samples iterations estimated
mean low mean high mean
std dev low std dev high std dev
-------------------------------------------------------------------------------
combinations no repetition and
order does not matter 6 from 36 100 1 10.2829 s
92.5451 ms 92.3971 ms 92.9411 ms
1.15617 ms 532.604 us 2.48342 ms
clang++
benchmark name samples iterations estimated
mean low mean high mean
std dev low std dev high std dev
-------------------------------------------------------------------------------
combinations no repetition and
order does not matter 6 from 36 100 1 11.0786 s
88.1275 ms 87.8212 ms 89.3204 ms
2.82107 ms 400.665 us 6.67526 ms

Behind the link below is a generic C# answer to this problem: How to format all combinations out of a list of objects. You can limit the results only to the length of k pretty easily.
https://stackoverflow.com/a/40417765/2613458

It can also be done using backtracking by maintaining a visited array.
void foo(vector<vector<int> > &s,vector<int> &data,int go,int k,vector<int> &vis,int tot)
{
vis[go]=1;
data.push_back(go);
if(data.size()==k)
{
s.push_back(data);
vis[go]=0;
data.pop_back();
return;
}
for(int i=go+1;i<=tot;++i)
{
if(!vis[i])
{
foo(s,data,i,k,vis,tot);
}
}
vis[go]=0;
data.pop_back();
}
vector<vector<int> > Solution::combine(int n, int k) {
vector<int> data;
vector<int> vis(n+1,0);
vector<vector<int> > sol;
for(int i=1;i<=n;++i)
{
for(int i=1;i<=n;++i) vis[i]=0;
foo(sol,data,i,k,vis,n);
}
return sol;
}

I thought my simple "all possible combination generator" might help someone, i think its a really good example for building something bigger and better
you can change N (characters) to any you like by just removing/adding from string array (you can change it to int as well). Current amount of characters is 36
you can also change K (size of the generated combinations) by just adding more loops, for each element, there must be one extra loop. Current size is 4
#include<iostream>
using namespace std;
int main() {
string num[] = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z" };
for (int i1 = 0; i1 < sizeof(num)/sizeof(string); i1++) {
for (int i2 = 0; i2 < sizeof(num)/sizeof(string); i2++) {
for (int i3 = 0; i3 < sizeof(num)/sizeof(string); i3++) {
for (int i4 = 0; i4 < sizeof(num)/sizeof(string); i4++) {
cout << num[i1] << num[i2] << num[i3] << num[i4] << endl;
}
}
}
}}
Result
0: A A A
1: B A A
2: C A A
3: A B A
4: B B A
5: C B A
6: A C A
7: B C A
8: C C A
9: A A B
...
just keep in mind that the amount of combinations can be ridicules.
--UPDATE--
a better way to generate all possible combinations would be with this code, which can be easily adjusted and configured in the "variables" section of the code.
#include<iostream>
#include<math.h>
int main() {
//VARIABLES
char chars[] = { 'A', 'B', 'C' };
int password[4]{0};
//SIZES OF VERIABLES
int chars_length = sizeof(chars) / sizeof(char);
int password_length = sizeof(password) / sizeof(int);
//CYCKLE TROUGH ALL OF THE COMBINATIONS
for (int i = 0; i < pow(chars_length, password_length); i++){
//CYCKLE TROUGH ALL OF THE VERIABLES IN ARRAY
for (int i2 = 0; i2 < password_length; i2++) {
//IF VERIABLE IN "PASSWORD" ARRAY IS THE LAST VERIABLE IN CHAR "CHARS" ARRRAY
if (password[i2] == chars_length) {
//THEN INCREMENT THE NEXT VERIABLE IN "PASSWORD" ARRAY
password[i2 + 1]++;
//AND RESET THE VERIABLE BACK TO ZERO
password[i2] = 0;
}}
//PRINT OUT FIRST COMBINATION
std::cout << i << ": ";
for (int i2 = 0; i2 < password_length; i2++) {
std::cout << chars[password[i2]] << " ";
}
std::cout << "\n";
//INCREMENT THE FIRST VERIABLE IN ARRAY
password[0]++;
}}

To make it more complete, the following answer covers the case that the data set contains duplicate values. The function is written close to the style of std::next_permutation() so that it is easy to follow up.
template< class RandomIt >
bool next_combination(RandomIt first, RandomIt n_first, RandomIt last)
{
if (first == last || n_first == first || n_first == last)
{
return false;
}
RandomIt it_left = n_first;
--it_left;
RandomIt it_right = n_first;
bool reset = false;
while (true)
{
auto it = std::upper_bound(it_right, last, *it_left);
if (it != last)
{
std::iter_swap(it_left, it);
if (reset)
{
++it_left;
it_right = it;
++it_right;
std::size_t left_len = std::distance(it_left, n_first);
std::size_t right_len = std::distance(it_right, last);
if (left_len < right_len)
{
std::swap_ranges(it_left, n_first, it_right);
std::rotate(it_right, it_right+left_len, last);
}
else
{
std::swap_ranges(it_right, last, it_left);
std::rotate(it_left, it_left+right_len, n_first);
}
}
return true;
}
else
{
reset = true;
if (it_left == first)
{
break;
}
--it_left;
it_right = n_first;
}
}
return false;
}
The full data set is represented in the range [first, last). The current combination is represented in the range [first, n_first) and the range [n_first, last) holds the complement set of the current combination.
As a combination is irrelevant to its order, [first, n_first) and [n_first, last) are kept in ascending order to avoid duplication.
The algorithm works by increasing the last value A on the left side by swapping with the first value B on the right side that is greater than A. After the swapping, both sides are still ordered. If no such value B exists on the right side, then we start to consider increasing the second last on the left side until all values on the left side are not less than the right side.
An example of drawing 2 elements from a set by the following code:
std::vector<int> seq = {1, 1, 2, 2, 3, 4, 5};
do
{
for (int x : seq)
{
std::cout << x << " ";
}
std::cout << "\n";
} while (next_combination(seq.begin(), seq.begin()+2, seq.end()));
gives:
1 1 2 2 3 4 5
1 2 1 2 3 4 5
1 3 1 2 2 4 5
1 4 1 2 2 3 5
1 5 1 2 2 3 4
2 2 1 1 3 4 5
2 3 1 1 2 4 5
2 4 1 1 2 3 5
2 5 1 1 2 3 4
3 4 1 1 2 2 5
3 5 1 1 2 2 4
4 5 1 1 2 2 3
It is trivial to retrieve the first two elements as the combination result if needed.

The basic idea of this solution is to mimic the way you enumerate all the combinations without repetitions by hand in high school. Let com be List[int] of length k and nums be List[int] the given n items, where n >= k.
The idea is as follows:
for x[0] in nums[0,...,n-1]
for x[1] in nums[idx_of_x[0] + 1,..,n-1]
for x[2] in nums [idx_of_x[1] + 1,...,n-1]
..........
for x[k-1] in nums [idx_of_x[k-2]+1, ..,n-1]
Obviously, k and n are variable arguments, which makes it impossible to write explicit multiple nested for-loops. This is where the recursion comes to rescue the issue.
Statement len(com) + len(nums[i:]) >= k checks whether the remaining unvisited forward list of items can provide k iitems. By forward, I mean you should not walk the nums backward for avoiding the repeated combination, which consists of same set of items but in different order. Put it in another way, in these different orders, we can choose the order these items appear in the list by scaning the list forward. More importantly, this test clause internally prunes the recursion tree such that it only contains n choose k recursive calls. Hence, the running time is O(n choose k).
from typing import List
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
assert 1 <= n <= 20
assert 1 <= k <= n
com_sets = []
self._combine_recurse(k, list(range(1, n+1)), [], com_sets)
return com_sets
def _combine_recurse(self, k: int, nums: List[int], com: List[int], com_set: List[List[int]]):
"""
O(C_n^k)
"""
if len(com) < k:
for i in range(len(nums)):
# Once again, don't com.append() since com should not be global!
if len(com) + len(nums[i:]) >= k:
self._combine_recurse(k, nums[i+1:], com + [nums[i]], com_set)
else:
if len(com) == k:
com_set.append(com)
print(com)
sol = Solution()
sol.combine(5, 3)
[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]

Try this:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void combo(vector<char> &alphabet, int n, vector<string> &result, string curr) {
if (n == 0) {
result.push_back(curr);
return;
}
for (int i = 0; i < alphabet.size(); i++) {
combo(alphabet, n - 1, result, curr + alphabet[i]);
}
return;
}
int main() {
//N items
vector<char> alphabet = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n','o','p','q','r','s','t','u','v','w','x','y','z'};
vector<string> result;
//K is 4
combo(alphabet, 4, result, "");
for (auto s : result) {
cout << s << endl;
}
return 0;
}

Related

How to make my code about 'arithmetic substrings' work quicker

I have some problems with code for my classes. Even though it works correctly, I run out of time for half of the examples.
Here's the task (I really did my best trying to translate it):
You have a permutation of numbers 1,2,...,n for some n. All consecutive numbers of permutations together create sequence a1, a2, an. Your task is to count, how many arithmetic substrings of a sequence of length 3 exist.
Input:
In first line there is a number n (1 <= n <= 200 000). In the second line there is n numbers a1, a2...an representing our permutation.
Output:
The program needs to print out amount of arithmetic substrings of length 3 for permutations from entry. You can assume that the result won't be bigger than 1 000 000.
Is there any way to make it work faster? Thanks for help!
#include <iostream>
using namespace std;
int main()
{
int input_length;
cin >> input_length;
int correct_sequences = 0;
bool* whether_itroduced = new bool[input_length + 1]{0}; // true - if number was already introduced and false otherwise.
for (int i = 0; i < input_length; i++)
{
int a;
cin >> a;
whether_itroduced[a] = true;
int range = min(input_length - a, a - 1); // max or min number that may be in the subsequence e.g. if introduced number a = 3, and all numbers are six, max range is 2 (3 - 2 = 1 and 3 + 2 = 5, so the longest possible subsequence is 1, 3, 5)
for (int r = range * -1; r <= range; r++) // r - there is a formula used to count arithmetic sequences -> an-1 = a1-r, an = a1, an+1 = a1+r, I have no idea how to explain it
{
if (r == 0) continue; // r cannot be 0
if (whether_itroduced[a - r] && !whether_itroduced[a + r])
correct_sequences++;
}
}
cout << correct_sequences;
}
example
input:
5
1 5 4 2 3
output:
2
// 1,2,3 and 5,4,3

Printing n pairs of prime numbers, C++

I need to write a program which is printing n pairs of prime numbers and the those pairs are :
p q
where p and q are prime numbers and q = p+2.
Input example :
n = 3
3 5 //
5 7 //
11 13 //
I'm pretty much nowhere still... So, someone?
#include <iostream>
#include <cmath>
int twins(int n)
{
for (int i = 0; i < n; i++)
{
???
}
}
int main()
{
std::cout<<twins(5);
return 0;
}
Here is the top-level simple pseudo-code for such a beast:
def printTwinPrimes(count):
currNum = 3
while count > 0:
if isPrime(currNum) and isPrime(currNum + 2):
print currnum, currnum + 2
count = count - 1
currNum = currNum + 2
It simply starts at 3 (since we know 2,4 is impossible as a twin-prime pair because 4 is composite). For each possibility, it checks whether it constitutes a twin-prime pair and prints it if so.
So all you need to do (other than translating that into real code) is to create isPrime(), for which there are countless examples on the net.
For completeness, here's a simple one, by no means the most efficient but adequate for beginners:
def isPrime(num):
if num < 2:
return false
root = 2
while root * root <= num:
if num % root == 0:
return false
root = root + 1
return true
Though you could make that more efficient by using the fact that all primes other than two or three are of the form 6n±1, n >= 1(a):
def isPrime(num):
if num < 2: return false
if num == 2 or num == 3: return true
if num % 2 == 0 or num % 3 == 0: return false
if num % 6 is neither 1 nor 5: return false
root = 5
adder = 2 # initial adder 2, 5 -> 7
while root * root <= num:
if num % root == 0:
return false
root = root + adder # checks 5, 7, 11, 13, 17, 19, ...
adder = 6 - adder # because alternate 2, 4 to give 6n±1
return true
In fact, you can use this divisibility trick to see if an arbitraily large number stored as a string is likely to be a prime. You just have to check if the number below it or above it is divisible by six. If not, the number is definitely not a prime. If so, more (slower) checks will be needed to fully ascertain primality.
A number is divisible by six only if it is divisible by both two and three. It's easy to tell the former, even numbers end with an even digit.
But it's also reasonably easy to tell if it's divisible by three since, in that case, the sum of the individual digits will also be divisible by three. For example, lets' use 31415926535902718281828459.
The sum of all those digits is 118. How do we tell if that's a multiple of three? Why, using exactly the same trick recursively:
118: 1 + 1 + 8 = 10
10: 1 + 0 = 1
Once you're down to a single digit, it'll be 0, 3, 6, or 9 if the original number was a multiple of three. Any other digit means it wasn't (such as in this case).
(a) If you divide any non-negative number by six and the remainder is 0, 2 or 4, then it's even and therefore non-prime (2 is the exception case here):
6n + 0 = 2(3n + 0), an even number.
6n + 2 = 2(3n + 1), an even number.
6n + 4 = 2(3n + 2), an even number.
If the remainder is 3, then it is divisible by 3 and therefore non-prime (3 is the exception case here):
6n + 3 = 3(2n + 1), a multiple of three.
That leaves just the remainders 1 and 5, and those numbers are all of that form 6n±1.
Might not be the most efficient but you can calculate all primes till n, store them in a vector then only print those which have a difference of 2
#include <iostream>
#include<vector>
using namespace std;
void pr(int n, vector<int>& v)
{
for (int i=2; i<n; i++)
{
bool prime=true;
for (int j=2; j*j<=i; j++)
{
if (i % j == 0)
{
prime=false;
break;
}
}
if(prime) v.push_back(i);
}
}
int main()
{
vector<int> v;
pr(50, v);
for(int i = 0;i < v.size()-1; i++) {
if(v[i+1]-v[i] == 2) {
cout << v[i+1] << " " << v[i] << endl;
}
}
return 0;
}
I think is the efficient algo for you and easy to understand. You can change the value of k as per your constraints.
#include <iostream>
#include <cstring>
using namespace std;
int n,p=2,savePrime=2,k=100000;
void printNPrime(int n)
{
bool prime[k];
memset(prime, true, sizeof(prime));
while(n>0)
{
if (prime[p] == true)
{
if(p-savePrime == 2)
{
cout<<savePrime<<" "<<p<<endl;
n--;
}
// Update all multiples of p
for (int i=p*2; i<=k; i += p)
prime[i] = false;
savePrime=p;
}
p++;
}
}
int main() {
cin>>n;
printNPrime(n);
return 0;
}

Algorithm for Combinations of given numbers with repetition? C++

So I N - numbers I have to input, and I got M - numbers of places for those numbers and I need to find all combinations with repetition of given numbers.
Here is example:
Let's say that N is 3(I Have to input 3 numbers), and M is 4.
For example let's input numbers: 6 11 and 533.
This should be result
6,6,6,6
6,6,6,11
6,6,6,533
6,6,11,6
...
533,533,533,533
I know how to do that manualy when I know how much is N and M:
In example where N is 3 and M is 4:
int main()
{
int N = 3;
int M = 4;
int *numbers = new int[N + 1];
for (int i = 0; i < N; i++)
cin >> numbers[i];
for (int a = 0; a < N; a++)
for (int b = 0; b < N; b++)
for (int c = 0; c < N; c++)
for (int d = 0; d < N; d++)
{
cout << numbers[a] << " " << numbers[b] << " " << numbers[c] << " " << numbers[d] << endl;
}
return 0;
}
But how can I make algorithm so I can enter N and M via std::cin and I get correct resut?
Thanks.
First one short tip: don't use "new" or C-style arrays in C++ when we have RAII and much faster data structures.
For the solution to your problem I would suggest making separate function with recursion. You said you know how to do it manually so the first step in making it into algorithm is to tear down you manual solution step by step. For this problem when you solve it by hand you basically start with array of all first numbers and then for last position you just loop through available numbers. Then you go to the second last position and again loop through available numbers just now with the difference that for every number there you must also repeat the last spot number loop. Here is the recursion. For every "n"th position you must loop through available numbers and for every call the same function for "n+1"th number.
Here is a simplified solution, leaving out the input handling and exact print to keep code shorter and more focused on the problem:
#include <vector>
#include <iostream>
void printCombinations(const std::vector<int>& numbers, unsigned size, std::vector<int>& line) {
for (unsigned i = 0; i < numbers.size(); i++) {
line.push_back(numbers[i]);
if (size <= 1) { // Condition that prevents infinite loop in recursion
for (const auto& j : line)
std::cout << j << ","; // Simplified print to keep code shorter
std::cout << std::endl;
line.erase(line.end() - 1);
} else {
printCombinations(numbers, size - 1, line); // Recursion happens here
line.erase(line.end() - 1);
}
}
}
int main() {
std::vector<int> numbers = {6, 11, 533};
unsigned size = 4;
std::vector<int> line;
printCombinations(numbers, size, line);
return 0;
}
If you have any questions feel free to ask.
Totally there is no need for recursion here. This is a typical job for dynamic programming. Just get the first solution right for n = 1 (1 slot is available) which means the answer is [[6],[11],[533]] and then move on one by one by relying on the one previously memoized solution.
Sorry that i am not fluent in C, yet in JS this is the solution. I hope it helps.
function combosOfN(a,n){
var res = {};
for(var i = 1; i <= n; i++) res[i] = res[i-1] ? res[i-1].reduce((r,e) => r.concat(a.map(n => e.concat(n))),[])
: a.map(e => [e]);
return res[n];
}
var arr = [6,11,533],
n = 4;
console.log(JSON.stringify(combosOfN(arr,n)));
Normally the easiest way to do dynamic nested for loops is to create your own stack and use recursion.
#include <iostream>
#include <vector>
void printCombinations(int sampleCount, const std::vector<int>& options, std::vector<int>& numbersToPrint) {
if (numbersToPrint.size() == sampleCount) {
// got all the numbers we need, print them.
for (int number : numbersToPrint) {
std::cout << number << " ";
}
std::cout << "\n";
}
else {
// Add a new number, iterate over all possibilities
numbersToPrint.push_back(0);
for (int number : options) {
numbersToPrint.back() = number;
printCombinations(sampleCount, options, numbersToPrint);
}
numbersToPrint.pop_back();
}
}
void printCombinations(int sampleCount, const std::vector<int>& options) {
std::vector<int> stack;
printCombinations(sampleCount, options, stack);
}
int main()
{
printCombinations(3, {1,2,3});
}
output
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Here is an algorithm to solve this, that does't use recursion.
Let's say n=2 and m=3. Consider the following sequence that corresponds to these values:
000
001
010
011
100
101
110
111
The meaning of this is that when you see a 0 you take the first number, and when you see a 1 you take the second number. So given the input numbers [5, 7], then 000 = 555, 001=557, 010=575 etc.
The sequence above looks identical to representing numbers from 0 to 7 in base 2. Basically, if you go from 0 to 7 and represent the numbers in base 2, you have the sequence above.
If you take n=3, m=4 then you need to work in base 3:
0000
0001
0002
0010
0011
0012
....
So you go over all the numbers from 0 to 63 (4^3-1), represent them in base 3 and follow the coding: 0 = first number, 1 = second number, 2 = third number and 3 = fourth number.
For the general case, you go from 0 to M^N-1, represent each number in base N, and apply the coding 0 = first number, etc.
Here is some sample code:
#include <stdio.h>
#include <math.h>
void convert_to_base(int number, char result[], int base, int number_of_digits) {
for (int i = number_of_digits - 1; i >= 0; i--) {
int remainder = number % base;
number = number / base;
result[i] = '0' + remainder;
}
}
int main() {
int n = 2, m = 3;
int num = pow(n, m) - 1;
for (int i = 0; i <= num; i++) {
char str[33];
convert_to_base(i, str, n, m);
printf("%s\n", str);
}
return 0;
}
Output:
000
001
010
011
100
101
110
111

Maximum value of M digits out of N digits [duplicate]

This question already has answers here:
How to get the least number after deleting k digits from the input number
(11 answers)
Closed 6 years ago.
I am trying to code a program that can do something like this:
in:
5 4
1 9 9 9 0
out:
9990
and i have a problem. It doesnt work on any set of numbers. For example it works for the one above, but it doesnt work for this one:
in:
15 9
2 9 3 6 5 8 8 8 8 7 2 2 8 1 4
out: 988887814
2 9 3 6 5 8 8 8 8 7 2 2 8 1 4
I did this with a vector approach and it works for any set of numbers, but i'm trying to do it a stack for a better complexity.
EDIT ---- MODIFIED FOR STD::STACK
Code for method using stack:
#include <iostream>
#include <fstream>
#include <stack>
using namespace std;
ifstream in("trompeta.in");
ofstream out("trompeta.out");
void reverseStack(stack<char> st) {
if(!st.empty())
{
char x = st.top();
st.pop();
reverseStack(st);
out<<x;
}
return;
}
int main()
{
int n,m,count=1;
stack <char> st;
char x;
in>>n>>m;
in>>x;
st.push(x);
for(int i=1; i<n; i++)
{
in>>x;
if(st.top()<x && count+n-i-1>=m)
{
st.pop();
st.push(x);
}
else
{
st.push(x);
count++;
if (count>m-1) break;
}
};
reverseStack(st);
}
Code for method using vectors:
#include <iostream>
#include <fstream>
using namespace std;
ifstream in ( "trompeta.in" );
ofstream out ( "trompeta.out" );
int main ()
{
int i = 0, N, M, max, j, p = 0, var;
in >> N >> M;
char* v = new char[N];
char* a = new char[M];
in >> v;
var = M;
max = v[0];
for ( i = 0; i < M; i++ )
{
for ( j = p ; j < N-var+1; j++ )
{
if ( v[j] > max )
{
max = v[j];
p = j;
}
}
var--;
a[i] = max;
max = v[p+1];
p = p+1;
}
for ( i = 0; i < M; i++ )
out << a[i]-'0';
}
Can any1 help me to get the STACK code working?
Using the fact that the most significant digit completely trumps all other digets except in place of a tie, I would look at the first (N-M+1) digits, find the largest single digit in that range.
If it occurs once, the first digit is locked in. Discard the digits which occur prior to that position, and you repeat for "maximum value of M-1 numbers of out N-position" to find the remaining digits of the answer. (or N-position-1, if position is zero based)
If it occurs multiple times, then recursively find "maximum value of M-1 numbers out of N-position" for each, then select the largest single result from these. There can be at most N such matches.
I forgot to mention, if N==M, you are also done.
proof of recursion:
Computing the value of the sub-match will always select M-1 digits. When M is 1, you only need to select the largest of a few positions, and have no more recursion. This is true for both cases. Also the "select from" steps always contain no more than N choices, because they are always based on selecting one most significant digit.
------------------ how you might do it with a stack ----------------
An actual implementation using a stack would be based on an object which contains the entire state of the problem, at each step, like so:
struct data { // require: n == digits.size()
int n, m;
std::string digits;
bool operator<(const data &rhs){ return digits < rhs.digits; }
};
The point of this is not just to store the original problem, but to have a way to represent any subproblem, which you can push and pop on a stack. The stack itself is not really important, here, because it is used to pick the one best result within a specific layer. Recursion handles most of the work.
Here is the top level function which hides the data struct:
std::string select_ordered_max(int n, int m, std::string digits) {
if (n < m || (int)digits.size() != n)
return "size wrong";
data d{ n, m, digits };
data answer = select_ordered_max(d);
return answer.digits;
}
and a rough pseudocode of the recursive workhorse
data select_ordered_max(data original){
// check trivial return conditions
// determine char most_significant
// push all subproblems that satisfy most_significant
//(special case where m==1)
// pop subproblems, remembering best
return answer {original.m, original.m, std::string(1, most_significant) + best_submatch.digits };
}
String comparison works on numbers when you only compare strings of the exact same length, which is the case here.
Yes, I know having n and m is redundant with digits.size(), but I didn't want to work too hard. Including it twice simplified some recursion checks. The actual implementation only pushed a candidate to the stack if it passed the max digit check for that level of recursion. This allowed me to get the correct 9 digit answer from 15 digits of input with only 28 candidates pushed to the stack (and them popped during max-select).
Now your code has quite a few issues, but rather than focusing on those lets answer the question. Let's say that your code has been corrected to give us:
const size_t M where M is the number of digits expected in our output
const vector<int> v which is the input set of numbers of size N
You just always want to pick the highest value most significant number remaining. So we'll keep an end iterator to prevent us from picking a digit that wouldn't leave us with enough digits to finish the number, and use max_element to select:
const int pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
auto maximum = 0;
auto end = prev(cend(v), M - 1);
auto it = max_element(cbegin(v), end);
for (auto i = M - 1; i > 0; --i) {
maximum += *it * pow10[i];
advance(end, 1);
it = max_element(next(it), end);
}
maximum += *it;
Live Example
This code depends upon M being greater than 0 and less than N and less than log10(numeric_limits<int>::max())
EDIT: Sad to say this solves the consecutive digits problem, after edits the question wants subsequent digits, but not necessarily consecutive
So the little known numeric library provides inner_product which seems like just the tool for this job. Now your code has quite a few issues, but rather than focusing on those lets answer the question. Let's say that your code has been corrected to give us:
vector<int> foo(M) where M is the number of digits expected in our output
const vector<int> v which is the input set of numbers of size N
We'll use foo in the inner_product, initializing it with decreasing powers of 10:
generate(begin(foo), end(foo), [i=int{1}]() mutable {
auto result = i;
i *= 10;
return result; });
We can then use this in a loop:
auto maximum = 0;
for (auto it = prev(rend(v), size(foo) + 1); it != rbegin(v); advance(it, -1)) {
maximum = max<int>(inner_product(cbegin(foo), cend(foo), it, 0), maximum);
}
maximum = max<int>(inner_product(cbegin(foo), cend(foo), rbegin(v), 0), maximum);
Live Example
To use it's initialization requires that your initial M was smaller than N, so you may want to assert that or something.
--EDITED--
here's my suggestion with STACK based on my previous suggestion using vector
findMaxValueOutOfNDigits(stackInput, M, N)
{
// stackInput = [2, 9, 3, 6, 5, 8, 8, 8, 8, 7, 2, 2, 8, 1, 4]
// *where 4 was the first element to be inserted and 2 was the last to be inserted
// if the sequence is inverted, you can quickly fix it by doing a "for x = 0; x < stack.length; x++ { newStack.push(stack.pop()) }"
currentMaxValue = 0
for i = 0; i < (M - N + 1); i++
{
tempValue = process(stackInput, M, N)
stackInput.pop()
if (tempValue > currentMaxValue)
currentMaxValue = tempValue
}
return currentMaxValue
}
process(stackInput, M, N)
{
tempValue = stackInput.pop() * 10^(N - 1)
*howManyItemsCanILook = (M - N + 1)
for y = (N - 2); y == 0; y++
{
currentHowManyItemsCanILook = *howManyItemsCanILook
tempValue = tempValue + getValue(stackInput, *howManyItemsCanILook) * 10^(y)
*howManyItemsCanILook = *howManyItemsCanILook - 1
for x = 0; x < (currentHowManyItemsCanILook - *howManyItemsCanILook); x++
{
stackInput.pop()
}
}
return tempValue
}
getValue(stackInput, *howManyItemsCanILook)
{
currentMaxValue = stackInput.pop()
if (currentMaxValue == 9)
return 9
else
{
goUntil = *howManyItemsCanILook
for i = 0; i < goUntil; i++
{
*howManyItemsCanILook = *howManyItemsCanILook - 1
tempValue = stackInput.pop()
if (currentMaxValue < tempValue)
{
currentMaxValue = tempValue
if (currentMaxValue == 9)
return currentMaxValue
}
}
return currentMaxValue
}
}
note: where *howManyItemsCanILook is passed by reference
I hope this helps

Find the sum of all multiples of 3 or 5 up to 1000

I'm doing the problems on Project Euler in C++, but I'm not getting the right answers to the first one.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
int b;
int c;
for (int a = 0; a <= 1000;)
{
a = a + 3;
b = a + b;
}
cout << b << "\n";
for (int a = 0; a <=1000;)
{
a = a + 5;
c = a + c;
}
cout << c << "\n";
b = b + c;
cout << b << "\n";
return 0;
}
My output is:
167835
101505
269340
Where's the error in my logic?
You are adding all values that are both multiples of 3 and 5 (i.e. multiples of 15) twice. Additionally, you will also include 1002 and 1005, which probably isn't intended.
You're double counting numbers that are multiples of 3 and 5 (i.e. multiples of 15).
Consider, Find the sum of all multiples of 3 up to 20?
Ans : =>
3, 6, 9, 12, 15 this are multiples of 3 up to 20
Sum of all multiple of 3 up to 20 is => [3 + 6 +9 + 12 + 15]
(3 + 6 +9 + 12 + 15) you can rewrite in following way
3 (1+ 2+3 +4+5 ) = > 3 (15) => 45
sum of sequence can be calculated using following formula
K(K+1)/2 = > here K is 5 => 5 (5+1)/2 = >15
In general, We can say that multiple of any number (N) within given range R
K = R/N;
N* (K (K+1))/2
In our case R =20 and N =3
int sumDivisibeBy(int R, int N)
{
int K = R / N;
int SEQSUM = ((K*(K + 1)) / 2));
return (N*SEQSUM)
}
In your case you need to call this function thrice =>
sumDivisibeBy(1000,3) + sumDivisibeBy(1000,5)-sumDivisibeBy(1000,15)
Along with double counting multiples of 15, your increments are in the wrong order. If you increment a first, you will have values above 1000. Also I'm not sure about c++ initializing ints, but maybe set them equal to 0, at least for readers.
wouldn't bother incrementing by 3 and by 5, you can increment by 1 and check whether numbers are divisible by 3 or by 5. Computers are designed for number crunching.
int sum = 0;
for (int i = 0; i < 1000; i++)
{
if (i%3 == 0 ||
i%5 == 0)
{
sum += i;
}
}
cout << "SUM:" << sum << endl;
While others have posted exactly where you've erred, you should be trying to figure out how you got the wrong answer as well.
In your case, you could have written all the values you determined to be multiples of 3 and multiples of 5; then you could have analyzed the 333 multiples of 3 you should've seen and the 199 multiples of 5 you should've seen.
I don't want to give away the keys to finding the actual solution (despite the fact that others have already) but part of the problem solving at PE is debugging.