I was writing an algorithm for a problem that goes as follows:
Consider an algorithm that takes as input a positive integer n. If n is even, the algorithm divides it by two, and if n is odd, the algorithm multiplies it by three and adds one. The algorithm repeats this until n is one. For example, the sequence for n=3 is as follows:
3→10→5→16→8→4→2→1
Original question can be found here
The algorithm that I wrote for it is as follows:
#include <iostream>
#include<vector>
using namespace std;
void check(long int n, vector<int> &arr);
int main(){
long int n;
cin>>n;
vector<int> arr; //Vector to store values of n
check(n,arr);
for(unsigned int i=0;i<arr.size();i++){
cout<<arr[i]<<' '; //Printing the final values of n
}
return 0;
}
void check(long int n,vector<int> &arr){
arr.push_back(n);
if(n%2==0){ //if n is even
n=n/2;
if(n!=1){
check(n,arr);
}
else if(n==1){
arr.push_back(1);
}
}
else{ //if n is odd
n=(n*3)+1;
if(n!=1){
check(n,arr);
}
else if(n==1){
arr.push_back(1);
}
}
return;
}
My solution is working perfectly for smaller values of n. However when n becomes large enough- especially somewhere around 138367(this was the first test case when the answer got wrong according to the compiler), the values of n printed at the end also start to include some 'negative numbers', which is somewhat unreasonable.
For instance, if I input n=986089625, in the beginning, the next number that follows it in the end result is -1336698420. While the correct number should be 2958268876. Surprisingly the next number that follows is correct, but at certain (random) intervals, the numbers are becoming negative.
I know the algorithm can be simplified further, but I'm not able to understand the problem with this one. I assume there's something subtle that I'm missing!
You can see how this works with this simple example
#include <limits.h>
#include <iostream>
int main()
{
int n = INT_MAX;
std::cout << "n=" << n << '\n';
std::cout << "n+1=" << n + 1 << '\n';
unsigned m = UINT_MAX;
std::cout << "m=" << m << '\n';
std::cout << "m+1=" << m + 1 << '\n';
}
giving
n=2147483647
n+1=-2147483648
m=4294967295
m+1=0
When the limit is reached, a wrap around occurs to either INT_MIN or zero, depending on the signedness of the integer type.
The same happens also in the opposite direction of course, wrapping from INT_MIN to INT_MAX or from zero to UINT_MAX.
Typical int (signed 32-bit long) can store numbers only upto 2,147,483,647 (2**31 - 1) and the number 2958268876 exceeds this limit.
You are using long int for calculation, so you should use it also for the elements of vector.
In other words, the three vector<int>s should be replaced with vector<long int>.
Related
I'm trying to solve Fibonacci using C++, but my code shows negative numbers when the output digit limit crosses with big numbers.
#include<stdio.h>
#include<iostream>
using namespace std;
int64_t get_fibonacci_last_digit_naive(int n)
{
int64_t a = 0, c, i;
int64_t b = 1;
if (n == 0)
return (a);
for (i = 2; i <= n; i++)
{
c = a + b;
a = b;
b = c;
}
return (b);
}
int main()
{
int n;
cin >> n;
cout << get_fibonacci_last_digit_naive(n) << '\n';
return 0;
}
so when my input is 239, my out put shows
239
-1716907696316940191
Process returned 0 (0x0) execution time : 12.395 s
Press any key to continue.
Now how i can store digits with no upper limits in C++?. i am very noob and exlpain me thinking that i dont know anythg. so huw can i print digits more than 30 in c++?
The built-in integer data types in C++ can only store values in a given range. For int64 that would be -263 to 263-1 (NOTE: prior to C++20 the standard allows for different signed integer representations so in theory the limits listed may differ by +/- 1). If a calculation results in values outside of this range you will get integer over flow and your value will continue from the other end of the range. This is the reason you see negative values - the 239-th Fibonacci number is actually very big(it has 50 digits in its decimal notation) and can not be stored in any built-in data type.
On the other hand to compute only the last digit of the 239-th Fibonacci number you do not need to actually compute the whole value. In fact for any number in decimal notation its last digit is the remainder of the number when divided by 10 (i.e. the last digit of X is X%10). This also applies for arithmetic operations for instance the last digit of A + B is (A % 10 + B % 10) % 10. I hope this tip helps you solve the problem on your own.
For starters pay attention to that this header
#include<stdio.h>
is redundant. Neither declaration from the header is used in your program.
And in C++ you should at least specify
#include <cstdio>
if a declaration from the header is required.
To get such a big fibonacci number as the 239-th fibonacci number you need to use a special library that provides services for processing big numbers or you have to write such services yourself by using for example the standard class std::string.
However to get the last digit of a fibonacci number there is no need to calculate the whole fibonacci number. It is enough to track only last digits.
Here is my naive approach.:)
#include <iostream>
#include <functional>
unsigned int get_fibonacci_last_digit_my_naive( unsigned int n )
{
const unsigned int Base = 10;
unsigned int a[] = { 0, 1 };
while (n--)
{
a[1] += std::exchange( a[0], a[1] );
a[1] %= Base;
}
return a[0];
}
int main()
{
unsigned int n = 0;
std::cin >> n;
std::cout << "The last digit of the " << n << "-th fibonacci number is "
<< get_fibonacci_last_digit_my_naive( n ) << '\n';
return 0;
}
The program output is
The last digit of the 239-th fibonacci number is 1
Or if to change the function main the following way
int main()
{
unsigned int n = 0;
std::cin >> n;
for ( unsigned int i = n; i < n + 10; i++ )
{
std::cout << "The last digit of the " << i << "-th fibonacci number is "
<< get_fibonacci_last_digit_my_naive( i ) << '\n';
}
return 0;
}
and to enter the number 230 then the program output will be
The last digit of the 230-th fibonacci number is 5
The last digit of the 231-th fibonacci number is 4
The last digit of the 232-th fibonacci number is 9
The last digit of the 233-th fibonacci number is 3
The last digit of the 234-th fibonacci number is 2
The last digit of the 235-th fibonacci number is 5
The last digit of the 236-th fibonacci number is 7
The last digit of the 237-th fibonacci number is 2
The last digit of the 238-th fibonacci number is 9
The last digit of the 239-th fibonacci number is 1
I've written the following C++ code to factorize really large numbers efficiently (numbers up to 24997300729).
I have a vector containing 41000 primes approx.( I know having such a large vector isn't a good idea although but couldn't figure a way around this).
This code produces the prime factorization of moderately large numbers in no time but when it comes to numbers such as, 24997300572 the program stalls.
Here's the program below with some screenshots of the output:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cmath>
using namespace std;
vector<int> primes = {paste from
https://drive.google.com/file/d/1nGvtMMQSa9YIDkMW2jgEbJk67P7p54ft/view?usp=sharing
};
void factorize(int n) {
if (n == 1)
return;
if (find(primes.begin(), primes.end(), n) != primes.end()) {
cout << n <<" "; //if n is prime dont'proceed further
return;
}
//obtaining an iterator to the location of prime equal to or just greater than sqrt(n)
auto s = sqrt(n);
vector<int>::iterator it = lower_bound(primes.begin(), primes.end(), s);
if (it == primes.end()) {
return; // if no primes found then the factors are beyond range
}
for (auto i = it;i != primes.begin();i--) {
if (n % *i == 0)
{
cout << *i << " ";
n = n / (*i);
factorize(n);
return; // the two consecutive for() loops should never run one after another
}
}
for (auto i = it;i != primes.end();i++) {
if (n % *i == 0)
{
cout << *i << " ";
n = n / (*i);
factorize(n);
return; // the two consecutive for() loops should never run one after another
}
}
}
int main() {
unsigned int n;
cout << "Enter a number between 1 and 24997300729 ";
cin >> n;
if (n > 24997300729) {
cout << "Number out of range;";
exit(-1);
}
factorize(n);
return 0;
}
This is OK
But This is NOT!!!
I tried using long long int and long double wherever I could to over come the problem of large numbers, but that didn't help much.
Any help Would Be Greatly Appreciated
It's a little unclear (at least to me) exactly why you've structured the program the way you have.
You can fully factor a number by only looking for prime factors less than or equal to that number's square root. Any prime factor larger than those pairs with one prime factors smaller than that, so you only have to search for those to find all the prime factors. Any remaining factors can be obtained by simple division, not searching.
I'd probably generate the base of prime numbers on the fly (mostly likely using a sieve). The square root of 24'997'300'729 is (about) 158'105. A quick test shows that even without any work on optimization, a sieve of Eratosthenes will find the primes up to that limit in about 12 milliseconds.
Personally, I'd rather not have a fixed limit on the largest number the user can factor, other than the limit on the size of number we're working with, so if the user enters something close to the limit for a 64-bit number, we find all the primes that fit in 32 bits, and then use those to factor the number. This will obviously be slower than if we don't find as many primes, but a user probably won't be too surprised at the idea that factoring a larger number takes longer than factoring a smaller number.
So, implementing that, we might end up with code something like this:
#include <iostream>
#include <locale>
#include <vector>
#include <string>
using Number = unsigned long long;
auto build_base(Number limit) {
std::vector<bool> sieve(limit / 2, true);
for (Number i = 3; i < limit; i += 2) {
if (sieve[i / 2]) {
for (Number temp = i * i; temp < limit; temp += i)
if (temp & 1)
sieve[temp / 2] = false;
}
}
return sieve;
}
void factor(Number input, std::vector<bool> const &candidates)
{
while (input % 2 == 0) {
std::cout << 2 << "\t";
input /= 2;
}
for (Number i = 1; i < candidates.size(); i++) {
if (candidates[i]) {
auto candidate = i * 2 + 1;
while ((input % candidate) == 0) {
std::cout << candidate << "\t";
input /= candidate;
}
}
}
if (input != 1)
std::cout << input;
}
int main(int argc, char **argv) {
std::cout.imbue(std::locale(""));
if (argc != 2) {
std::cerr << "Usage: factor <number>\n";
return EXIT_FAILURE;
}
auto number = std::stoull(argv[1]);
auto limit = std::sqrt(number) + 1;
auto candidates = build_base(limit);
factor(number, candidates);
}
At a high level, the code works like this: we start by finding the primes up to the square root of the number the user entered. Since we want all the primes up to a limit, we use a sieve of Eratosthenes to find them. This builds a vector of bools, in which vector[n] will be true if n is prime, and false if n is composite. It does this starting from 3 (2 is a special case we kind of ignore for now) and crossing off the multiples of three. Then it finds the next number that hasn't been crossed off (which will be five, in this case), and crosses off its multiples. It continues doing that until it reaches the end of the array. To save some space, it leaves all the even numbers out of the array, because (other than that special case for 2) we already know none of them is prime.
Once we have that, we use those prime numbers to find prime factors of the number we want to factor. This proceeds pretty simply: walk through the vector of primes, and test whether each prime number divides evenly into the target number. If it does, print it out, divide it out of the target number, and continue.
At least for me, this seems to work pretty dependably, and is reasonably fast. If we wanted to do a better job of factoring larger numbers, the next big step would be to switch to a segmented sieve. This can improve the speed of the first part of the job by a pretty wide margin, allowing us (for example) to factor anything that'll fit into a 64-bit number in no more than about 10 seconds.
I am trying to find out the number of perfect squares in the given range. The method I am following is provided on: digital_root
The code I have implemented is not giving correct answers sometimes because This method does not consider the numbers like 10,1000 etc.
Please help me to work out this method.
int cot=0;
void squares(int a,int b){
if(a==b){
int digit,digit_root=0,no;
no=a;
digit=no%10;
if(digit==2||digit==3||digit==7||digit==8){
}else{
no=a;
while(no>0){
digit=no%10;
if((digit==0)||(digit==9)){
}else{
digit_root=digit_root+digit;
digit_root=digit_root%9;
}
no=no/10;
}
if(digit_root==0||digit_root==7||digit_root==1||digit_root==4){
if(digit_root==1){
if(a)
}
cot++;
}
}
}else{
int c=(a+b)/2;
squares(a,c);
squares(c+1,b);
}
}
int main() {
int a,b,t;
cin>>t;
for(int i=0;i<t;i++){
cin >> a>>b;
squares(a,b);
cout << cot<<endl;
cot=0;
}
return 0;
}
the best algorithm will probably be to subtract sqrt(bigger number) - sqrt(other num), i.e. something like this
int a = 1,b=100;
if (sqrt(a) != int(sqrt(a)){
cout<<int(sqrt(b))-int(sqrt(a))<<endl;}
else{
cout<<int(sqrt(b))-int(sqrt(a))+1<<endl;}
the logic is very simple, perfect square is natural num * the same natural num so, 1*1,2*2,3*3,4*4 and so on
So you just need to get the closest perfect sqrt of the bigger num and subtract it with the smaller num (just be careful in case that the smallest num is a perfect square itself)
There's too much going on here. Simplify it. Write a function that determines whether a single number is a perfect square. Get that working right. Then use that function to determine how many perfect squares there are in your range. That probably shouldn't be recursive; that's just too hard to follow. Use a loop that covers the range:
for (int i = a; i <= b; ++i)
if (is_perfect_square(i))
++count;
It's easy to print numbers from 1 to N, and the numbers will be perfect square.
Here is the logic to check perfect square
/*function definition to check perfect square*/
int isPerfectSquare(int number)
{
int iVar;
float fVar;
fVar=sqrt((double)number);
iVar=fVar;
if(iVar==fVar)
return 1;
else
return 0;
}
You dont need all these costly calculations.
Things are really simple here.
Instead of looping from A to B and checking for perfect squares,
we can calculate the first integer square root of A at O(1) and
count the rest perfect squares with simple increments of power n,
up to B. In this way we can avoid costly calculations.
But even better, we can even avoid loops by just using ceil and floor.
For example, square numbers between 1000 and 2000:
sqrt(1000) = 31.6 --> ceil(31.6) --> 32
sqrt(2000) = 44.7 --> floor(44.7)--> 44
therefore the difference of these two plus one gives us the number of perfect squares.
#include <cmath>
#include <iostream>
using namespace std;
int main() {
int A, B;
//get the range [A,B]
cin >> A >> B;
cout << floor(sqrt(B)) - ceil(sqrt(A)) + 1 << end;
return 0;
}
I am working on solving Euler project 3:
Description: The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
This is my code to generate the answer. However I need an integer type to hold 600851475143. When I compile this on GCC on a Mac I get:
integer constant is too large for ‘long’ type".
I expect long long could easily hold this number. I also tried making it unsigned. Why doesn't my code hold that small number and what can I do to make it work?
#include <iostream>
#include <vector>
using namespace std;
static bool IsPrimeFactor(int numToTest,int testNum,vector<int> factors)
{
if(numToTest%testNum==0) // is it a factor?
{
// see if it is a prime factor
for(unsigned int i=0; i < factors.size(); i++)
{
if(testNum%factors[i]==0) // see if this factor
{ //is divisble by one we have already
return false;
}
}
return true;
}
return false;
}
int main() {
unsigned long long numToTest=600851475143;
unsigned int testNum=2; // 0 and 1 are assumed
vector<int> factors;
while(testNum<numToTest) // don't go higher than the max num
{
if(IsPrimeFactor(numToTest,testNum,factors)) // is it a factor?
{
factors.push_back(testNum); // got through prime factors
} // and none divided it
testNum++;
}
for(unsigned int i=0; i < factors.size(); i++)
{
cout << "factor " <<factors[i] << endl;
}
cout<<"Highest factor: " << factors[factors.size()-1]<<endl;
return 0;
}
Check this question. You have to specify your literal like this:
600851475143LL
As #Space_C0wb0y said, you need to specify a suffix for the literal.
Also, you're going to have a problem with your IsPrimeFactor function - the parameters are ints, but as you've already discovered, an int or even a long is not big enough to store the number you'll be passing in repeatedly...
Example: Let’s say your user input is 6.
Then the number of sequences that sum up to 6 is 11 (including 6 itself). This is shown clearly below:
6
5+1
4+1+1
3+1+1+1
2+1+1+1+1
1+1+1+1+1+1
2+2+1+1
3+2+1
4+2
2+2+2
3+3
You SHOULD NOT have any sequences that repeat. You cannot have 2+2+1+1 and 1+1+2+2 as two different combinations!!
CODE:
#include <iostream>
using namespace std;
int sum(double number, int min, int & counter)
{
int temp=0, n;
n=number+temp;
if ((number>=(n/2)) & (number!=0))
{
number --;
temp ++;
while (number>=(n/2))
{
cout << number << "+"<< temp << "\n";
number --;
temp ++;
counter ++;
}
}
else if (number==0)
{
return 0;
}
sum(n-min, 1,counter);
return 0;
}
int main()
{
int number, counter=1;
cout << "Please enter the number: ";
cin >> number ;
cout << "\n";
sum(number, 1, counter);
cout << counter;
return 0;
}
My output is
6
5+1
4+1+1
3+1+1+1
2+1+1+1+1
1+1+1+1+1+1
2+2+1+1
3+2+1
3+1+2
2+3+1
4+2
2+2+2
3+3
0+1
Total out is 13.
Real output which is a shorter version for those of you who dont like whats posted above.
5+1
4+2
3+3
4+1
3+2
2+3
3+1
2+2
2+1
1+2
1+1
0+1
13
Where 1+2 and 2+3 are doubles as listed above.
Any ideas what is wrong here?
I guess it would be easier if you'd sum so that the first summand is always highest possible and you don't allow that of two adjacent summands the second one is greater than the first one.
Just a thought...
I've already posted a solution to it in your previous question:
void sum_r(int n, int m, int cnt, int* nums){
for (;n >= m; m++)
sum_r(n-m, nums[cnt] = m, cnt+1, nums);
if (!n) for (int i=0; i<cnt; i++) printf("%d%c",nums[i],(i==cnt-1)?'\n':'+');
};
void sum(int n){
int nums[100];
return sum_r(n, 1, 0, nums);
};
int main(){
sum(6);
return 0;
};
EDIT: I'll try to explain it better. The main idea is to impose an order on the generated sequence, it will help in avoiding repetition.
We will use the min parameter for that, it will be the smallest possible term we can use from now on in the sequence.
The function sum_r just prints the sequence of values of min at each recursion level.
The num term is used as a kind of accumulator, or the value left "to spare".
We can write a simplier function, that just counts the number of such sequences:
int sum_c(int n, int m){
if (!n) return 1; // termination condition. end of sequence reached with "perfect match". this means we have found 1 additional sequence. Note that it's the only way of adding new values to result.
int comb_cnt = 0;
while (n >= m) { // we need a stop condition, and there is no point in having negative value of (n - m)
comb_cnt += // here we accumulate all the solutions from next levels
sum_c(n-m, m); // how many sequences are for current value of min?
m++; // trying a larger `min`
};
return comb_cnt; // number of sequence fond at this level
};
Here's a hint: The problem is to compute the partitions of the input number. See also: partition function
Well the logical AND operator in C++ is &&, not & as you have in this line:
if ((number>=(n/2)) & (number!=0))