For example, 16 can be expressed in these ways:
2*2*2*2
4*2*2
4*4
8*2
(excluding the trivial case 1*16)
36:
2*2*3*3
2*2*9
2*18
4*3*3
12*3
4*9
Therefore, I need to find all the representations of any given number just like above.
To start, I was able to come up with all the divisors of a given number with the codes below:
void FindDivisors(int n)
{
vector<int> my_vector;
for (int i = 2; i < n/2 + 1; i++)
{
if (n % i == 0)
my_vector.push_back(i); //store divisors in a vector.
}
}
After this, I got stuck. How do I get from all the divisors to all the factorizations wanted?
I can think of a recursion method that seems to work but do not exactly know how to implement it:
Take 16 as the example. Let's name the function to find all the representations of n to be "Factor(n)". All non-trivial divisors of 16 are {2,4,8}. We divide 16 by each of its divisor and get {8, 4, 2}. Then Factor(16) = the union of 2*Factor(8), 4*Factor(4) and 8*Factor(8). However, this is as far as I got. I am new to recursion and not sure if this route works out. I need some help on how to put things together.
As long as you don't know the number of factors, the most effective solution is recursion.
You will need a vector to store the current path:
vector<int> path; // it will store all current factors
and a recursive function.
For every iteration you try to divide current remainder and remember:
void OutputRec(int value)
{
if (value == 1) // We have divided the whole number
{
for (int i = 0; i < path.size(); i++) cout << path[i] << " ";
cout << endl;
return;
}
for (int i = value; i > 1; i--)
{
if (value % i == 0) { // if it is divisible
path.push_back(i); // add to path
OutputRec(i, value / i); // continue working
path.pop_back(); // remove from path
}
}
}
void Output(int value)
{
cout << "Result for " << value << ": " << endl;
path = vector<int>();
OutputRec(value);
}
int main() {
Output(4);
Output(16);
Output(36);
Output(256);
return 0;
}
For example, let we have 8. Here is how it works:
OutputRec(8), path = []:
i = 8: divisible (8 / 1 = 1)
OutputRec(1), path = [8], value == 1 > output "8".
i = 7, 6, 5: not divisible
i = 4: divisible (8 / 4 = 2)
OutputRec(2), path = [4]:
i2 = 2: divisible (2 / 2 = 1)
OutputRec(1), path = [4 2], value == 1 > output "4 2".
i = 3: not divisible
i = 2: divisible (8 / 2 = 4)
OutputRec(4), path = [2]:
i3 = 4: divisible (4 / 4 = 1)
OutputRec(1), path = [2 4], value == 1 > output "2 4".
i3 = 3: not divisible
i3 = 2: divisible (4 / 2 = 2)
OutputRec(2), path = [2 2]:
i4 = 2: divisible (2 / 2 = 1)
OutputRec(1), path = [2 2 2], value == 1 > output "2 2 2"
Result:
8,
4 * 2,
2 * 4,
2 * 2 * 2
Now, you see the problem: [2 4] and [4 2] is duplicated answer. How can we avoid duplicating answers? The easiest approach is to output values only in ascending (descending, does not matter) order.
Let's add max variable and store the last number inserted into a path and find only those dividers which are less or equal to it.
For example, if current path is [2], then the recursion shouldn't go for [2 4], but should go for [2 2]. The initial value of max is equal to value as the first number in the path can be any.
void OutputRec(int max, int value)
{
if (value == 1) {
for (int i = 0; i < path.size(); i++) cout << path[i] << " ";
if (path.size() == 1) cout << "1";
cout << endl;
return;
}
for (int i = max; i > 1; i--) // loop from max. Min(max, value) would be better
{
if (value % i == 0) {
path.push_back(i);
OutputRec(i, value / i);
path.pop_back();
}
}
}
void Output(int value)
{
cout << "Result for " << value << ": " << endl;
path = vector<int>();
OutputRec(value, value);
}
Here is how it works now:
OutputRec(8), path = []:
i = 8: divisible (8 / 8 = 1)
OutputRec(1), path = [8], value == 1 > output "8".
i = 7, 6, 5: not divisible
i = 4: divisible (8 / 4 = 2)
OutputRec(2), path = [4]:
i2 = 2: divisible
OutputRec(1), path = [4 2], value == 1 > output "4 2".
i = 3: not divisible
i = 2: divisible (8 / 2 = 4)
OutputRec(4), path = [2]:
// notice i3 starts from 2, because last inserted is 2
i3 = 2: divisible (4 / 2 = 2)
OutputRec(2), path = [2 2]:
i4 = 2: divisible (2 / 2 = 1)
OutputRec(1), path = [2 2 2], value == 1 > output "2 2 2"
Result:
8,
4 * 2,
2 * 2 * 2
Everything works fine! The only thing which looks incorrect is "8". It probably should be "8 * 1". You can add a line like if (path.size() == 1) cout << "1"; to the output.
Result:
8 * 1,
4 * 2,
2 * 2 * 2
Here is the working Ideone demo.
I hope that I didn't confuse you even more. It is really difficult to explain what recursion is at the first time.
Recursion is like swimming or cycling - it looks difficult first. Then, you try it and learn it, and once you understand it - you will wonder why couldn't you do this before :) Good luck.
Related
I was trying to find a way to skip some indexes and add the number of skipped indexes to the index.
for example,
I want to skip all the index divisible by 4, and add those skipped indexes as well.
i.e, if index = 4, 4 mod 4 == 0, so index becomes 5.
if index = 8, 8 mod 4 == 0, but index becomes 10, because we already had to skip 4.
likewise, if index = 16, 16 mod 4 == 0, but index becomes 21. Because 16 + 4 = 20, which again is a multiple of 4, so we skip that and goes to next index, 21.
okay, let me try to explain it through a code snippet i was trying it on.
int fn(int i) {
if (i <= 0) {
return 0;
}
if (i % 4 == 0) {
return fn(i / 4) + (i / 4);
} else {
return i / 4;
}
}
for (int i = 0; i < 100; i++) {
int bl = fn(i);
cout << "block:" << i << endl << "Translated:" << bl << endl;
}
But as you can see its not working properly. Any ideas?
Every block of four consecutive numbers—like 1, 2, 3, 4 or 5, 6, 7, 8—contains three usable indices and one that should be skipped. So all we need to do is:
Divide by three to get the number of blocks needed.
Multiply that number by four to switch from a number of usable indices to a number of original indices.
Add the remainder modulo three to account for position within the last block.
Adjust because we apparently want to start with index 1. Thus adjustment is to subtract one (to convert to zero-based indices), do the calculation described above, and then add one (to convert back to one-based indices).
This program:
#include <stdio.h>
int fn(int i)
{
return (i-1)/3*4 + (i-1)%3 + 1;
}
int main(void)
{
for (int i = 1; i < 17; ++i)
printf("%d -> %d.\n", i, fn(i));
}
produces this output:
1 -> 1.
2 -> 2.
3 -> 3.
4 -> 5.
5 -> 6.
6 -> 7.
7 -> 9.
8 -> 10.
9 -> 11.
10 -> 13.
11 -> 14.
12 -> 15.
13 -> 17.
14 -> 18.
15 -> 19.
16 -> 21.
I'm assuming fn is supposed to return the offset to the normal index. If this is true, your code is actually correct - you're just printing the "translated" value wrong. bl will contain the offset; this has to be added to i in order to get the actual index.
std::cout << "block:" << i << std::endl << "Translated:" << i + bl << std::endl;
Demo
This function is better solved through logic than recursion. We're skipping every third index; ergo, we need only add 1 to the index after every 3 steps.
#include <iostream>
int fn(int i) {
if (i <= 0) {
return 0;
}
int offset = (i-1)/3;
return offset;
}
int main() {
for (int i = 1; i <= 13; i++) {
int bl = fn(i);
std::cout << "block:" << i << std::endl << "Translated:" << i + bl << std::endl;
}
}
Demo
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;
}
Can anybody find any potentially more efficient algorithms for accomplishing the following task?:
For any given permutation of the integers 0 thru 7, return the index which describes the permutation lexicographically (indexed from 0, not 1).
For example,
The array 0 1 2 3 4 5 6 7 should return an index of 0.
The array 0 1 2 3 4 5 7 6 should return an index of 1.
The array 0 1 2 3 4 6 5 7 should return an index of 2.
The array 1 0 2 3 4 5 6 7 should return an index of 5039 (that's 7!-1 or factorial(7)-1).
The array 7 6 5 4 3 2 1 0 should return an index of 40319 (that's 8!-1). This is the maximum possible return value.
My current code looks like this:
int lexic_ix(int* A){
int value = 0;
for(int i=0 ; i<7 ; i++){
int x = A[i];
for(int j=0 ; j<i ; j++)
if(A[j]<A[i]) x--;
value += x*factorial(7-i); // actual unrolled version doesn't have a function call
}
return value;
}
I'm wondering if there's any way I can reduce the number of operations by removing that inner loop, or if I can reduce conditional branching in any way (other than unrolling - my current code is actually an unrolled version of the above), or if there are any clever bitwise hacks or filthy C tricks to help.
I already tried replacing
if(A[j]<A[i]) x--;
with
x -= (A[j]<A[i]);
and I also tried
x = A[j]<A[i] ? x-1 : x;
Both replacements actually led to worse performance.
And before anyone says it - YES this is a huge performance bottleneck: currently about 61% of the program's runtime is spent in this function, and NO, I don't want to have a table of precomputed values.
Aside from those, any suggestions are welcome.
Don't know if this helps but here's an other solution :
int lexic_ix(int* A, int n){ //n = last index = number of digits - 1
int value = 0;
int x = 0;
for(int i=0 ; i<n ; i++){
int diff = (A[i] - x); //pb1
if(diff > 0)
{
for(int j=0 ; j<i ; j++)//pb2
{
if(A[j]<A[i] && A[j] > x)
{
if(A[j]==x+1)
{
x++;
}
diff--;
}
}
value += diff;
}
else
{
x++;
}
value *= n - i;
}
return value;
}
I couldn't get rid of the inner loop, so complexity is o(n log(n)) in worst case, but o(n) in best case, versus your solution which is o(n log(n)) in all cases.
Alternatively, you can replace the inner loop by the following to remove some worst cases at the expense of another verification in the inner loop :
int j=0;
while(diff>1 && j<i)
{
if(A[j]<A[i])
{
if(A[j]==x+1)
{
x++;
}
diff--;
}
j++;
}
Explanation :
(or rather "How I ended with that code", I think it is not that different from yours but it can make you have ideas, maybe)
(for less confusion I used characters instead and digit and only four characters)
abcd 0 = ((0 * 3 + 0) * 2 + 0) * 1 + 0
abdc 1 = ((0 * 3 + 0) * 2 + 1) * 1 + 0
acbd 2 = ((0 * 3 + 1) * 2 + 0) * 1 + 0
acdb 3 = ((0 * 3 + 1) * 2 + 1) * 1 + 0
adbc 4 = ((0 * 3 + 2) * 2 + 0) * 1 + 0
adcb 5 = ((0 * 3 + 2) * 2 + 1) * 1 + 0 //pb1
bacd 6 = ((1 * 3 + 0) * 2 + 0) * 1 + 0
badc 7 = ((1 * 3 + 0) * 2 + 1) * 1 + 0
bcad 8 = ((1 * 3 + 1) * 2 + 0) * 1 + 0 //First reflexion
bcda 9 = ((1 * 3 + 1) * 2 + 1) * 1 + 0
bdac 10 = ((1 * 3 + 2) * 2 + 0) * 1 + 0
bdca 11 = ((1 * 3 + 2) * 2 + 1) * 1 + 0
cabd 12 = ((2 * 3 + 0) * 2 + 0) * 1 + 0
cadb 13 = ((2 * 3 + 0) * 2 + 1) * 1 + 0
cbad 14 = ((2 * 3 + 1) * 2 + 0) * 1 + 0
cbda 15 = ((2 * 3 + 1) * 2 + 1) * 1 + 0 //pb2
cdab 16 = ((2 * 3 + 2) * 2 + 0) * 1 + 0
cdba 17 = ((2 * 3 + 2) * 2 + 1) * 1 + 0
[...]
dcba 23 = ((3 * 3 + 2) * 2 + 1) * 1 + 0
First "reflexion" :
An entropy point of view. abcd have the fewest "entropy". If a character is in a place it "shouldn't" be, it creates entropy, and the earlier the entropy is the greatest it becomes.
For bcad for example, lexicographic index is 8 = ((1 * 3 + 1) * 2 + 0) * 1 + 0 and can be calculated that way :
value = 0;
value += max(b - a, 0); // = 1; (a "should be" in the first place [to create the less possible entropy] but instead it is b)
value *= 3 - 0; //last index - current index
value += max(c - b, 0); // = 1; (b "should be" in the second place but instead it is c)
value *= 3 - 1;
value += max(a - c, 0); // = 0; (a "should have been" put earlier, so it does not create entropy to put it there)
value *= 3 - 2;
value += max(d - d, 0); // = 0;
Note that the last operation will always do nothing, that's why "i
First problem (pb1) :
For adcb, for example, the first logic doesn't work (it leads to an lexicographic index of ((0* 3+ 2) * 2+ 0) * 1 = 4) because c-d = 0 but it creates entropy to put c before b. I added x because of that, it represents the first digit/character that isn't placed yet. With x, diff cannot be negative.
For adcb, lexicographic index is 5 = ((0 * 3 + 2) * 2 + 1) * 1 + 0 and can be calculated that way :
value = 0; x=0;
diff = a - a; // = 0; (a is in the right place)
diff == 0 => x++; //x=b now and we don't modify value
value *= 3 - 0; //last index - current index
diff = d - b; // = 2; (b "should be" there (it's x) but instead it is d)
diff > 0 => value += diff; //we add diff to value and we don't modify x
diff = c - b; // = 1; (b "should be" there but instead it is c) This is where it differs from the first reflexion
diff > 0 => value += diff;
value *= 3 - 2;
Second problem (pb2) :
For cbda, for example, lexicographic index is 15 = ((2 * 3 + 1) * 2 + 1) * 1 + 0, but the first reflexion gives : ((2 * 3 + 0) * 2 + 1) * 1 + 0 = 13 and the solution to pb1 gives ((2 * 3 + 1) * 2 + 3) * 1 + 0 = 17. The solution to pb1 doesn't work because the two last characters to place are d and a, so d - a "means" 1 instead of 3. I had to count the characters placed before that comes before the character in place, but after x, so I had to add an inner loop.
Putting it all together :
I then realised that pb1 was just a particular case of pb2, and that if you remove x, and you simply take diff = A[i], we end up with the unnested version of your solution (with factorial calculated little by little, and my diff corresponding to your x).
So, basically, my "contribution" (I think) is to add a variable, x, which can avoid doing the inner loop when diff equals 0 or 1, at the expense of checking if you have to increment x and doing it if so.
I also checked if you have to increment x in the inner loop (if(A[j]==x+1)) because if you take for example badce, x will be b at the end because a comes after b, and you will enter the inner loop one more time, encountering c. If you check x in the inner loop, when you encounter d you have no choice but doing the inner loop, but x will update to c, and when you encounter c you will not enter the inner loop. You can remove this check without breaking the program
With the alternative version and the check in the inner loop it makes 4 different versions. The alternative one with the check is the one in which you enter the less the inner loop, so in terms of "theoretical complexity" it is the best, but in terms of performance/number of operations, I don't know.
Hope all of this helps (since the question is rather old, and I didn't read all the answers in details). If not, I still had fun doing it. Sorry for the long post. Also I'm new on Stack Overflow (as a member), and not a native speaker, so please be nice, and don't hesitate to let me know if I did something wrong.
Linear traversal of memory already in cache really doesn't take much times at all. Don't worry about it. You won't be traversing enough distance before factorial() overflows.
Move the 8 out as a parameter.
int factorial ( int input )
{
return input ? input * factorial (input - 1) : 1;
}
int lexic_ix ( int* arr, int N )
{
int output = 0;
int fact = factorial (N);
for ( int i = 0; i < N - 1; i++ )
{
int order = arr [ i ];
for ( int j = 0; j < i; j++ )
order -= arr [ j ] < arr [ i ];
output += order * (fact /= N - i);
}
return output;
}
int main()
{
int arr [ ] = { 11, 10, 9, 8, 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 };
const int length = 12;
for ( int i = 0; i < length; ++i )
std::cout << lexic_ix ( arr + i, length - i ) << std::endl;
}
Say, for a M-digit sequence permutation, from your code, you can get the lexicographic SN formula which is something like: Am-1*(m-1)! + Am-2*(m-2)! + ... + A0*(0)! , where Aj range from 0 to j. You can calculate SN from A0*(0)!, then A1*(1)!, ..., then Am-1 * (m-1)!, and add these together(suppose your integer type does not overflow), so you do not need calculate factorials recursively and repeatedly. The SN number is a range from 0 to M!-1 (because Sum(n*n!, n in 0,1, ...n) = (n+1)!-1)
If you are not calculating factorials recursively, I cannot think of anything that could make any big improvement.
Sorry for posting the code a little bit late, I just did some research, and find this:
http://swortham.blogspot.com.au/2011/10/how-much-faster-is-multiplication-than.html
according to this author, integer multiplication can be 40 times faster than integer division. floating numbers are not so dramatic though, but here is pure integer.
int lexic_ix ( int arr[], int N )
{
// if this function will be called repeatedly, consider pass in this pointer as parameter
std::unique_ptr<int[]> coeff_arr = std::make_unique<int[]>(N);
for ( int i = 0; i < N - 1; i++ )
{
int order = arr [ i ];
for ( int j = 0; j < i; j++ )
order -= arr [ j ] < arr [ i ];
coeff_arr[i] = order; // save this into coeff_arr for later multiplication
}
//
// There are 2 points about the following code:
// 1). most modern processors have built-in multiplier, \
// and multiplication is much faster than division
// 2). In your code, you are only the maximum permutation serial number,
// if you put in a random sequence, say, when length is 10, you put in
// a random sequence, say, {3, 7, 2, 9, 0, 1, 5, 8, 4, 6}; if you look into
// the coeff_arr[] in debugger, you can see that coeff_arr[] is:
// {3, 6, 2, 6, 0, 0, 1, 2, 0, 0}, the last number will always be zero anyway.
// so, you will have good chance to reduce many multiplications.
// I did not do any performance profiling, you could have a go, and it will be
// much appreciated if you could give some feedback about the result.
//
long fac = 1;
long sn = 0;
for (int i = 1; i < N; ++i) // start from 1, because coeff_arr[N-1] is always 0
{
fac *= i;
if (coeff_arr[N - 1 - i])
sn += coeff_arr[N - 1 - i] * fac;
}
return sn;
}
int main()
{
int arr [ ] = { 3, 7, 2, 9, 0, 1, 5, 8, 4, 6 }; // try this and check coeff_arr
const int length = 10;
std::cout << lexic_ix(arr, length ) << std::endl;
return 0;
}
This is the whole profiling code, I only run the test in Linux, code was compiled using G++8.4, with '-std=c++11 -O3' compiler options. To be fair, I slightly rewrote your code, pre-calculate the N! and pass it into the function, but it seems this does not help much.
The performance profiling for N = 9 (362,880 permutations) is:
Time durations are: 34, 30, 25 milliseconds
Time durations are: 34, 30, 25 milliseconds
Time durations are: 33, 30, 25 milliseconds
The performance profiling for N=10 (3,628,800 permutations) is:
Time durations are: 345, 335, 275 milliseconds
Time durations are: 348, 334, 275 milliseconds
Time durations are: 345, 335, 275 milliseconds
The first number is your original function, the second is the function re-written that gets N! passed in, the last number is my result. The permutation generation function is very primitive and runs slowly, but as long as it generates all permutations as testing dataset, that is alright. By the way, these tests are run on a Quad-Core 3.1Ghz, 4GBytes desktop running Ubuntu 14.04.
EDIT: I forgot a factor that the first function may need to expand the lexi_numbers vector, so I put an empty call before timing. After this, the times are 333, 334, 275.
EDIT: Another factor that could influence the performance, I am using long integer in my code, if I change those 2 'long' to 2 'int', the running time will become: 334, 333, 264.
#include <iostream>
#include <vector>
#include <chrono>
using namespace std::chrono;
int factorial(int input)
{
return input ? input * factorial(input - 1) : 1;
}
int lexic_ix(int* arr, int N)
{
int output = 0;
int fact = factorial(N);
for (int i = 0; i < N - 1; i++)
{
int order = arr[i];
for (int j = 0; j < i; j++)
order -= arr[j] < arr[i];
output += order * (fact /= N - i);
}
return output;
}
int lexic_ix1(int* arr, int N, int N_fac)
{
int output = 0;
int fact = N_fac;
for (int i = 0; i < N - 1; i++)
{
int order = arr[i];
for (int j = 0; j < i; j++)
order -= arr[j] < arr[i];
output += order * (fact /= N - i);
}
return output;
}
int lexic_ix2( int arr[], int N , int coeff_arr[])
{
for ( int i = 0; i < N - 1; i++ )
{
int order = arr [ i ];
for ( int j = 0; j < i; j++ )
order -= arr [ j ] < arr [ i ];
coeff_arr[i] = order;
}
long fac = 1;
long sn = 0;
for (int i = 1; i < N; ++i)
{
fac *= i;
if (coeff_arr[N - 1 - i])
sn += coeff_arr[N - 1 - i] * fac;
}
return sn;
}
std::vector<std::vector<int>> gen_permutation(const std::vector<int>& permu_base)
{
if (permu_base.size() == 1)
return std::vector<std::vector<int>>(1, std::vector<int>(1, permu_base[0]));
std::vector<std::vector<int>> results;
for (int i = 0; i < permu_base.size(); ++i)
{
int cur_int = permu_base[i];
std::vector<int> cur_subseq = permu_base;
cur_subseq.erase(cur_subseq.begin() + i);
std::vector<std::vector<int>> temp = gen_permutation(cur_subseq);
for (auto x : temp)
{
x.insert(x.begin(), cur_int);
results.push_back(x);
}
}
return results;
}
int main()
{
#define N 10
std::vector<int> arr;
int buff_arr[N];
const int length = N;
int N_fac = factorial(N);
for(int i=0; i<N; ++i)
arr.push_back(N-i-1); // for N=10, arr is {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
std::vector<std::vector<int>> all_permus = gen_permutation(arr);
std::vector<int> lexi_numbers;
// This call is not timed, only to expand the lexi_numbers vector
for (auto x : all_permus)
lexi_numbers.push_back(lexic_ix2(&x[0], length, buff_arr));
lexi_numbers.clear();
auto t0 = high_resolution_clock::now();
for (auto x : all_permus)
lexi_numbers.push_back(lexic_ix(&x[0], length));
auto t1 = high_resolution_clock::now();
lexi_numbers.clear();
auto t2 = high_resolution_clock::now();
for (auto x : all_permus)
lexi_numbers.push_back(lexic_ix1(&x[0], length, N_fac));
auto t3 = high_resolution_clock::now();
lexi_numbers.clear();
auto t4 = high_resolution_clock::now();
for (auto x : all_permus)
lexi_numbers.push_back(lexic_ix2(&x[0], length, buff_arr));
auto t5 = high_resolution_clock::now();
std::cout << std::endl << "Time durations are: " << duration_cast<milliseconds> \
(t1 -t0).count() << ", " << duration_cast<milliseconds>(t3 - t2).count() << ", " \
<< duration_cast<milliseconds>(t5 - t4).count() <<" milliseconds" << std::endl;
return 0;
}
After using make_pair, I got some pairs namely pairToCount
in this format (element 1 element 2)= # of frequent in the Db:
(1 2) = 1
(1 3) = 1
(1 4) = 1
(2 3) = 2
(2 4) = 3
(2 5) = 1
(3 4) = 2
(5 4) = 1
I want to do the following for each number (1,2,3,4,5):
First, check each pair has number 1 ==> then sum its frequent for example:
1 is exist in the following pairs: (1 2), (1 3), (1 4)==> the sum of there frequent is =1+1+1=3
do the same for 2, 3, 4,5
2 is in (1 2), (2 3), (2 4),(2 5)==> the sum of there frequent is =1+2+3+1=7
3 is in (1 3), (2 3), (3 4)==> the sum of there frequent is =1+2+2=5
and so on. This is the code I wrote it.
int sum = 0;
int found;
for (const auto& p1 : pairToCount)
{
int r = p1.first.first;
std::cout << " (" << r;
for (const auto& p2 : pairToCount)
{
if (r == p2.first.first)
{
sum += p2.second;
found = p2.first.second;
}
else if (r == p2.first.second)
{
sum += p2.second;
found = p2.first.first;
}
else
exit;
std::cout << "," << found ;
}
std::cout << ") = "<< sum << "\n ";
sum = 0;
}
I got duplication printing the last element and the same test
+
since there is no pair start with 4, the code doesn't work in this case.
This the result:
(1,2,3,4,4,4,4,4,4) = 3
(1,2,3,4,4,4,4,4,4) = 3
(1,2,3,4,4,4,4,4,4) = 3
(2,1,1,1,3,4,5,5,5) = 7
(2,1,1,1,3,4,5,5,5) = 7
(2,1,1,1,3,4,5,5,5) = 7
(3,5,1,1,2,2,2,4,4) = 5
(5,4,4,4,4,4,2,2,4) = 2
I just learn make_pair, and spent 4 hours reading about it, to see if there is any example or similar question can guide me but no luck!
You can simplify your problem a lot by using a map (or unordered_map if you have C++11 or from boost).
The idea would be to iterate once over your list of pairs/frequency, and store the partial sums in the map for each key. You can then print out the sums in a second loop.
#include <map>
// ...
std::map<int,int> sums;
for (const auto& p1 : pairToCount)
sums[p1.first.first] += p1.second;
sums[p1.first.second] += p1.second;
}
for (const auto& k : sums) {
// print what you want
}
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.