I've read several posts on this, I even did this during one of my exams, but was in vb.net. It worked fine, however eclipse is just running non-stop when I try to execute my program, or otherwise it gives me the wrong answer. Here is my fourth attempt at it. I need to add the sum of the first n prime numbers, hence I do a check for whether a number is prime or not. The loop does not stop for some reason. Any help would be appreciated. Thanks.
int count = 0;
int noMod0s = 0;
int total = 0;
//static boolean prime;
for (int y = 2;count<5;y++) {
for (int z = 1;z<y;z++) {
if (y % z == 0) {
noMod0s++;
}
}
if (noMod0s == 1) {
total = total + y;
count++;
noMod0s = 0;
}
}
System.out.println(total);
There are at least two issues with your code:
You are not resetting variable noMod0s for each separate primality test. You should do it before the second loop.
The second loop should start from 2 not 1 to be a valid primality test. Of course in this case you will be comparing noMod0s == 0. It works the same but it gives a clearer idea of what the code is doing.
Related
I am new to coding in Java so I am practicing with the Euler Projects to get into it. I am using Eclipse and my issue is that code that to my eyes should work fine doesn't work. I don't get an error, but nothing outputs to the console either. The console is blank.
This is my code for question 5:
/*
2520 is the smallest number that can be divided by each of the numbers
from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all
of the numbers from 1 to 20?
*/
class main {
public static void main(String[] args) {
int i = 2520;
int biggestNum = 0;
while (biggestNum != i) {
for (int j = 1; j <= 20; j++) {
if (i%j != 0) {break;}
if (j == 20) {biggestNum = i; }
}
i++;
}
System.out.println(biggestNum);
}
}
and this is the code for question 3:
/*
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*/
public class euler3 {
public static boolean isPrime (long num) {
for (long i = 2; i < num; i++) {
if (num % i == 0 ) return false;
}
return true;
}
public static void main(String[] args) {
long num = 600851475143L;
long x = 1;
for (int i = 2; i <= num; i++) {
if (num % i == 0) {
if (isPrime(i)) {
x = i;
}
}
}
System.out.println(x);
}
}
The thing with question 3, though, is that it works for the small number (13195) and it gives me 29, but I get the blank console again for the larger one.
I decided to include both of these questions since they have the same problem of not outputting my answer to the console. Any help would be appreciated.
I decided to include both of these questions since they have the same problem of not outputting my answer to the console. Any help would be appreciated.
Welcome to stackoverflow. When debugging your code, be sure to do so one at a time. Just because both programs aren't displaying the output that you expect doesn't mean that they have the same issue.
There are many ways to debug your buggy code. You can do "printf" style debugging by placing System.out.println(...) statements inside of your loops so you can see what is happened or your can use a Java debugger. The 2nd answer can often get a faster result in terms of finding the problem but you need to learn about debuggers and it depends on which IDE you are using.
When you get more experienced, being able to execute the code in your head really helps with bugs as these. For example, I can look at your code and see:
for loop is going from 2 to 600851475143L
tests if the number if prime
sets x to be the number if it prime.
continue. OH it's not breaking from the loop.
You have to go step by step through your code either in your head, with a debugger, or by walking through debug output to find these sorts of bugs.
Best of luck.
I am writing a Java program that calculates the largest prime factor of a large number. But I have an issue with the program's complexity, I don't know what has caused the program to run forever for large numbers, it works fine with small numbers.
I have proceeded as follow :
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class Largest_prime_factor {
public static void main(String[] args)
{
//ArrayList primesArray = new ArrayList();
ArrayList factorArray = new ArrayList();
long largest = 1;
long number = 600851475143L ;
long i, j, k;
//the array list factorArray will have all factors of number
for (i = 2; i < number; i++)
{
if( number % i == 0)
{
factorArray.add(i);
}
}
Here, the Array List will have all the factors of the number.
So I'll need to get only the prime ones, for that, I used a method that checks if a number is prime or not, if it's not a prime number, I remove it from the list using the following method :
java.util.ArrayList.remove()
So the next part of the code is as follow :
for (i = 2; i < number; i++)
{
if (!isPrime(i))
{
factorArray.remove(i);
System.out.println(factorArray);
}
}
System.out.println(Collections.max(factorArray));
}
The last line prints the largest number of factorArray, which is what I am looking for.
public static boolean isPrime(long n)
{
if(n > 2 && (n & 1) == 0)
return false;
for(int i = 3; i * i <= n; i += 2)
if (n % i == 0)
return false;
return true;
}
}
The function above is what I used to determine if the number is a prime or not before removing it from the list.
This program works perfectly for small numbers, but it takes forever to give an output for large numbers, although the last function is pretty fast.
At first, I used to check if a number is prime or not inside of the first loop, but it was even slower.
You are looping over 600851475143 numbers.
long number = 600851475143L ;
for (i = 2; i < number; i++)
Even if we assume that each iteration takes very very small time (as small as 1 microsecond), it'll still take days before the loop finishes.
You need to optimise your prime-finding logic in order for this program to run faster.
One way to reduce the iterations to reasonable number is to loop until square root of number.
for (i = 2; i < Math.sqrt(number); i++)
or
for (i = 2; i*i < number; i++)
The calculation of the prime factors of 600851475143L should take less than a milli-second (with a not totally inefficient algorithm). The main parts your code is currently missing:
The border should be sqrt(number) and not number.
The current value should be checked in a while-loop (to prevent that non-prime-factors are added to the list, reduces range to check).
The max. value should be decreased (as well as the border) to number/factor after finding a factor.
Further improvements are possible, e.g. to iterate only over non-even numbers (or only iterate over numbers that are neither a multiple of 2 and 3) etc.
An example implementation for the same question on codereview (link):
public static long largestPrimeFactor(
final long input) {
////
if (input < 2)
throw new IllegalArgumentException();
long n = input;
long last = 0;
for (; (n & 1) == 0; n >>= 1)
last = 2;
for (; n % 3 == 0; n /= 3)
last = 3;
for (long v = 5, add = 2, border = (long) Math.sqrt(n); v <= border; v += add, add ^= 6)
while (n % v == 0)
border = (long) Math.sqrt(n /= last = v);
return n == 1 ? last : n;
}
for (i = 2; i < number; i++)
{
if( number % i == 0)
{
factorArray.add(i);
}
}
For an large input size, you will be visiting up to the value of the number. Same for the loop of removing factors.
long number = 600851475143L ;
this is a huge number, and you're looping through this twice. Try putting in a count for every 10,000 or 100,000 (if i%10000 print(i)) and you'll get an idea of how fast it's moving.
One of the possible solutions is to only test if the the prime numbers smaller than the large number divide it.
So I checked
for (i=2; i < number; i++)
{
if(isPrime(i))
{
if( number % i == 0)
{
factorArray.add(i);
}
}
}
So here I'll only be dividing by prime numbers instead of dividing by all numbers smaller than 600851475143.
But this is still not fast, a complete modification of the algorithm is necessary to obtain an optimal one.
#Balkrishna Rawool suggestion is the right way to go. For that I would suggest to change the iteration like this: for (i = 3; i < Math.sqrt(number); i+=2) and handle the 2 manually. That will decrease your looping because none of the even numbers except 2 are prime.
I was trying to make a method to do the prime factorization of a number, and it's probably not the most efficient, but I don't see why it shouldn't work.
public static ArrayList<Integer> primeFactorize(int num) {
ArrayList<Integer> primeFactors = new ArrayList<Integer>();
for (int i = 2; i < Math.sqrt((double) num); i++) {
if (isPrime(i) && factor(num).contains(i)) {
primeFactors.add(i);
num /= i;
if (isPrime(num)) {
primeFactors.add(num);
break;
}
i = 2;
}
}
return primeFactors;
}
It calls upon two other methods that I wrote named factor() and isPrime(), which do exactly what you would expect them to (returns an ArrayList of factors and either true or false depending on if the input is prime, respectively).
I went through the debugger with num being 12, and it worked fine for the first loop, where it added 2 to primeFactors. However, when it got to the top of the array again with num being 6 and i being 2, it exited the loop as if i < Math.sqrt((double) num) returned false.
But that wouldn't make sense, because the square root of 6 is a bit over 2. I also tried (double) i < Math.sqrt((double) num), but it just did the same exact thing.
Can anyone see what I'm missing? Thanks for any replies.
EDIT: Here is my code now, thanks for the help! I know for sure I could make it more efficient, so I might do that later, but for now this is perfect.
public static ArrayList<Integer> primeFactorize(int num) {
ArrayList<Integer> primeFactors = new ArrayList<Integer>();
int i = 2;
while (i < Math.sqrt((double) num)) {
if (isPrime(i) && num % i == 0) {
primeFactors.add(i);
num /= i;
if (isPrime(num)) {
primeFactors.add(num);
break;
}
i = 2;
}
else
i++;
}
return primeFactors;
}
In your for loop, the i++ section will get called at the end of every loop. So in your code, you set i equal to 2. Then, the loop ends, and adds 1 to i, making it be 3. Then the comparison happens, and 3 is more than sqrt(6), so the loop exits.
If you want i to be 2 in the next iteration, you need to set it to a value so that after the increment operation runs it will be 2, not before; in this case, you should set it to 1. A better solution would be to change your code structure so it's not necessary though. As pointed out by biziclop, a while loop will let you decide whether or not to increment, and will avoid this problem.
Since you already accepted an answer I assume your problem is solved. The thing I want to point out is that casting integers to doubles is generally a bad idea if there is another way. Therefore I want to show you the below implementation, which doesn't use floating-point arithmetic. Also I think it's a bad idea to check whether or not num is a prime number, because this slows down the algorithm. Moreover if num % i == 0 evaluates to true, i is always a prime number, thus the isPrime(i) check is superfluous and also slows down your algorithm.
List <Integer> primeFactors(int n) {
List<Integer> factors = new ArrayList<>();
for (int i = 2; i <= n / i; ++i) {
while (n % i == 0) {
factors.add(i);
n /= i ;
}
}
if (n > 1) {
factors.add(n);
}
return factors ;
}
Is there any better logic that can be applied to magic numbers?
Or is there a magic number that I am missing out on?
Please help me out with this simplest working code!
A Magic number is a number whose sum of digits eventually leads to 1.
Example#1: 19 ; 1+9 =10 ; 1+0 = 1. Hence a magic number.
Example#2: 226; 2+2+6=10; 1+0 =1. Hence a magic number.
Example#3: 874; 8+7+4=19; 1+9=10; 1+0=1. Hence a magic number.
boolean isMagic ( int n ) {
return n % 9 == 1;
}
Well, I'm not 100% that the code you placed would work to get a "magic number", but my approach to the problem would be different.
First, I'd receive a String, so that I can get the different digits of the number with a String.charat.
Then I'd use a while cycle to sum the numbers until it gets a single digit number, then check if it's 1.
The code would be
boolean isMagicNumber(String number) {
int[] digits = new int[number.length()];
int sum = 99;
while(sum/10 >= 1) {
sum = 0;
for(int i = 0; i < number.length(); i++) {
sum += Integer.parseInt(""+number.charAt(i));
}
if(sum == 1) {
return true;
}
}
return false;
}
There might be a better solution, but this is what I'd do to solve the problem.
I am doing an excercise in the book "Java how to program". The excercise wants me to write a method that determines if a number is "prime". (A "Prime number" is a positiv integer which is only dividable with itself and 1). Then I am supposed to implement the method in an application that displays all integers up to 10 000.
I use "double-values" to test whether the remainder is 0 or not, to test dividability.
Anyway, I just don´t get the program to work, it displays all numbers fro 3, with an increement on how many times each number is displayed (3 44 555 etc). Can anyone please tell me what I´m doing wrong?
The code is the following:
public class Oppgave625
{
public static void main(String[] args)
{
for(double a = 2; a <= 10000; a++)
{
for(double b = 1; b < a; b++)
{
if (prime(a, b) !=0)
{
System.out.printf("%.0f ", prime(a, b));
}
}
}
}
static double prime(double x, double y)
{
if (x % y != 0)
{
return x;
}
else
{
return 0;
}
}
}
Use int instead. double is not good for this purpose
you might want to read this article to understand the use of the % Operator for floating point numbers.
Actually, there were many individual errors in here. I shortened the prime() function to the point where it was only a modulo op, so I was able to inline it. Second, I inverted the test so it checked for numbers that do not have a remainder, and continues to the next number as soon as it finds a divisor. Third, I changed b = 1 so that we do not check for numbers divisible by 1, because this would result to all numbers. Finally, I only print out the numbers for which we do not discover a divisor. The final result:
public static void main(String[] args) {
outer:
for (int a = 2; a <= 1000; a++) {
for (int b = 2; b < a; b++) {
if (a % b == 0) {
continue outer;
}
}
System.out.println(a);
}
}
Edit: I forgot to mention, I also changed the types from floats to ints, since I'm sure that's what you meant.
It's great that you posted sample code for this, but there are several things that are wrong:
you should not use a floating point type for this, but an int or a long. Floating point types should never be used for precise values.
you are making two calls to your prime function, effectively doubling the required steps
your prime function only tells you whether two numbers divide themselves evenly, it does not tell you whether one is a prime or not
for prime numbers, you should use a more efficient algorithm instead of calculating the same values over and over for each number. Look up Sieve of Eratosthenes.
You are approaching the problem like this: The number A is NOT prime, whenever i can find a number B that can divide A without a remainder.
Bur right now, you print out A whenever it is not dividable by B.
Instead you could say: whenever A not divisible by B, increase B. When i found a B to divide A, quit the inner loop, print nothing.
When i found no B, print A and quit loop.
Furthermore, you only have to test for divisibility of A until (a/2)-1.
A prime number is a number that is only divisible by one and itself. That is: one number. Your code is comparing two numbers as in the Euclidean algorithm for testing coprime-ness. This is very different than testing if a number is prime.
Your code should look something like this:
for i = 2 to 10,000 {
if( isPrime(i) ){
print i
}
}
function isPrime( int n ){
for i = 2 to n {
next if i == n
if( n % i == 0 ){
return 0;
}
}
return 1;
}
boolean isPrime = true;
for (int i = 2; i<=100; i++){
for(int j = 2; j<=i/2; j++){
isPrime = true;
if (i%j==0){
isPrime = false;
break;
}
}
if (isPrime){
Log.d("PrimeNumber",""+i);
}
}