What's wrong with my Euler's problem10 code? - primes

It just doesn't give out the correct answer for some reason and for some reason it gives correct one with smaller input.
public class Problem10 {
public static void main(String[] args) {
System.out.println(sumPrimeNumber(2000000));
}
public static boolean isPrime(int prime){
boolean isPrime = true;
if(prime%2==0)
return false;
for(int i = 3;i<=Math.pow(prime, 0.5);i+=2){
if(prime%i==0){
return false;
}
}
return isPrime;
}
public static int sumPrimeNumber(int max){
int sum = 0;
int prime = 3;
while(prime < max){
if(isPrime(prime)){
sum += prime;
}
prime += 2;
}
return sum + 2;
}
}

I figure out I should change sum to long. I though that it didn't overflow because it gives out a positive integer.

Your int (max 2 billion) is probably overflowing.
Change ints to longs.
public class Problem10 {
public static void main(String[] args) {
System.out.println(sumPrimeNumber(2000000));
}
public static boolean isPrime(long prime){
boolean isPrime = true;
if(prime%2==0)
return false;
for(int i = 3;i<=Math.pow(prime, 0.5);i+=2){
if(prime%i==0){
return false;
}
}
return isPrime;
}
public static int sumPrimeNumber(long max){
long sum = 0;
int prime = 3;
while(prime < max){
if(isPrime(prime)){
sum += prime;
}
prime += 2;
}
return sum + 2;
}
}

Your isPrime() function has an error. It flags 2 as composite, returning false.
Change the initial if to:
if (prime % 2 == 0)
return prime == 2;
which will return true for 2 and false for other even numbers.

Related

Dividing an array into the greatest amount of parts with equal sums

The array can hold negative numbers. I've written this code using recursion. First I'm summing the first i elements and then I'm checking for each such sum if the rest of the array (starting from i + 1) can be divided with this sum.
It works for some cases but not for others. I've noticed that it doesn't work if there's a prime somewhere.
It works if I sort the array in descending order beforehand but I don't understand why.
In this case the output is 2, while it should be 0.
#include <iostream>
const int N = 5;
int tab[N] = {1, 2, 3, 3, 4};
// returns the number of partitions with a given sum (or 0 if it can't be partitioned)
int divisions(int tab[N], int p, int sum) {
if (N < 2) return 0;
if (p == N) {
return 1;
}
int s_sum = tab[p++];
while (s_sum != sum && p < N) {
s_sum += tab[p++];
}
if (s_sum == sum) {
return divisions(tab, p, sum) + 1;
} else {
return 0;
}
}
// creates all the possible sums and returns the greatest number of partitions where each partition sums up to some sum
int compareAllDivisions(int tab[N]) {
int maxResult = 0;
for (int i = 0; i < N; ++i) {
int sum = 0;
for (int j = 0; j <= i; ++j) {
sum += tab[j];
}
int result = divisions(tab, i + 1, sum);
if (maxResult < result) {
maxResult = result;
}
}
if (maxResult >= 2) {
return maxResult;
} else {
return 0;
}
}
int main() {
std::cout << compareAllDivisions(tab) << std::endl;
return 0;
}
It is because of return value of if (s_sum == sum) part.
It should be changed like below
if (s_sum == sum) {
int ret = divisions(tab, p, sum);
if(ret == 0) return 0;
else return ret + 1;
} else {
return 0;
}
Your return value of divisions is 0 when can't make and pos number when can make.
So, let's consider when 0 returns in there. It can't make at the back, but it will return pos number!

C++ Finding the nth prime number

i am trying to find the nth prime number.
For example: input 1 - result 2 , input 2 - result 3, input 3-result 5...
My isprime function currently works but i couldnt figure it out, there must be something wrong, please help, thanks:)
/*
Finding the nth Prime Number
Yasin OSMAN
*/
//Including Libraries
#include <iostream>
using namespace std;
//Defining a global counter
int counter = 0;
/*
Defining Functions
*/
//isPrime Function (returns true if the given number is prime)
bool isPrime(int n) {
bool answer = true;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
answer = false;
}
}
return answer;
}
int main() {
int userInput;
cout<<"Please indicate which prime number do you want to see: ";
cin>>userInput;
for(int i=0;i<=userInput;i++){
if(isPrime(counter)){
if(counter==userInput){
cout<<counter<<"th prime number is : "<<i<<endl;
}
counter++;
}
counter++;
}
return 0;
}
To improve the isPrime function:
numbers less than 2 won't be prime, so reject them first.
bool isPrime(int n) {
if (n < 2) return false; // add this line
bool answer = true;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
answer = false;
}
}
return answer;
}
To improve the main function:
Increment the counter only if a prime number is found.
Count prime numbers found, then check the total number.
Check if the number, not the counter, is prime.
int main() {
int userInput;
cout<<"Please indicate which prime number do you want to see: ";
cin>>userInput;
for(int i=0, counter=0;counter<=userInput;i++){ // note: the global "counter" is shadowed here
if(isPrime(i)){
counter++;
if(counter==userInput){
cout<<counter<<"th prime number is : "<<i<<endl;
}
}
}
return 0;
}
Thanks to #MikeCAT
i changed my isPrime function for numbers that less than 2,
bool isPrime(int n) {
bool answer = true;
if(n<2){
answer=false;
return answer;
}
if(n>=2){
for (int i = 2; i < n; i++) {
if (n % i == 0) {
answer = false;
return answer;
}
}
return answer;
}
}
and i also made nthPrime a function,
int nthPrime(int n){
double i;
for(i=2;counter<n;i++){
if(isPrime(i)){
counter++;
}
}
return i-1;
}
and to display the result i used the following code :
int userInput;
cout<<"Please indicate which prime number do you want to see: ";
cin>>userInput;
cout<<counter<<"th prime number is : "<<nthPrime(userInput);
return 0;
Output Example : Please indicate which prime number do you want to see: 5
5th prime number is : 11

Comparing two int arrays in C

Is there a better way to compare two int array in C++.
struct integer
{
int *number;
int size;
};
This is my struct and i have used this comparing function. I found this solution but it looks like bulshit.
int BigInteger::biggest(integer number1, integer number2)
{
int biggest = 0;
if (number1.size > number2.size)
{
biggest = 1;
}
else if (number1.size < number2.size)
{
biggest = -1;
}
else
{
for (int i = number1.size; i >=0 ; --i)
{
if (number1.number[i] > number2.number[i])
{
biggest = 1;
return biggest;
}
else if (number1.number[i] < number2.number[i])
{
biggest = -1;
return biggest;
}
else
{
continue;
}
}
}
return biggest;
}
if function turn value as 1 then number1 greater than number2
if function turn value as 0 then number1 equal to number2
if function turn value as -1 then number2 greater than number1
This will not improve anything except, that it's much clearer
int BigInteger::biggest(integer number1, integer number2)
{
if (number1.size != number2.size)
return number1.size - number2.size;
for (int i = 0 ; i < number1.size; ++i) {
if (number1.number[i] == number2.number[i])
continue;
return number1.number[i] - number2.number[i];
}
return 0;
}
This function
Returns > 0 then number1 > number2
Returns < 0 then number1 < number2
And 0 if they are equal
Also, in c++ you can overload operators so implementing > and < should be easy using this code.
There are a few small bugs. You don't need some of this code. It will run slightly faster when it is not part of a class. And with just a bit of modification it will work with qsort() (the parameters need to be pointers) (edit: void pointers)
struct integer
{
int *number;
int size;
};
int biggest(const integer &number1, const integer &number2)
{
int biggest = 0;
if (number1.size > number2.size)
{
biggest = 1;
}
else if (number1.size < number2.size)
{
biggest = -1;
}
else
{
for (int i = number1.size - 1; i >= 0; i--) // or --i, no difference
{
if (number1.number[i] > number2.number[i])
{
biggest = 1;
return biggest;
}
if (number1.number[i] < number2.number[i])
{
biggest = -1;
return biggest;
}
// don't need a continue statement here
}
}
return biggest;
}
You can use the std::mismatch() function like this:
int BigInteger::biggest(integer a, integer b)
{
if (a.size != b.size)
return a.size - a.size;
const auto res = std::mismatch(a.number, a.number + a.size, b.number);
if (res.first == (a.number + a.size))
return 0;
else
return (*res.first) < (*res.second) ? -1 : 1;
}
The name of the function biggest() is quite misleading. compare() would be much better. Also, if the function's return type would be boolean (true: a < b), then you could use std::lexicographical_compare(), and the code would much more simpler.

sieve of Eratosthenes C++ algorithm

I am trying to implement this algorithm and I have having a hard time working out the algorithm to work for finding the prime numbers up to 1000. I don't really understand but my code is not giving me the correct output, if you can suggest a way I should change my code I would greatly appreciate it.
#include <iostream>
using namespace std;
bool isPrime(int n);
int main() {
int i;
for(i = 1; i <= 1000; i++){
if( isPrime(i)) cout << "This number " << i << " is a prime. " << endl;
}
}
bool isPrime(int n){
if(n <= 1){
return false;
}
if(n == 2){
return true;
}
for(int i = 2; i < n; i++){
if(n % i == 0){
return false;
}else{
return true;
}
}
}
Your decision inside the for loop inside isPrime() is wrong. This is a criterion to terminate the loop:
if(n % i == 0){
but the elsepart is no reason to terminate. You have to wait until the for loop finished. Like this:
for(int i = 2; i < n; i++){
if(n % i == 0){
// Here, we are sure that n can be divided by any other numbers than 1 and n.
return false;
}
}
// Here, we are sure that n cannot be divided by any number 2 .. (n-1).
return true;
}
By the way, you only have to check until the square root of n. You can spare the rest.
There is problem in your isPrime function
bool isPrime(int n){
if(n <= 1){
return false;
}
if(n == 2){
return true;
}
for(int i = 2; i < n; i++){
if(n % i == 0){
return false;
}
else{
return true; /* this line is very dangerous. When there is odd number it is not divisible by two so the control goes to else block and you get every odd number as your prime number */
}
}
}
Instead use this
bool isPrime(int n){
if(n <= 1){
return false;
}
if(n == 2){
return true;
}
for(int i = 2; i < n; i++){
if(n % i == 0){
return false;
}
}
return true;
}
For Sieve Of Erastosthenes
try this code it may help
int b;
cout << "Enter upper limit" << endl;
cin >> b;
bool *x;
x = new bool[b];
x[2] = true;
for (int i = 2; i < b; i++)
{
int count = 2;
if (x[i])
{
cout << i << endl;
while (i*count < b)
{
x[i*count] = false;
count++;
}
}
}
The problem is in the isPrime function.
Your isPrime function says if the the first value of i (i.e 2) is not divided by n then return true. So for eg. 21, 27 etc are also counted as a prime number.
You can use a flag variable in the isPrime function and used it to determine whether the n is prime or not. Like this
boolean prime = true;
for(int counter = 2; counter <= number / 2; counter++) {
if(number % counter == 0) {
prime = false;
break;
}
}
return prime;
I don't think this is Sieve of Eratosthenes algorithm. If you want to implement this algorithm then you can read from here.

Digit-increasing number test

A number is called digit-increasing if it is equal n + nn + nnn + ... for some digit n between 1 and 9. For example 24 is digit-increasing because it equals 2 + 22 (here n = 2).
Actually, a friend of mine asked me this question and i am stuck thinking about it but couldn't find the exact solution so far. Can anyone help ? I needed the function that returns true if it is digit-increasing else false.
There are only relatively few numbers with this property: Within the range of unsigned long long (64 bits), there are only 172 digit-increasing numbers.
Therefore, in terms of a practical solution, it makes sense to pre-compute them all and put them in a hash. Here is Python code for that:
# Auxiliary function that generates
# one of the 'nnnn' elements
def digits(digit,times):
result = 0
for i in range(times):
result += digit*(10**i)
return result
# Pre-computing a hash of digit-increasing
# numbers:
IncDig = {}
for i in range(1,30):
for j in range(1,10):
number = reduce(lambda x,y:x+y,[digits(j,k) for k in range(1,i+1)])
IncDig[number] = None
Then the actual checking function is just a look-up in the hash:
def IncDigCheck(number):
return (number in IncDig)
This is virtually O(1), and the time and space taken for the pre-calculation is minimal, because there are only 9 distinct digits (zero doesn't count), hence only K*9 combinations of type n + nn + ... for a sum of length K.
General representation is:
n + (n*10 + n) + (n*100+n)...
If number look like sum of same digits then any digit can be represented as
(1+111+...) * base_digit
. Assuming this we can use simple algorithm:
bool isDigitIncreasing(const int num)
{
int n = 1;
int sum = 1; //value to increase n
while (n <= num) {
//if num is (111...) * base_digit and base_digit is < 10
if (num % n == 0 && n * 10 > num) return true;
sum = sum * 10 + 1; //N*10+N where n is 1 as was assumed
n += sum; //next step
}
return false;
}
Simple exhaustive search will work.
def is_digit_increasing_number(x):
# n = 1, 1+11, 1+11+111, ...
n = 1
i = 1
while n <= x:
if x % n == 0 and n * 10 > x:
return True
i += 1
n = n * 10 + i
return False
Simplest possible way is do the addition (bottom-up), I'll use simple for loop:
List<int> numbersSum = new List<int>{1,2,3,4,5,6,7,8,9};
List<int> lastNumber = new List<int>{1,2,3,4,5,6,7,8,9};
for(int i=0;i<= lg n + 1;i++)
{
for(int j=0;j<9;j++)
{
if(list[j] < n)
{
var lastNumberJ = lastNumber[j]*10+j+1;
list[j] += lastNumberJ; // add numbers to see will be same as n.
if (list[j] == n)
return j+1;
lastNumber[j] = lastNumberJ;
}
}
}
return -1;
The important part is you just need at most log n iteration and also you can return sooner if all numbers are bigger than given number, this is O(log n) algorithm.
Here is a python code.The basic logic here is that a digit increasing number if divided by a specific number between 1-9 gives a digit increasing number made of only ones.All the digit increasing numbers of 1 follow a specific pattern ie 12345678...
import sys
for n in range(1,10):
a=1
if k%n!=0:
a=0
else:
g=str(k/n)
j=int(g[0])
for i in range(1,len(g)):
if int(g[i])==j+1:
j=int(g[i])
else:
a=0
break
if a==1:
print "Yes,it is a digit increasing number"
sys.exit(0)
print "No,it is not a digit increasing number"
I have done in this way. Check out once.
int sum = 0, count =0;
bool flag = false;
public bool isDigitIncreasing(int input_number)
{
int n= get_number_of_digit(input_number); // Gets number of digits
int sum = 0;
for(int i=0;i<n;i++)
{
sum = sum*10+1;
count = count + sum;
}
for(int i=1; i<=9;i++)
{
if((input_number)==count*i)
{
flag = true;
break;
}
else
flag = false;
}
return flag;
}
public int get_number_of_digit(int num)
{
int size = 0;
do
{
num = num/10;
size++;
}while(num>0);
return size;
}
Here is the shortest solution
public static int isDigitIncreasing (int n)
{
if(n<10)
{
return 1;
}
for(int i=1;i<=9;i++)
{
int tempsum=i;
int previous=i;
while(tempsum<=n)
{
previous=previous*10 + i;
tempsum=tempsum + previous;
if(tempsum==n)
{
return 1;
}
}
}
return 0;
}
Ambiguitiy: Are the values 1-9 repeating for themselves? (too lazy to google this myself)
If 1-9 are repeating then following should work. If not, and you want the code to work only on values > 10 then you can initialize mult with 10.
int i, mult = 1, result, flag;
for( i=1; i<9; i++ )
{
flag = 0;
while( result < TARGET )
{
result = result+(i*mult);
mult = mult*10;
if( result == TARGET )
{
flag = 1;
break;
}
}
if( flag == 1 )
break;
}
After execution, i must contain the values for which RESULT is a repeating number IF the flag is 1. If flag is zero after execution then the TARGET isn't a repeating number.
I wonder if its possible that a number could be repeating for multiple values, just curious.
Here num is the number and n is the digit
#include<stdio.h>
int f(int num,int n)
{
int d=n;
while(num>0)
{
num-=n;
n=d+n*10;
}
if(num==0)
return 1;
else
return 0;
}
int main()
{
int num;
int n;
int flag;
printf("Enter the number :");
scanf("%d",&num);
printf("Enter the digit :");
scanf("%d",&n);
flag = f(num,n);
if(flag == 1)
printf("It's in n+nn+nnn+...\n");
if(flag ==0)
printf("It's not\n");
return 0;
}
Let d(k) be 1+11+111+...+(11...11) where the last number has k digits. Then d(1)=1, and d(k+1)=10d(k)+k+1.
We want to test if d(k)*i = n, for some k, and for some i=1..9.
If we've computed d(k), then i (if it exists) must be n/d(k). We can check if n/d(k) is correct, by comparing n with ((n/d(k))%10)*d(k). The %10 makes the test fail if i is larger than 9.
This gives us a relatively terse solution: compute subsequent d(k) until they are bigger than n, and at each point check to see if n is a digit-multiple of d(k).
Here's a very lightly code-golfed implementation of that idea:
#include <stdio.h>
int is_digit_increasing(int n) {
for(int d=1,k=1;d<=n;d=d*10+ ++k)if(n==(n/d)%10*d)return 1;
return 0;
}
int main(int argc, char**argv) {
for (int i=0; i<10000; i++) {
if (is_digit_increasing(i)) {
printf("%d\n", i);
}
}
return 0;
}
// Example program
#include <iostream>
#include <string>
int isDigitIncreasingNo(int n) {
if(n<=0)
return 0;
int len = std::to_string(n).length();
int vector1 = 0;
int vector2 = 0;
for(int i=1;i<=len;i++)
vector2 = (vector2*10)+i;
vector1 = vector2/10;
if(n % vector2 == 0 && (n / vector2)<=9 )
return 1;
if(n % vector1 == 0 && (n / vector1)<=9 )
return 1;
return 0;
}
int main()
{
for (int i=0; i<10000000; i++) {
if (isDigitIncreasingNo(i)) {
printf("%d\n", i);
}
}
return 0;
}
public boolean isDigitIncreasing(int number)
{
int sum;
int size=calculateNumberOfDigits(number);
for(int i=1;i<=9;i++)
{
sum=0;
int temp=size;
while(temp>=1)
{
for(int j=temp;j<=1;j--)
{
sum=sum+i*(int)Math.pow(10,j-1);
}
temp--;
}
if(sum==number)
{
return true;//Its a digit increasing
}
}
return false;
}
public int calculateNumberOfDigits(int number)
{
int size=0;
do
{
number=number/10;
size++;
}while(size>0);
return size;
}