I am trying to solve Project Euler 14 and the output is always zero.
The basic Idea is n/2 when n is even and 3n + 1 when n is odd.
Then if m/2 < n or m < n (where m/2 or m is previous number whose number had already been calculated) give the number of iterations as iterations stored.
I am storing the iterations of previous numbers.
#include<iostream>
using namespace std;
bool ok=true;
unsigned long int p[1000001]; //initialization of array p to store iterations
unsigned long int q[2]={1,1}; // initialization of two element array to store the max sequence number
unsigned long int x=0;
int Colltz(unsigned long int num,unsigned long int count) { // function starts
unsigned long int j=num;
p[0]=0; //Initial iterations for 1 and 2
p[1]=1; // Initial value for 1
p[2]=2; // Initial val for 3
while(ok) { // while loop
if((j%2==0)&&(j/2>num)) { //(to check whether j is available in the array if not it divides it further until j/2<num
j=j/2;
++count;
}
if((j%2==0)&&((j/2)<num)) { // since j/2 the arry should contin the number and the collatz vlue is +1
++count;
p[num]=p[j/2]+count;
ok=false;
break;
}
if ((j%2)!=0) { //if it is odd
j=3*j+1;
++count;
Colltz(j,count);
}
if(j<num) { // if j < num then j is Collatz of j is calculated and added
p[num]=p[j]+count;
ok=false;
break;
}
if((p[num]>=q[1])) {
q[0]=num; // to get the max count
q[1]=p[num];
}
}// end of while loop
return q[1];
}
int main() {
unsigned long int i=3;
unsigned long int j=0;
int counted=1;
while(i<6) {
j=Colltz(i,counted);
++i;
}
cout<<j;
}
So basically my function should take in the number (for which I have initialized count to 0) and then find out whether it is even or odd and if it is even whether it is greater than n or less and then follow steps accordingly and if it is odd whether it is less than n and calculate accordingly.
Your code seems a little bit messed up! Check my solution and see whether that helps :
#include <stdio.h>
unsigned long int Collatz(unsigned long int);
int main()
{
unsigned long int n,i,bingo;
int ChainLen=0;
for(i=1;i<=1000000;i++)
{
if((n=Collatz(i)) > ChainLen)
{
ChainLen=n;
bingo=i;
}
}
printf("\n%lu\n",bingo);
return 0;
}
unsigned long int Collatz(unsigned long int x)
{
if(x==1)
return 1;
if(x%2==0)
{
return 1 + Collatz(x/2);
}
else
return 1 + Collatz(x * 3 + 1);
}
Related
Consistently comparing digits symmetrically to its middle digit. If first number is bigger than the last , first is wining and I have to display it else I display last and that keep until I reach middle digit(this is if I have odd number of digits), if digit don't have anything to be compared with it wins automatically.
For example number is 13257 the answer is 7 5 2.
Another one 583241 the answer is 5 8 3.
For now I am only trying to catch when number of digits is odd. And got stuck.. This is my code. The problem is that this code don't display any numbers, but it compares them in the if statement(I checked while debugging).
#include <iostream>
using namespace std;
int countDigit(int n) {
int count = 0;
while (n != 0) {
count++;
n /= 10;
}
return count;
}
int main() {
int n;
cin >> n;
int middle;
int count = countDigit(n);
if (count % 2 == 0) {
cout<<"No mid digit exsist!!";
}
else {
int lastDigit = n % 10;
middle = (count + 1) / 2;
for (int i = 0; i < middle; i++) {
for (int j = lastDigit; j<middle; j--) {
if (i > j) {
cout << i <<' ';
}
else {
cout << j;
}
}
}
}
return 0;
}
An easier approach towards this, in my opinion, would be using strings. You can check the size of the string. If there are even number of characters, you can just compare the first half characters, with the last half. If there are odd numbers, then do the same just print the middle character.
Here's what I'd do for odd number of digits:
string n;
cin>>n;
int i,j;
for(i=0,j=n.size()-1;i<n.size()/2,j>=(n.size()+1)/2;i++,j--)
{
if(n[i]>n[j]) cout<<n[i]<<" ";
else cout<<n[j]<<" ";
}
cout<<n[n.size()/2]<<endl;
We analyze the requirements and then come up with a design.
If we have a number, consisting of digits, we want to compare "left" values with "right" values. So, start somehow at the left and the right index of digits in a number.
Look at this number: 123456789
Index: 012345678
Length: 9
in C and C++ indices start with 0.
So, what will we do?
Compare index 0 with index 8
Compare index 1 with index 7
Compare index 2 with index 6
Compare index 3 with index 5
Compare index 4 with index 4
So, the index from the left is running up and the index from the right is running down.
We continue as long as the left index is less than or equal the right index. All this can be done in a for or while loop.
It does not matter, wether the number of digits is odd or even.
Of course we also do need functions that return the length of a number and a digit of the number at a given position. But I see that you know already how to write these functions. So, I will not explain it further here.
I show you 3 different examples.
Ultra simple and very verbose. Very inefficient, because we do not have arrays.
Still simple, but more compressed. Very inefficient, because we do not have arrays.
C++ solution, not allowed in your case
Verbose
#include <iostream>
// Get the length of a number
unsigned int length(unsigned long long number) {
unsigned int length = 0;
while (number != 0) {
number /= 10;
++length;
}
return length;
}
// Get a digit at a given index of a number
unsigned int digitAt(unsigned int index, unsigned long long number) {
index = length(number) - index - 1;
unsigned int result = 0;
unsigned int count = 0;
while ((number != 0) && (count <= index)) {
result = number % 10;
number /= 10;
++count;
}
return result;
}
// Test
int main() {
unsigned long long number;
if (std::cin >> number) {
unsigned int indexLeft = 0;
unsigned int indexRight = length(number) - 1;
while (indexLeft <= indexRight) {
if (digitAt(indexLeft, number) > digitAt(indexRight, number)) {
std::cout << digitAt(indexLeft, number);
}
else {
std::cout << digitAt(indexRight, number);
}
++indexLeft;
--indexRight;
}
}
}
Compressed
#include <iostream>
// Get the length of a number
size_t length(unsigned long long number) {
size_t length{};
for (; number; number /= 10) ++length;
return length;
}
// Get a digit at a given index of a number
unsigned int digitAt(size_t index, unsigned long long number) {
index = length(number) - index - 1;
unsigned int result{}, count{};
for (; number and count <= index; ++count, number /= 10)
result = number % 10;
return result;
}
// Test
int main() {
if (unsigned long long number; std::cin >> number) {
// Iterate from left and right at the same time
for (size_t indexLeft{}, indexRight{ length(number) - 1 }; indexLeft <= indexRight; ++indexLeft, --indexRight)
std::cout << ((digitAt(indexLeft,number) > digitAt(indexRight, number)) ? digitAt(indexLeft, number) : digitAt(indexRight, number));
}
}
More modern C++
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
if (std::string numberAsString{}; std::getline(std::cin, numberAsString) and not numberAsString.empty() and
std::all_of(numberAsString.begin(), numberAsString.end(), std::isdigit)) {
for (size_t indexLeft{}, indexRight{ numberAsString.length() - 1 }; indexLeft <= indexRight; ++indexLeft, --indexRight)
std::cout << ((numberAsString[indexLeft] > numberAsString[indexRight]) ? numberAsString[indexLeft] : numberAsString[indexRight]);
}
}
You are trying to do something confusing with nested for-cycles. This is obviously wrong, because there is nothing “quadratic” (with respect to the number of digits) in the entire task. Also, your code doesn’t seem to contain anything that would determine the highest-order digit.
I would suggest that you start with something very simple: string’ify the number and then iterate over the digits in the string. This is obviously neither elegant nor particularly fast, but it will be a working solution to start with and you can improve it later.
BTW, the sooner you get out of the bad habit of using namespace std; the better. It is an antipattern, please avoid it.
Side note: There is no need to treat odd and even numbers of digits differently. Just let the algorithm compare the middle digit (if it exists) against itself and select it; no big deal. It is a tiny efficiency drawback in exchange for a big code simplicity benefit.
#include <cstdint>
#include <iostream>
#include <string>
using std::size_t;
using std::uint64_t;
uint64_t extract_digits(uint64_t source) {
const std::string digits{std::to_string(source)};
auto i = digits.begin();
auto j = digits.rbegin();
const auto iend = i + (digits.size() + 1) / 2;
uint64_t result{0};
for (; i < iend; ++i, ++j) {
result *= 10;
result += (*i > *j ? *i : *j) - '0';
}
return result;
}
int main() {
uint64_t n;
std::cin >> n;
std::cout << extract_digits(n) << std::endl;
}
If the task disallows the use of strings and arrays, you could try using pure arithmetics by constructing a “digit-inverted” version of the number and then iterating over both numbers using division and modulo. This will (still) have obvious limitations that stem from the data type size, some numbers cannot be inverted properly etc. (Use GNU MP for unlimited integers.)
#include <cstdint>
#include <iostream>
using std::size_t;
using std::uint64_t;
uint64_t extract_digits(uint64_t source) {
uint64_t inverted{0};
size_t count{0};
for (uint64_t div = source; div; div /= 10) {
inverted *= 10;
inverted += div % 10;
++count;
}
count += 1;
count /= 2;
uint64_t result{0};
if (count) for(;;) {
const uint64_t a{source % 10}, b{inverted % 10};
result *= 10;
result += a > b ? a : b;
if (!--count) break;
source /= 10;
inverted /= 10;
}
return result;
}
int main() {
uint64_t n;
std::cin >> n;
std::cout << extract_digits(n) << std::endl;
}
Last but not least, I would strongly suggest that you ask questions after you have something buildable and runnable. Having homework solved by someone else defeats the homework’s purpose.
I wish to find a random prime number over one million but my program only outputs one maybe half the time.
When it doesn't it will just output nothing.
unsigned long long int primeFinder(unsigned long long int base) {
int flag = 0;
unsigned long long int m = base / 2;
for (int i = 2; i <= m; i++) {
if (base%i == 0) {
flag = 1;
break;
}
}
if (flag == 1) {
base = base + 2;
primeFinder(base);
}
else {
return base;
}
}
int main() {
srand(time(NULL));
unsigned long long int base;
base = 1000000;
int number = rand() % 1000000;
base += number;
cout<<primeFinder(base);
}
I am assuming this is because of my if statement, but I am not too sure about how to ensure it will return a prime number. I am using visual studio express 2017.
The main problem is that you do not ensure that your starting point is an odd number. Since you recursively call primeFinder() incrementing the "base" by two, this will result in endless recursion when the starting point is an even number, i.e. about half the time.
An easy way to fix this is to change the initial call as follows:
cout<<primeFinder(base|1);
Next, you only need to check for divisors up to the square root. This can be done by calculating m as follows:
unsigned long long int m = llround(sqrt(base));
Remember to #include<cmath>.
Furthermore, I would recommend restructuring primeFinder() to avoid the recursion and have a separate function to determine if a given number is a prime:
bool isPrime(unsigned long long int n)
{
unsigned long long int m = llround(sqrt(n));
for (int i = 2; i <= m; i++) {
if (n%i == 0) {
return false;
}
}
return (n>1);
}
unsigned long long int primeFinder(unsigned long long int base)
{
while(!isPrime(base))
{
base += 2;
}
return base;
}
Finally, when we have a while loop or a recursion, it is always good to know the worst case of how many iterations the program may need to perform.
In this case the question is: starting from an odd number n, what is the maximal value of the next prime, i.e. the smallest prime, p, such that p >= n?
To the help comes Bertrand's Postulate (which despite the name is actually a theorem) saying that p<2*n. Thus for a given starting value of base, primeFinder() will run at most about base/2 iterations (since we increment the guess by 2 for each iteration).
Thus, the worst case complexity of primeFinder() is O(n^(3/2)).
I'm trying to write a c++ program which gets an integer n (n>=1 && n<=100000) from the user and puts the sum of its digits into b. The output needed is the b-th prime number coming after n. I'm an absolute beginner in programming so I don't know what's wrong with the for loop or any other code that it doesn't show the correct output. For example the 3rd prime number after 12 (1+2=3) is 19 but the loop counts the prime numbers from 2 instead of 12, so it prints 7 as result.
#include <iostream>
using namespace std;
bool isPrime(int n)
{
if(n <= 1)
return false;
for(int i = 2; i <= (n/2); i++)
if(n % i == 0)
return false;
return true;
}
int main()
{
long int n;
int b = 0;
cin>>n;
while(n >= 1 && n <= 100000){
b += n % 10;
n /= 10;
}
for(int i = n, counter = b; counter <= 10; i++)
if(isPrime(i)){
counter++;
if(i > n)
cout<<counter<<"th prime number after n is : "<<i<<endl;
}
return 0;
}
So one of the possible solutions to my question, according to #Bob__ answer (and converting it to the code style I've used in the initial code) is as follows:
#include <iostream>
using namespace std;
bool isPrime(long int number)
{
if(number <= 1)
return false;
for(int i = 2; i <= (number / 2); i++)
if(number % i == 0)
return false;
return true;
}
int sumOfDigits(long int number)
{
int sum = 0;
while(number >= 1 && number <= 100000)
{
sum += number % 10;
number /= 10;
}
return sum;
}
long int bthPrimeAfter(int counter, long int number)
{
while(counter)
{
++number;
if(isPrime(number))
--counter;
}
return number;
}
int main()
{
long int number;
cin>>number;
int const counter = sumOfDigits(number);
cout<<bthPrimeAfter(counter, number)<<"\n";
return 0;
}
As dratenik said in their comment:
You have destroyed the value in n to produce b in the while loop. When the for loop comes around, n keeps being zero.
That's a key point to understand, sometimes we need to make a copy of a variable. One way to do that is passing it to a function by value. The function argument will be a local copy which can be changed without affecting the original one.
As an example, the main function could be written like the following:
#include <iostream>
bool is_prime(long int number);
// ^^^^^^^^ So is `n` in the OP's `main`
int sum_of_digits(long int number);
// ^^^^^^^^^^^^^^^ This is a local copy.
long int nth_prime_after(int counter, long int number);
int main()
{
long int number;
// The input validation (check if it's a number and if it's in the valid range,
// deal with errors) is left to the reader as an exercise.
std::cin >> number;
int const counter = sum_of_digits(number);
std::cout << nth_prime_after(counter, number) << '\n';
return 0;
}
The definition of sum_of_digits is straightforward.
int sum_of_digits(long int number)
{
int sum = 0;
while ( number ) // Stops when number is zero. The condition n <= 100000
{ // belongs to input validation, like n >= 0.
sum += number % 10;
number /= 10; // <- This changes only the local copy.
}
return sum;
}
About the last part (finding the nth prime after the chosen number), I'm not sure to understand what the asker is trying to do, but even if n had the correct value, for(int i = n, counter = b; counter <= 10; i++) would be just wrong. For starters, there's no reason for the condition count <= 10 or at least none that I can think of.
I'd write something like this:
long int nth_prime_after(int counter, long int number)
{
while ( counter )
{
++number;
if ( is_prime(number) )
{
--counter; // The primes aren't printed here, not even the nth.
}
}
return number; // Just return it, the printing is another function's
} // responsabilty.
A lot more could be said about the is_prime function and the overall (lack of) efficiency of this algorithm, but IMHO, it's beyond the scope of this answer.
I'm trying to find the last digit of the sum of the fibonacci series from a starting to an end point. As we find the last digit using %10 , Fibonnaci will repeat it's last digit sequence every 60 times - using the Pisano Series
My attempt at the solution:
We find the last digits of the first 60 digits, store them in an array and then continuously loop over and sum over the digits starting from n%60 to m. We then finally modulo 10 the result.
#include <iostream>
#include <vector>
using std::vector;
int fibonacci_fast(long long n,long long m) {
// write your code here
long long a[60];
a[0]=0;
a[1]=1;
long long sum=0;
for(long long i=2;i<60;i++)
{
a[i] = a[i-1]+a[i-2];
a[i] = a[i] % 10;
}
int j=0;
int p=1;
int c=0;
for(int i=n%60;;i++)
{
if(i==60)
{
i=i%60;
}
sum=sum+a[i];
c=c+1;
if(c==m)
{
break;
}
}
return sum%10;
}
int main() {
long long from, to;
std::cin >> from >> to;
std::cout << fibonacci_fast(from, to) << '\n';
}
The major issue I'm having with this current code is that for lower values, it works fine, but if I input higher values such as 0 to 239, It only works when the condition changes to if(c+1)==m which then results in the smaller values solutions turning wrong.
The c counter works correctly though and goes up to 239 but I still cannot figure out the issue with the code.
#include <vector>
using std::vector;
int fibonacci_fast(long long n,long long m) {
// write your code here
long long a[60];
a[0]=0;
a[1]=1;
long long sum=0;
sum = a[0] + a[1];
for(long long i=2;i<60;i++)
{
a[i] = a[i-1]+a[i-2];
a[i] = a[i] % 10;
sum = (sum + a[i]) % 10;
}
int x = (m - n + 1)/60;
sum = (sum * x) % 10;
int i = n + 60 * x;
while(i <= m)
{
sum = (sum + a[i%60]) % 10;
i++;
}
return sum;
}
int main() {
long long from, to;
std::cin >> from >> to;
std::cout << fibonacci_fast(from, to) << '\n';
}
I think you need to set the variable c to be equal to the value of n and not 0 (zero)
int c = n;
Also, please clear the concept whether you want to include the index m or not.
Example, if user enters:
n -> 10
m -> 20
Then your code provided above will add the last digit values of the Fibonacci numbers from the index 10 to the index 19 only. So please clear this doubt of mine, then I will add further.
I'm novice to Programming. I can find numbers consisting of even digits but my algorithm complexity is O(n). For large n my algorithm is too slow. So I need a more efficient algorithm. Can anyone help me?
For example, the first numbers with even digits are 0 , 2 , 4 , 6 , 8 , 20 , 22 , 24 , 26 , 28 , 40 etc. 2686 is another example of a number with even digits.
Here is my code: http://ideone.com/nsBzej
#include<bits/stdc++.h>
using namespace std;
long long int a[10],b[20];
long long int powr(int i)
{
long long int ans=5;
for(int j=2;j<=i;j++)
{
ans=ans*5;
}
return ans;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
long long int n,s,sum,p;
int t;
cin>>t;
for(int j=1;j<=t;j++)
{
s=20,sum=0;
a[1]=0, a[2]=2, a[3]=4, a[4]=6, a[5]=8;
for(int i=1;i<=17;i++)
{
b[i]=s;
s=s*10;
}
cin>>n;
for(int i=17;i>=1;i--)
{
p=powr(i);
while(p<n)
{
sum=sum+b[i];
n=n-p;
}
}
printf("Case %d: %lld\n",j,sum);
}
}
It is complexity O(n). But I get wrong verdict.
#include <stdio.h>
int main(void){
unsigned long long nth = 1000000000000ULL-1;//-1: 1 origin
unsigned long long k[30] = {0, 5};//28:Log10(ULL_MAX)/Log10(5) + 1
unsigned long long sum = k[1];
unsigned long long temp = 4;//4 : 2,4,6,8
int i;
//make table
for(i = 1; i < 30 ; ++i){
if(k[i] == 0){
temp *= 5;//5 : 0,2,4,6,8 , 2digits: 4*5, 3digits: 4*5*5
sum += temp;
k[i] = sum;
}
if(k[i] > nth)
break;
}
while(--i){//The same basically barakmanos
int n = nth / k[i];
printf("%d", n * 2);
nth -= n * k[i];
}
printf("%d\n", nth * 2);
return 0;
}