Related
I have a class, call it 'BigNumber', which has a vector v field.
Each element should be one digit.
I want to implement a method to multiply this vector by an integer, but also keep elements one digit.
E.g: <7,6> * 50 = <3,8,0,0>
The vector represents a number, stored in this way. In my example, <7,6> is equal to 76, and <3,8,0,0> is 3800.
I tried the following, but this isn't good (however it works), and not the actual solution for the problem.
//int num, BigNumber bn
if (num > 0)
{
int value = 0, curr = 1;
for (int i = bn.getBigNumber().size() - 1; i >= 0; i--)
{
value += bn.getBigNumber().at(i) * num * curr;
curr *= 10;
}
bn.setBigNumber(value); //this shouldn't be here
return bn;
}
The expected algortithm is multiply the vector itself, not with a variable what I convert to this BigNumber.
The way I set Integer to BigNumber:
void BigNumber::setBigNumber(int num)
{
if (num > 0)
{
bigNum.clear();
while (num != 0)
{
bigNum.push_back(num % 10);
num = (num - (num % 10)) / 10;
}
std::reverse(bigNum.begin(), bigNum.end());
}
else
{
throw TOOSMALL;
}
};
The method I want to implement:
//class BigNumber{private: vector<int> bigNum; ... }
void BigNumber::multiplyBigNumber(BigNumber bn, int num)
{
if (num > 0)
{
//bn.bigNum * num
}
else
{
throw TOOSMALL;
}
}
As this is for a school project, I don't want to just write the code for you. So here's a hint.
Let's say you give me the number 1234 --- and I choose to store each digit in a vector in reverse. So now I've got bignum = [4, 3, 2, 1].
Now you ask me to multiply that by 5. So I create a new, empty vector result=[ ]. I look at the first item in bignum. It's a 4.
4 * 5 is 20, or (as you do at school) it is 0 carry 2. So I push the 0 into result, giving result = [0] and carry = 2.
Questions for you:
If you were doing this by hand (on paper), what would you do next?
Why did I decide to store the digits in reverse order?
Why did I decide to use a new vector (result), rather than modifying bignum?
and only after you have a worked out how to multiply a bignum by an int:
How would you multiply two bignums together?
The solutin for the problem is the follow code. I don't know if I can make this algorithm faster, but it works, so I'm happy with it.
BigNumber BigNumber::multiplyBigNumber(BigNumber bn, int num){
if (num > 0)
{
std::vector<int> result;
std::vector<int> rev = bn.getBigNumber();
std::reverse(rev.begin(),rev.end());
int carry = 0;
for(int i = 0; i<rev.size(); i++){
result.push_back((rev[i] * num + carry) % 10);
carry = (rev[i] * num + carry) / 10;
if(i == rev.size()-1 && carry / 10 == 0 && carry % 10 != 0 ) {
result.push_back(carry);
carry = carry / 10;
}
}
while((carry / 10) != 0){
result.push_back(carry % 10);
carry /= 10;
if(carry / 10 == 0) result.push_back(carry);
}
std::reverse(result.begin(),result.end());
bn.setBigNumber(result);
return bn;
}else{
throw TOOSMALL;
}
}
If I want to find the total number of odd integers between a leftrange and a rightrange, do you think this works ?
example leftrange = 3, rightrange = 8.
int FindOdd(int left, int right)
{
bool lefteven = (left % 2) ? false: true;
bool righteven = (right % 2) ? false: true;
int length = (right-left) + 1;
if (lefteven != righteven) //even length
{
return (length/2);
}
else //odd length
{
if (!lefteven)
return ((length/2) + 1);
else
return (length/2);
}
}
It's a clumsy way to do it. A better way is to use integer division:
unsigned FindOdd(unsigned a, unsigned b)
{
return b / 2 - a / 2;
}
This will not include the final number if b is odd. I've cheekily changed the types to unsigned for the sake of elegance.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
For the problem 10139 - Factovisors on UVa Online Judge, 2 numbers n and m are given, and we need to check whether m divides n!.
I use the algorithm:
Generate primes till const number
Take m and get its primes factor
For each prime in m's factors, calculate getpower function for n and compare them
I test different cases it give me also Wrong Answer, any suggestion?
Here's my code:
bool Factovisor (int n, int m) {
/* Special Cases */
if(n==0 && m!=1 )
return false;
else if(n==0&&m==1)
return true;
else if(m==0)
return false;
else if(m==n||m==1)
return true;
else if (n >= m)
return true;
else {
vector <factores> factores_in_m;
int index = 0;
int k=m;
/* first I generate all primes in primes vector */
for (int i = 0; i < primes.size(); i++) {
if (primes[i] > k) {
break;
} else {
/* factores is struct contain the prime and count*/
factores f = {primes[i], 0};
while (k % primes[i] == 0) {
f.count += 1;
k = k / primes[i];
}
if (f.count) {
factores_in_m.push_back(f);
}
}
}
if (k > 1) {
if (n < k) {
return false;
} else {
factores f;
f.prime= k;
f.count =1;
factores_in_m.push_back(f);
}
}
for (int i = 0; i < factores_in_m.size(); i++) {
if (factores_in_m[i].count - get_powers(n, factores_in_m[i].prime) > 0) {
return false;
}
}
return true;
}
}
int get_powers (int n, int p) {
int result = 0, power = p;
while (power <= n) {
result += n / power;
power =power* p;
}
return result;
}
bool isPrime (int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
void get_prime () {
for (int i = 2; i < maxn0; i++) {
if (isPrime(i)) {
primes.push_back(i);
}
}
}
Maybe your prime generation is faulty, but certainly your get_powers implementation is susceptible to int overflow.
int get_powers (int n, int p) {
int result = 0, power = p;
while (power <= n) {
result += n / power;
power =power* p;
}
return result;
}
If int is, as it usually is, a 32-bit wide type, for primes larger than 46341 the computation power = power * p; overflows the first time it is done. That can lead to wrong results, for example
get_powers(10000000, 131071)
returns 52 if the overflow behaviour is wraparound modulo 232, but the correct result would be 76. Now, since m is smaller than 231, this particular one wouldn't hurt, since m cannot be divisible by 131071². But under the wraparound behaviour,
get_powers(1000000, 699733) = -2192
is negative, so for n = 1000000 and m = 2*699733 for example, you would wrongly conclude that n! isn't divisible by m.
To avoid the possible overflow, only divide by p,
int get_powers(int n, int p) {
int result = 0;
n /= p;
do {
result += n;
n /= p;
}while(n > 0);
return result;
}
From the comments:
I edited to add my functions to get primes till constant number "maxn0" – userG 2 hours ago
What value have you chosen for maxn0? – Daniel Fischer 2 hours ago
maxn0 = 10000
That value is too small.
With the primes to 10000, you are only guaranteed to correctly factorise numbers not exceeding 108 (well, since the next prime is 10007, numbers smaller than 10007² = 100140049), but the limit is given as 231, which is much larger.
Whenever a number m is given with two (not necessarily distinct) prime factors larger than 10000, you will not correctly factorise that, and that will usually lead to a wrong answer.
You need all primes ≤ √(231-1), that is all primes < 46340 to obtain the correct factorisation of all admissible m.
EDIT: wrong answer due to a misanderstanding of the question.
9 divides 7! but your algorithm will answer false because get_powers(7, 3) == 0 and 3 is a factor of 9.
It is not your implementation that is wrong but your algorithm.
Euler published the remarkable quadratic formula:
n² + n + 41
It turns out that the formula will produce 40 primes for the consecutive
values n = 0 to 39. However, when n =
40, 40^(2) + 40 + 41 = 40(40 + 1) + 41
is divisible by 41, and certainly when
n = 41, 41² + 41 + 41 is clearly
divisible by 41.
Using computers, the incredible formula n² − 79n + 1601 was
discovered, which produces 80 primes
for the consecutive values n = 0 to
79. The product of the coefficients, −79 and 1601, is −126479.
Considering quadratics of the form:
n² + an + b, where |a| < 1000 and |b| < 1000
where |n| is the modulus/absolute value of n
e.g. |11| = 11 and |−4| = 4
Find the product of the coefficients, a and b, for the
quadratic expression that produces the
maximum number of primes for
consecutive values of n, starting with
n = 0.
This is the problem for Euler 27.
I have attempted a solution for trying to find the equation n^2 + n + 41 to see if my logic is correct then I will attempt to see if it works on the actual problem. Here is my code (I will place comments explaining the whole program also, I would start reading from the int main function first) just make sure to read the comments so you can understand my logic:
#include <iostream>
using namespace std;
bool isPrime(int c) {
int test;
//Eliminate with some simple primes to start off with to increase speed...
if (c == 2) {
return true;
}
if (c == 3) {
return true;
}
if (c == 5) {
return true;
}
//Actual elimination starts here.
if (c <= 1 || c % 2 == 0 || c % 3 == 0 || c % 5 == 0) {
return false;
}
//Then using brute force test if c is divisible by anything lower than it except 1
//only if it gets past the first round of elimination, and if it doesn't
//pass this round return false.
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
//If the c pasts all these tests it should be prime, therefore return true.
return true;
}
int main (int argc, char * const argv[]) {
//a as in n^2 + "a"n + b
int a = 0;
//b as in n^2 + an + "b"
int b = 0;
//n as in "n"^2 + a"n" + b
int n = 0;
//this will hold the result of n^2 + an + b so if n = 1 a = 1
//and b = 1 then c = 1^2 + 1(1) + 1 = 3
int c = 0;
//bestChain: This is to keep track for the longest chain of primes
//in a row found.
int bestChain = 0;
//chain: the current amount of primes in a row.
int chain = 0;
//bestAB: Will hold the value for the two numbers a and b that
// give the most consecutive primes.
int bestAB[2] = { 0 };
//Check every value of a in this loop
for (a = 0; a < 40; a++) {
//Check every value of b in this loop.
for (b = 0; b < 42; b++) {
//Give c a starting value
c = n*n + a*n + b;
//(1)Check if it is prime. And keep checking until it is not
//and keep incrementing n and the chain. (2)If it not prime then che
//ck if chain is the highest chain and assign the bestChain
// to the current chain. (3)Either way reset the values
// of n and chain.
//(1)
while (isPrime(c) == true) {
n++;
c = n*n + a*n + b;
chain++;
}
//(2)
if (bestChain < chain) {
bestChain = chain;
bestAB[0] = a;
bestAB[1] = b;
chain = 0;
n = 0;
}
//(3)
else {
n = 0;
chain = 0;
}
}
}
//Lastly print out the best values of a and b.
cout << bestAB[0] << " " << bestAB[1];
return 0;
}
But, I get the results 0 and 2 for a and b respectively, why is this so? Where am I going wrong? If it is still unclear just ask for more clarification on a specific area.
Your isprime method is inefficient -- but also wrong:
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
in the first iteration of the for loop, test = c, so c % test is just c % c, which will always be 0. So your isprime method claims everything is non-prime (other than 2, 3, 5)
for (test = c; test > 1; test--) {
if (c % test == 0) {
return false;
}
}
Do you see the problem with that? If not, try working out some small sample values by hand.
As pointed out by others, your problem is in the isPrime method (test = c, so test % c = c % c == 0 is always true).
You can make your isPrime function run in O(sqrt(n)) instead of O(n) by initializing test to sqrt(c) (and only checking odd numbers). It is easy to see that if a number A is divisible by B < sqrt(A), then C = A/B must be > sqrt(A). Thus if there are no divisors < sqrt(A), there will be no divisors > sqrt(A).
Of course, you can run it a whole lot faster even, by using a probabilistic primality test, e.g. Miller-Rabin's primality test.
Also, I'm not sure, but I suspect you might reach the limit of int fairly quickly. It's probably a better idea to use unsigned long long from the start, before you start getting strange errors due to overflow & wrapping.
The sequence of triangle numbers is
generated by adding the natural
numbers. So the 7th triangle number
would be 1 + 2 + 3 + 4 + 5 + 6 + 7 =
28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55,
...
Let us list the factors of the first
seven triangle numbers:
1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first
triangle number to have over five
divisors.
Given an integer n, display the first
triangle number having at least n
divisors.
Sample Input: 5
Output 28
Input Constraints: 1<=n<=320
I was obviously able to do this question, but I used a naive algorithm:
Get n.
Find triangle numbers and check their number of factors using the mod operator.
But the challenge was to show the output within 4 seconds of input. On high inputs like 190 and above it took almost 15-16 seconds. Then I tried to put the triangle numbers and their number of factors in a 2d array first and then get the input from the user and search the array. But somehow I couldn't do it: I got a lot of processor faults. Please try doing it with this method and paste the code. Or if there are any better ways, please tell me.
Here's a hint:
The number of divisors according to the Divisor function is the product of the power of each prime factor plus 1. For example, let's consider the exponential prime representation of 28:
28 = 22 * 30 * 50 * 71 * 110...
The product of each exponent plus one is: (2+1)*(0+1)*(0+1)*(1+1)*(0+1)... = 6, and sure enough, 28 has 6 divisors.
Now, consider that the nth triangular number can be computed in closed form as n(n+1)/2. We can multiply numbers written in the exponential prime form simply by adding up the exponents at each position. Dividing by two just means decrementing the exponent on the two's place.
Do you see where I'm going with this?
Well, you don't go into a lot of detail about what you did, but I can give you an optimization that can be used, if you didn't think of it...
If you're using the straightforward method of trying to find factors of a number n, by using the mod operator, you don't need to check all the numbers < n. That obviously would take n comparisons...you can just go up to floor(sqrt(n)). For each factor you find, just divide n by that number, and you'll get the conjugate value, and not need to find it manually.
For example: say n is 15.
We loop, and try 1 first. Yep, the mod checks out, so it's a factor. We divide n by the factor to get the conjugate value, so we do (15 / 1) = 15...so 15 is a factor.
We try 2 next. Nope. Then 3. Yep, which also gives us (15 / 3) = 5.
And we're done, because 4 is > floor(sqrt(n)). Quick!
If you didn't think of it, that might be something you could leverage to improve your times...overall you go from O(n) to O(sqrt (n)) which is pretty good (though for numbers this small, constants may still weigh heavily.)
I was in a programming competition way back in school where there was some similar question with a run time limit. the team that "solved" it did as follows:
1) solve it with a brute force slow method.
2) write a program to just print out the answer (you found using the slow method), which will run sub second.
I thought this was bogus, but they won.
see Triangular numbers: a(n) = C(n+1,2) = n(n+1)/2 = 0+1+2+...+n. (Formerly M2535 N1002)
then pick the language you want implement it in, see this:
"... Python
import math
def diminishing_returns(val, scale):
if val < 0:
return -diminishing_returns(-val, scale)
mult = val / float(scale)
trinum = (math.sqrt(8.0 * mult + 1.0) - 1.0) / 2.0
return trinum * scale
..."
First, create table with two columns: Triangle_Number Count_of_Factors.
Second, derive from this a table with the same columns, but consisting only of the 320 rows of the lowest triangle number with a distinct number of factors.
Perform your speedy lookup to the second table.
If you solved the problem, you should be able to access the thread on Project Euler in which people post their (some very efficient) solutions.
If you're going to copy and paste a problem, please cite the source (unless it was your teacher who stole it); and I second Wouter van Niferick's comment.
Well, at least you got a good professor. Performance is important.
Since you have a program that can do the job, you can precalculate all of the answers for 1 .. 320.
Store them in an array, then simply subscript into the array to get the answer. That will be very fast.
Compile with care, winner of worst code of the year :D
#include <iostream>
bool isPrime( unsigned long long number ){
if( number != 2 && number % 2 == 0 )
return false;
for( int i = 3;
i < static_cast<unsigned long long>
( sqrt(static_cast<double>(number)) + 1 )
; i += 2 ){
if( number % i == 0 )
return false;
}
return true;
}
unsigned int p;
unsigned long long primes[1024];
void initPrimes(){
primes[0] = 2;
primes[1] = 3;
unsigned long long number = 5;
for( unsigned int i = 2; i < 1024; i++ ){
while( !isPrime(number) )
number += 2;
primes[i] = number;
number += 2;
}
return;
}
unsigned long long nextPrime(){
unsigned int ret = p;
p++;
return primes[ret];
}
unsigned long long numOfDivs( unsigned long long number ){
p = 0;
std::vector<unsigned long long> v;
unsigned long long prime = nextPrime(), divs = 1, i = 0;
while( number >= prime ){
i = 0;
while( number % prime == 0 ){
number /= prime;
i++;
}
if( i )
v.push_back( i );
prime = nextPrime();
}
for( unsigned n = 0; n < v.size(); n++ )
divs *= (v[n] + 1);
return divs;
}
unsigned long long nextTriNumber(){
static unsigned long long triNumber = 1, next = 2;
unsigned long long retTri = triNumber;
triNumber += next;
next++;
return retTri;
}
int main()
{
initPrimes();
unsigned long long n = nextTriNumber();
unsigned long long divs = 500;
while( numOfDivs(n) <= divs )
n = nextTriNumber();
std::cout << n;
std::cin.get();
}
def first_triangle_number_with_over_N_divisors(N):
n = 4
primes = [2, 3]
fact = [None, None, {2:1}, {3:1}]
def num_divisors (x):
num = 1
for mul in fact[x].values():
num *= (mul+1)
return num
while True:
factn = {}
for p in primes:
if p > n//2: break
r = n // p
if r * p == n:
factn = fact[r].copy()
factn[p] = factn.get(p,0) + 1
if len(factn)==0:
primes.append(n)
factn[n] = 1
fact.append(factn)
(x, y) = (n-1, n//2) if n % 2 == 0 else (n, (n-1)//2)
numdiv = num_divisors(x) * num_divisors(y)
if numdiv >= N:
print('Triangle number %d: %d divisors'
%(x*y, numdiv))
break
n += 1
>>> first_triangle_number_with_over_N_divisors(500)
Triangle number 76576500: 576 divisors
Dude here is ur code, go have a look. It calculates the first number that has divisors greater than 500.
void main() {
long long divisors = 0;
long long nat_num = 0;
long long tri_num = 0;
int tri_sqrt = 0;
while (1) {
divisors = 0;
nat_num++;
tri_num = nat_num + tri_num;
tri_sqrt = floor(sqrt((double)tri_num));
long long i = 0;
for ( i=tri_sqrt; i>=1; i--) {
long long remainder = tri_num % i;
if ( remainder == 0 && tri_num == 1 ) {
divisors++;
}
else if (remainder == 0 && tri_num != 1) {
divisors++;
divisors++;
}
}
if (divisors >100) {
cout <<"No. of divisors: "<<divisors<<endl<<tri_num<<endl;
}
if (divisors > 500)
break;
}
cout<<"Final Result: "<<tri_num<<endl;
system("pause");
}
Boojum's answer motivated me to write this little program. It seems to work well, although it does use a brute force method of computing primes. It's neat how all the natural numbers can be broken down into prime number components.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <vector>
//////////////////////////////////////////////////////////////////////////////
typedef std::vector<size_t> uint_vector;
//////////////////////////////////////////////////////////////////////////////
// add a prime number to primes[]
void
primeAdd(uint_vector& primes)
{
size_t n;
if (primes.empty())
{
primes.push_back(2);
return;
}
for (n = *(--primes.end()) + 1; ; ++n)
{
// n is even -> not prime
if ((n & 1) == 0) continue;
// look for a divisor in [2,n)
for (size_t i = 2; i < n; ++i)
{
if ((n % i) == 0) continue;
}
// found a prime
break;
}
primes.push_back(n);
}
//////////////////////////////////////////////////////////////////////////////
void
primeFactorize(size_t n, uint_vector& primes, uint_vector& f)
{
f.clear();
for (size_t i = 0; n > 1; ++i)
{
while (primes.size() <= i) primeAdd(primes);
while (f.size() <= i) f.push_back(0);
while ((n % primes[i]) == 0)
{
++f[i];
n /= primes[i];
}
}
}
//////////////////////////////////////////////////////////////////////////////
int
main(int argc, char** argv)
{
// allow specifying number of TN's to be evaluated
size_t lim = 1000;
if (argc > 1)
{
lim = atoi(argv[1]);
}
if (lim == 0) lim = 1000;
// prime numbers
uint_vector primes;
// factors of (n), (n + 1)
uint_vector* f = new uint_vector();
uint_vector* f1 = new uint_vector();
// sum vector
uint_vector sum;
// prime factorize (n)
size_t n = 1;
primeFactorize(n, primes, *f);
// iterate over triangle-numbers
for (; n <= lim; ++n)
{
// prime factorize (n + 1)
primeFactorize(n + 1, primes, *f1);
while (f->size() < f1->size()) f->push_back(0);
while (f1->size() < f->size()) f1->push_back(0);
size_t numTerms = f->size();
// compute prime factors for (n * (n + 1) / 2)
sum.clear();
size_t i;
for (i = 0; i < numTerms; ++i)
{
sum.push_back((*f)[i] + (*f1)[i]);
}
--sum[0];
size_t numFactors = 1, tn = 1;
for (i = 0; i < numTerms; ++i)
{
size_t exp = sum[i];
numFactors *= (exp + 1);
while (exp-- != 0) tn *= primes[i];
}
std::cout
<< n << ". Triangle number "
<< tn << " has " << numFactors << " factors."
<< std::endl;
// prepare for next iteration
f->clear();
uint_vector* tmp = f;
f = f1;
f1 = tmp;
}
delete f;
delete f1;
return 0;
}