I have three integer variables, that can take only the values 0, 1 and 2. I want to distinguish what combination of all three numbers I have, ordering doesn't count. Let's say the variables are called x, y and z. Then x=1, y=0, z=0 and x=0, y=1, z=0 and x=0, y=0, z=1 are all the same number in this case, I will refer to this combination as 001.
Now there are a hundred ways how to do this, but I am asking for an elegant solution, be it only for educational purposes.
I thought about bitwise shifting 001 by the amount of the value:
001 << 0 = 1
001 << 1 = 2
001 << 2 = 4
But then the numbers 002 and 111 would both give 6.
The shift idea is good, but you need 2 bits to count to 3. So try shifting by twice the number of bits:
1 << (2*0) = 1
1 << (2*1) = 4
1 << (2*2) = 16
Add these for all 3 numbers, and the first 2 bits will count how many 0 you have, the second 2 bits will count how many 1 and the third 2 bits will count how many 2.
Edit although the result is 6 bit long (2 bits per number option 0,1,2), you only need the lowest 4 bits for a unique identifier - as if you know how many 0 and 1 you have, then the number of 2 is determined also.
So instead of doing
res = 1<<(2*x);
res+= 1<<(2*y);
res+= 1<<(2*z);
you can do
res = x*x;
res+= y*y;
res+= z*z;
because then
0*0 = 0 // doesn't change result. We don't count 0
1*1 = 1 // we count the number of 1 in the 2 lower bits
2*2 = 4 // we count the number of 2 in the 2 higher bits
hence using only 4 bits instead of 6.
When the number of distinct possibilities is small, using a lookup table could be used.
First, number all possible combinations of three digits, like this:
Combinations N Indexes
------------- - ------
000 0 0
001, 010, 100 1 1, 3, 9
002, 020, 200 2 2, 6, 18
011, 101, 110 3 4, 10, 12
012, 021, 102, 120, 201, 210 4 5, 7, 11, 15, 19, 21
022, 202, 220 5 8, 20, 24
111 6 13
112, 121, 211 7 14, 16, 22
122, 212, 221 8 17, 23, 25
222 9 26
The first column shows identical combinations; the second column shows the number of the combination (I assigned them arbitrarily); the third column shows the indexes of each combination, computed as 9*<first digit> + 3*<second digit> + <third digit>.
Next, build a look-up table for each of these ten combinations, using this expression as an index:
9*a + 3*b + c
where a, b, and c are the three numbers that you have. The table would look like this:
int lookup[] = {
0, 1, 2, 1, 3, 4, 2, 4, 5, 1
, 3, 4, 3, 6, 7, 4, 7, 8, 2, 4
, 5, 4, 7, 8, 5, 8, 9
};
This is a rewrite of the first table, with values at the indexes corresponding to the value in the column N. For example, combination number 1 is founds at indexes 1, 3, and 9; combination 2 is at indexes 2, 6, and 18, and so on.
To obtain the number of the combination, simply check
int combNumber = lookup[9*a + 3*b + c];
For such small numbers, it would be easiest to just check them individually, instead of trying to be fancy, eg:
bool hasZero = false;
bool hasOne = false;
bool hasTwo = false;
// given: char* number or char[] number...
for(int i = 0; i < 3; ++i)
{
switch (number[i])
{
case '0': hasZero = true; break;
case '1': hasOne = true; break;
case '2': hasTwo = true; break;
default: /* error! */ break;
}
}
If I understand you correctly, you have some sequence of numbers that can either be 1, 2, or 3, where the permutation of them doesn't matter (just the different combinations).
That being the case:
std::vector<int> v{1, 2, 3};
std::sort(v.begin(), v.end());
That will keep all of the different combinations properly aligned, and you could easily write a loop to test for equality.
Alternatively, you could use a std::array<int, N> (where N is the number of possible values - in this case 3).
std::array<int, 3> a;
Where you would set a[0] equal to the number of 1s you have, a[1] equal to the number of '2's, etc.
// if your string is 111
a[0] = 3;
// if your string is 110 or 011
a[0] = 2;
// if your string is 100 or 010 or 001
a[0] = 1;
// if your string is 120
a[0] = 1;
a[1] = 1;
// if your string is 123
a[0] = 1;
a[1] = 1;
a[2] = 1;
If you are looking to store it in a single 32-bit integer:
unsigned long x = 1; // number of 1's in your string
unsigned long y = 1; // number of 2's in your string
unsigned long z = 1; // number of 3's in your string
unsigned long result = x | y << 8 | z << 16;
To retrieve the number of each, you would do
unsigned long x = result & 0x000000FF;
unsigned long y = (result >> 8) & 0x000000FF;
unsigned long z = (result >> 16) & 0x000000FF;
This is very similar to what happens in the RBG macros.
int n[3]={0,0,0};
++n[x];
++n[y];
++n[z];
Now, in the n array, you have a unique ordered combination of values for each unique unordered combination of x,y,z.
For example, both x=1,y=0,z=0 and x=0,y=0,z=1 will give you n={2,1,0}
Related
My code:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
vector<ll> generate_all(map<ll, int> mp, int keys_done, ll prod) {
if (keys_done == mp.size()) {
vector<ll> v;
v.push_back(prod);
return v;
}
vector<ll> vr;
int ctr = 0;
for (auto it = mp.begin(); it != mp.end(); ++it, ctr++) {
if (ctr < keys_done or ctr > keys_done)
continue;
ll next_prod = 1;
for (int j = 1; j <= it->second; j++) {
next_prod *= it->first;
vector<ll> v1 = generate_all(mp, 1 + keys_done, prod * next_prod);
for (int k = 0; k < v1.size(); k++) {
vr.push_back(v1[k]);
}
}
}
return vr;
}
int main() {
map<ll, int> mp = {{2,4},{3,1}, {5,3}};
vector<ll> v_final=generate_all(mp,0,1);
for (const auto & val:v_final) {
cout << val << endl;
}
}
current output:
2
Expected output
2, 3, 4, 5, 6, 8, 10, 12, 15, 16, 20, 24, 25, 30, 40, 48, 50, 60, 75, 80, 100, 120, 125, 150, 200, 240, 250, 300, 375, 400, 500, 600, 750, 1000, 1200, 1500, 2000, 3000, 6000
To illustrate the output it is the following:
2^1,2^2, 2^3, 2^4, 3^1, 5^1, 5^2, 5^3,
2^1 * 3, 2^2 * 3, 2^3 * 3, 2^4 * 3, 5^1 * 3, 5^2 * 3, 5^3 * 3,
2^1 * 5, 2^2 * 5, 2^3 * 5, 2^4 * 5,
2^1 * 5^2, 2^2 * 5^2, 2^3 * 5^2, 2^4 * 5^2, 3^1 * 5^2,
2^1 * 5^3, 2^2 * 5^3, 2^3 * 5^3, 2^4 * 5^3, 3^1 * 5^3,
2^1 * 3^1 * 5^1, 2^1 * 3^1 * 5^2, 2^1 * 3^1 * 5^3,
2^2 * 3^1 * 5^1, 2^2 * 3^1 * 5^2, 2^2 * 3^1 * 5^3,
2^3 * 3^1 * 5^1, 2^3 * 3^1 * 5^2, 2^3 * 3^1 * 5^3,
2^4 * 3^1 * 5^1, 2^4 * 3^1 * 5^2, 2^4 * 3^1 * 5^3,
Here 2 can have 0 to 4 th power multiplied by 3 from 0 to 4 th power and so on.
If the choices were limited to 3 like this example. this is how my code would have looked:
vector<ll>v;
for(int i=0;i<=4;i++)
for(int j=0;j<=1;j++)
for(int k=0;k<=3;k++)
v.insert(pow(2,i)*pow(3,j)*pow(5,k));
return v;
But I need to solve for k such keys not just 3 keys.
If possible do also suggest a non-recusrvice method.
We have to implement 2 major mathematical concepts here
Create a power set
Building the cartesian product over several sets (or the comnination of all elements over several sets)
The task contains some additional indirections to add a little bit complexity.
Let's start with the power set.
We will first make a simplification for an easier understanding of the task. We will name the input pairs, consisting of a base value and an exponent, as set elements a,b,c and so on. If we assume an input of { {2,4},{3,1}, {5,3}, {4,2} }, then we will name this now as a set with 4 elements {a,b,c,d}.
What we need to generate is a power set from this. There are 2 main standard approaches.
Counting with checking of set bits via it mask
Setting more and more bits in a field and do permutations.
Let us look at solution 1. Counting. Based on "abcd" we will get
Count Binary Selection (sub set)
DCBA Cardinality
0 0000 {----} 0 Empty set
1 0001 {---A} 1
2 0010 {--B-} 1
3 0011 {--BA} 2
4 0100 {-C--} 1
5 0101 {-C-A} 2
6 0110 {-CB-} 2
7 0111 {-CBA} 3
8 1000 {D---} 4
9 1001 {D--A} 2
10 1010 {D-B-} 2
11 1011 {D-BA} 3
12 1100 {DC--} 3
13 1101 {DC-A} 3
14 1110 {DCB-} 3
15 1111 {DCBA} 4
As a result we will get the powerset:
{{A},{B},{AB},{C},{AC},{BC},{ABC},{D},{AD},{BD},{ABD},{CD},{ACD},{BCD},{ABCD}}
If you look at the output, we see that the elements are not sorted according to their cardinality. Therefore we will choose a different approach. We will set more and more bits in a field an do permutations on them. Also with a selector. Then, we will get something like this:
Binary Selection
0000 {----} Empty set. Ignored
0001 {---A} Set bit 0
0010 {--B-} Permutation
0101 {-C--} Permutation
1000 {D---} Permutation
0011 {--BA} Set next bit number 1
0101 {-C-A} Permutation
1001 {D--A} Permutation
0110 {-CB-} Permutation
1010 {D-B-} Permutation
1100 {D--A} Permutation
0111 {-CBA} Set next bit number 2
1011 {D-BA} Permutation
1101 {DC-A} Permutation
1110 {DCB-} Permutation
1111 {DCBA} Set next bit number 3
As a result we will get the "more reasonable/expected" powerset:
{{A},{B},{C},{D},{AB},{AC},{AD},{BC},{BD},{AD},{ABC},{ABD},{ACD},{BCD},{ABCD}}
By the way. The overall number of sub sets is of course 2^n and the size of the cardinality group is equal to the corresponding binomial coeeficient.
Cardinality
0 4 choose 0 --> 1
1 4 choose 1 --> 4
2 4 choose 1 --> 6
3 4 choose 1 --> 4
4 4 choose 1 --> 1
Sum: 16
The corresponding algorithm is easy to implement, which can also be seen later in the code example.
Next. If we have the powerset, then we need to combine all elements. Let us take as an example the sub set {ABC}. We can translate this back to the original input data:
{2,4},{3,1},{5,3}
which would expand with the given rule to
{2,4,8,16},{3},{5,25,125}
And now we need to build all combinations of that. The number of combinations is of cause the product of the cardinality of the sub sets. Here 4*1*3 = 12. To illustrate that and get a first idea of the solution approach, we list up all combinations.
2 3 5
4 3 5
8 3 5
16 3 5
2 3 25
4 3 25
8 3 25
16 3 25
2 3 125
4 3 125
8 3 125
16 3 125
We could imagine that we have an odometer with 3 disks. Diks 1 contains 2,4,8,13, disk 2 contins 3 and disk 3 contains 5,25,125.
Everytime, when a disks rolls over than the next disk will be triggered as well. So, if the first diks is at 16 and rolls over to 2 then diks 3 is triggered. Because disk 3 contains only 1 number (the 3), it will also immediately roll over and trigger disk 3. This will then show the next value. And so on and so on.
So, we also do some sort of counting, but the counters have a different base number. Anyway. All this is easy to implement.
As an additional implementation detail, I will not use the "pow" function. I will just multiple the counter, the value on the disk, with its base value. This will save space and time. And all of this put together could be implemented like the following:
(Please note. I use "easy code". We could use many more advanced algorithms, but for the sake of readability, I go this way. As said. Many other solutions possible)
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iomanip>
using MyType = unsigned long long;
// The base-number and the max exponent are the elements of a set
struct Element {
MyType base{};
MyType maxExponent{};
// Actually, this elements does not store one value only, but "maxExponent" elements
// Do get all of those, we use the well known odometer approach
// We can always calculate the next value in the list and inform, if we have a rollover
// In case of a roll over, we can inform other sets about this and the other set can also count up
MyType currentResult{ base };
MyType currentExponent{};
// Calculate next value. So, will for {2,4} get 2, 4, 8, 16
bool next(bool overflowFromPrevious) {
// Indicates that we will wrap around from previous
bool overflow{};
// If a previous odometer roll has overflowed
if (overflowFromPrevious) {
// Check, if we are NOT at the end. This will happen, if ther is only 1 as the max exponent.
if (currentExponent < maxExponent) {
// Get next exponent
++currentExponent;
// And calculate current data. We could also store those values,
// but we do not want to waste space
currentResult *= base;
// Now check again for overflow (after we incremented the exponent)
if (currentExponent >= maxExponent) {
// If overlow, then reset exponent counter and base
currentExponent = 0;
currentResult = base;
overflow = true;
}
}
else overflow = true;
}
return overflow;
}
// Simple inserter operator override, to be able to do an easier output
friend std::ostream& operator << (std::ostream& os, const Element& e) {
return os << '{' << e.base << ',' << e.maxExponent << '}';
}
};
// We will use a vetcor and not a set, because we need random access via the index operator
using MSet = std::vector<Element>;
void getProducts(MSet& mset) {
// Selectors for creating the subsets of the power set
std::vector<bool> selector(mset.size());
// For all number of elements in the original set
for (size_t k{}; k < mset.size(); ++k) {
// Set selecot bits. In each loop one more bit. So, 1 then 11, then 111 and so on
selector[k] = true;
// Do all permutations of the above set bits
do {
// For debug output
for (bool b : selector) std::cout << b * 1; std::cout << " ";
std::ostringstream oss{};
// Here we will store all elements of a resulting subset
MSet subSet{};
// Check if the selector bit is set, and if so, then add to subset
for (size_t n{}; n < mset.size(); ++n) {
if (selector[n]) {
subSet.push_back(mset[n]);
oss << mset[n]; // For debug output
}
}
// Debug output of powerset with number of subsets
std::cout << "Powerset("<< subSet.size()<< "): " << std::left << std::setw(22) << oss.str() << ' ';
// Now, we want to calculate all combinations of subsets, using the odometer approach
// Here we will store the overall number of combinations. It is the product of all max exponents
MyType combinations{ 1 };
for (const Element& element : subSet)
combinations *= element.maxExponent;
// Now get the product for all combinations over all subsets
for (MyType i{}; i < combinations; ++i) {
// Get the product for one combination
MyType product{ 1 };
for (Element& element : subSet)
product *= element.currentResult;
std::cout << product << ' '; // For debug output
// And, using the odometer approach, create the next combination
bool overflow{true};
for (Element& element : subSet)
overflow = element.next(overflow);
}
std::cout << '\n'; // For debug output
} while (std::prev_permutation(selector.begin(), selector.end()));
}
}
// Test / driver code
int main() {
MSet mset{ {2,4},{3,1}, {5,3}, {4,2} };
getProducts (mset);
}
I added a lot of debug output. You may delete that.
With that the solution the result will be:
By the way. I think that your expected output is wrong . . .
Am working on a C++ app in Windows platform. There's a unsigned char pointer that get's bytes in decimal format.
unsigned char array[160];
This will have values like this,
array[0] = 0
array[1] = 0
array[2] = 176
array[3] = 52
array[4] = 0
array[5] = 0
array[6] = 223
array[7] = 78
array[8] = 0
array[9] = 0
array[10] = 123
array[11] = 39
array[12] = 0
array[13] = 0
array[14] = 172
array[15] = 51
.......
........
.........
and so forth...
I need to take each block of 4 bytes and then calculate its decimal value.
So for eg., for the 1st 4 bytes the combined hex value is B034. Now i need to convert this to decimal and divide by 1000.
As you see, for each 4 byte block the 1st 2 bytes are always 0. So i can ignore those and then take the last 2 bytes of that block. So from above example, it's 176 & 52.
There're many ways of doing this, but i want to do it via using bit wise operators.
Below is what i tried, but it's not working. Basically am ignoring the 1st 2 bytes of every 4 byte block.
int index = 0
for (int i = 0 ; i <= 160; i++) {
index++;
index++;
float Val = ((Array[index]<<8)+Array[index+1])/1000.0f;
index++;
}
Since you're processing the array four-by-four, I recommend that you increment i by 4 in the for loop. You can also avoid confusion after dropping the unnecessary index variable - you have i in the loop and can use it directly, no?
Another thing: Prefer bitwise OR over arithmetic addition when you're trying to "concatenate" numbers, although their outcome is identical.
for (int i = 0 ; i <= 160; i += 4) {
float val = ((array[i + 2] << 8) | array[i + 3]) / 1000.0f;
}
First of all, i <= 160 is one iteration too many.
Second, your incrementation is wrong; for index, you have
Iteration 1:
1, 2, 3
And you're combining 2 and 3 - this is correct.
Iteration 2:
4, 5, 6
And you're combining 5 and 6 - should be 6 and 7.
Iteration 3:
7, 8, 9
And you're combining 8 and 9 - should be 10 and 11.
You need to increment four times per iteration, not three.
But I think it's simpler to start looping at the first index you're interested in - 2 - and increment by 4 (the "stride") directly:
for (int i = 2; i < 160; i += 4) {
float Val = ((Array[i]<<8)+Array[i+1])/1000.0f;
}
I'm student of second year on CS. On my algorithms and data structures course I've been tasked with following problem:
Input:
2<=r<=20
2<=o<=10
0<=di<=100
Output:
number of combinations
or "NO" if there are none
r is number of integers
di are said integers
o is number of groups
I have to find the number of correct combinations. The correct combination is one where every integer is assigned to some group, none of the groups are empty and the sum of integers in every group is the same:
For an instance:
r = 4;
di = {5, 4, 5, 6}
o = 2;
So the sum of integers in every group should add up to 10:
5 + 4 + 5 + 6 = 20
20 / o = 20 / 2 = 10
So we can make following groups:
{5, 5}, {4, 6}
{5, 5}, {6, 4}
{5, 5}, {4, 6}
{5, 5}, {6, 5}
So as we can see, the every combination is essentialy same as first one.( The order of elements in group doesnt matter.)
So actually we have just one correct combination: {5, 5}, {4, 6}. Which means output is equal to one.
Other examples:
r = 4;
di = {10, 2, 8, 6}
o = 2;
10 + 2 + 8 + 6 = 26;
26 / o = 26 / 2 = 13
There is no way to make such a sum of these integers, so the output is "NO".
I had a following idea of getting this thing done:
struct Input { // holds data
int num; // number of integers
int groups; // number of groups
int sumPerGroup; // sum of integers per group
int *integers; // said integers
};
bool f(bool *t, int s) { // generates binary numbers (right to left"
int i = 0;
while (t[i]) i++;
t[i] = 1;
if (i >= s) return true;
if (!t[i + 1])
for (int j = i - 1; j >= 0; j--)
t[j] = 0;
return false;
}
void solve(Input *input, int &result) {
bool bin[input->num]; // holds generated binary numbers
bool used[input->num]; // integers already used
for (int i = 0; i < input->num; i++) {
bin[i] = 0;
used[i] = 0;
}
int solved = 0;
do {
int sum = 0;
for (int i = 0; i < input->num; i++) { // checking if generated combination gets me nice sum
if (sum > input->sumPerGroup) break;
if (bin[i] && !used[i]) sum += input->integers[i]; // if generated combination wasnt used before, start adding up
if (sum == input->sumPerGroup) { // if its add up as it shoul
for (int j = 0; j < input->num; j++) used[j] = bin[j]; // mark integers as used
solved ++; // and mark group as solved
sum = 0;
}
if (udane == input->groups) { // if the number of solved groups is equal to number of groups
result ++; // it means we found another correct combination
solved = 0;
}
}
} while (!f(bin, input->num)); // as long as I can get more combinations
}
So, the main idea is:
1. I generate combination of some numbers as binary number
2. I check if that combination gets me a nice sum
3. If it does, I mark that up
4. Rinse and repeat.
So for input from first example {5, 4, 5, 6} in 2 groups:
5 4 5 6
-------
0 0 0 0
1 0 0 0
...
1 0 1 0 -> this one is fine, becouse 5 + 5 = 10; I mark it as used
1 1 1 0
...
0 1 0 1 -> another one works (4 + 6 = 10); Marked as used
So far i got myself 2 working groups which is equal to 2 groups - job done, it's a correct combination.
The real problem behind my idea is that I have no way of using some integer once I mark it as "used". This way in more complicated examples I would miss quite alot of correct groups. My question is, what is correct approach to this kind of problem? I've tried recursive approach and it didin't work any better (for the same reason)
Another idea I had is to permutate (std:next_permutate(...) for instance) integers from input each time I mark some group as used, but even on paper that looks silly.
I don't ask you to solve that problem for me, but if you could point any flaws in my reasoning that would be terrific.
Also, not a native speaker. So I'd like to apologise in advance if I butchered any sentence (I know i did).
I have to print the number of ways you can represent a given number as it's prime number parts.
Let me clarify: Let's say I have been given this number 7. Now, first of all, I have to find all the prime numbers that are less than 7, which are 2, 3 and 5. Now, in how many ways can I summarize those numbers (I can use one number as many times I want) so that the result equals 7? For example, number 7 has five ways:
2 + 2 + 3
2 + 3 + 2
2 + 5
3 + 2 + 2
5 + 2
I'm totally lost with this task. First I figured I'd make an array of usable elements like so: { 2, 2, 2, 3, 3, 5 } (7/2 = 3, so 2 must appear three times. Same goes with 3, which gets two occurences). After that, loop through the array and choose a 'leader' that determines how far in the array we are. I know the explanation is horrible, so here's the code:
#include <iostream>
#include <vector>
int primes_all[25] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
int main()
{
int number;
std::cin >> number;
std::vector<int> primes_used;
for(int i = 0; i < 25; i++) {
if(primes_all[i] < number && number-primes_all[i] > 1) {
for(int k = 0; k < number/primes_all[i]; k++)
primes_used.push_back(primes_all[i]);
}
else break;
}
int result = 0;
for(size_t i = 0; i < primes_used.size(); i++) {
int j = primes_used.size()-1;
int new_num = number - primes_used[i];
while(new_num > 1 && j > -1)
{
if(j > -1) while(primes_used[j] > new_num && j > 0) j--;
if(j != i && j > -1) {
new_num -= primes_used[j];
std::cout << primes_used[i] << " " << primes_used[j] << " " << new_num << std::endl;
}
j--;
}
if(new_num == 0) result++;
}
std::cout << result << std::endl;
system("pause");
return 0;
}
This simply doesn't work. Simply because the idea behind it is wrong. Here's a little details about the limits:
Time limit: 1 second
Memory limit: 128 MB
Also, the biggest number that can be given is 100. That's why I made the array of prime numbers below 100. The result grows very fast as the given number gets bigger, and will need a BigInteger class later on, but that's not an issue.
A few results known:
Input Result
7 5
20 732
80 10343662267187
SO... Any ideas? Is this a combinatory problem? I don't need code, just an idea. I'm still a newbie to C++ but I'll manage
Keep in mind that 3 + 2 + 2 is different than 2 + 3 + 2.
Also, were the given number to be a prime itself, it won't be counted. For example, if the given number is 7, only these sums are valid:
2 + 2 + 3
2 + 3 + 2
2 + 5
3 + 2 + 2
5 + 2
7 <= excluded
Dynamic programming is your friend here.
Consider the number 27.
If 7 has 5 results, and 20 has 732 results, then you know that 27 has at least (732 * 5) results. You can use a two variable system (1 + 26, 2 + 25 ... etc) using the precomputed values for those as you go. You don't have to recompute 25 or 26 because you already did them.
The concept you are searching for is the "prime partitions" of a number. S partition of a number is a way of adding numbers to reach the target; for instance, 1+1+2+3 is a partition of 7. If all the addends are prime, then the partition is a prime partition.
I think your example is wrong. The number 7 is usually considered to have 3 prime partitions: 2+2+3, 2+5, and 7. The order of the addends doesn't matter. In number theory the function that counts prime partitions is kappa, so we would say kappa(7) = 3.
The usual calculation of kappa is done in two parts. The first part is a function to compute the sum of the prime factors of a number; for instance, 42=2·3·7, so sopf(42)=12. Note that sopf(12)=5 because the sum is over only the distinct factors of a number, so even though 12=2·2·3, only one 2 is included in the calculation of the sum.
Given sopf, there is a lengthy formula to calculate kappa; I'll give it in LaTeX form, since I don't know how to enter it here: \kappa(n) = \frac{1}{n}\left(\mathrm{sopf}(n) + \sum_{j=1}^{n-1} \mathrm{sopf}(j) \cdot \kappa(n-j)\right).
If you actually want a list of the partitions, instead of just the count, there is a dynamic programming solution that #corsiKa pointed out.
I discuss prime partitions in more detail at my blog, including source code to produce both the count and the list.
Here's an efficient implementation which uses dynamic programming like corsiKa suggests, but does not use the algorithm he describes.
Simply: if n is reachable via k distinct paths (including the single-step one, if it exists), and p is prime, then we construct k paths to n+p by appending p to all paths to n. Considering all such n < N will produce an exhaustive list of valid paths to N. So we just sum the number of paths so discovered.
#include <iostream>
int primes_all[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
const int N_max = 85;
typedef long long ways;
ways ways_to_reach_N[N_max + 1] = { 1 };
int main()
{
// find all paths
for( int i = 0; i <= N_max; ++i ) {
ways ways_to_reach_i = ways_to_reach_N[i];
if (ways_to_reach_i) {
for( int* p = primes_all; *p <= N_max - i && p < (&primes_all)[1]; ++p ) {
ways_to_reach_N[i + *p] += ways_to_reach_i;
}
}
}
// eliminate single-step paths
for( int* p = primes_all; *p <= N_max && p < (&primes_all)[1]; ++p ) {
--ways_to_reach_N[*p];
}
// print results
for( int i = 1; i <= N_max; ++i ) {
ways ways_to_reach_i = ways_to_reach_N[i];
if (ways_to_reach_i) {
std::cout << i << " -- " << ways_to_reach_i << std::endl;
}
}
return 0;
}
Demo: http://ideone.com/xWZT8v
Replacing the typedef ways with a big integer type is left as an exercise to the reader.
A character (1 byte) can represent 255 characters but how do i actually find it?
(answering the comment)
There are 256 different combinations of 8 0s and 1s.
This is true because 256 = 28.
Each digit that you add doubles the number of combinations.
In a fixed width binary number, there are two choices for the first bit, two choices for the second bit, two choices for the third, and so on. The total number of combinations for an 8-bit byte is:
2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 = 28 = 256
do you mean
for (char c = " "; c <= "~"; c++) std::cout << c << std::endl;
?
This should show you printable characters in ASCII proper. To see all characters in your font, try c = 0 and c < 255 (be careful with 255 and infinite loop) - but this won't work with your terminal, most probably.
8 bits can represent permutations of ones and zeros from binary 00000000 to 11111111. Just like 3 decimal digits can represent permutations of decimal numbers (0-9) from decimal 000 to 999.
You just start counting: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and then after you reach the digit maximum, you carry over a 1 and start from 0: ..., 8, 9, 10. Right? And then continue this until you fill up all your digits with nines: ..., 997, 998, 999.
It's the same thing in binary: 0, 1 then carry over 1 and start from 0: 0, 1, 10. Continue: 10, 11, 100, 101, 110, 111, 1000, 1001 etc.
Simply counting from 0 to the maximum value than can be represented by your digits gives you all the permutations.