How do I use BigInterger In my code for calculating primes? - java

I'm using this basic and crude code below for calculating prime numbers then exporting them to a text file:
import java.util.Scanner;
import java.io.*;
public class primeGenerator{
public static void main(String[] args)throws Exception {
Scanner kb = new Scanner(System.in);
String prime;
long num = kb.nextLong();
long i;
long z=0;
while(z==0){
for (i=2; i < num ;i++ ){
long n = num%i;
if (n==0){
break;
}
}
if(i == num){
writer(num);
}
num=num+2;
}
}
public static void writer(long num) throws Exception {
FileWriter writer = new FileWriter("prime.txt",true);
String prime= ""+ num;
writer.write(prime);
writer.write(" ");
writer.flush();
writer.close();
}
}
I would like to find primes beyond the Primative long's range and apparently big integer is the way to go about it. So how do i alter my code to do so?

Do you really need this? Having numbers bigger than can be handled by long means you want to test numbers bigger than 9223372036854775807. If your for-loop can test a hundred million divisions per second, it will still take it 2923 years to determine if that number is prime - and longer for larger numbers, of course.
A common optimization is to only test divisions up to sqrt(num). If you haven't found anything then, the number is prime.

Well, use BigInteger wherever you've currently got long. Instead of using % you'll use mod, instead of incrementing you'll use i = i.add(BigInteger.ONE), instead of == 0 you'll use equals(BigInteger.ZERO) etc.
Use Scanner.nextBigInteger instead of Scanner.nextLong, too.
Given that this looks like homework of some description (possibly self-set, of course) I won't write out the whole code for you - but if you have specific problems, feel free to ask.

Related

I'm working on Euler 12 , the code i have seems to workes properly but too slow , very very slow. How can i modify it to run faster?

Like i sad , i am working on Euler problem 12 https://projecteuler.net/problem=12 , i believe that this program will give the correct answer but is too slow , i tried to wait it out but even after 9min it still cant finish it. How can i modify it to run faster ?
package highlydivisibletriangularnumber_ep12;
public class HighlyDivisibleTriangularNumber_EP12 {
public static void findTriangular(int triangularNum){
triangularValue = triangularNum * (triangularNum + 1)/2;
}
static long triangularValue = 0l;
public static void main(String[] args) {
long n = 1l;
int counter = 0;
int i = 1;
while(true){
findTriangular(i);
while(n<=triangularValue){
if(triangularValue%n==0){
counter++;
}
n++;
}
if(counter>500){
break;
}else{
counter = 0;
}
n=1;
i++;
}
System.out.println(triangularValue);
}
}
Just two simple tricks:
When x%n == 0, then also x%m == 0 with m = x/n. This way you need to consider only n <= Math.ceil(sqrt(x)), which is a huge speed up. With each divisor smaller than the square root, you get another one for free. Beware of the case of equality. The speed gain is huge.
As your x is a product of two numbers i and i+1, you can generate all its divisors as product of the divisors of i and i+1. What makes it more complicated is the fact that in general, the same product can be created using different factors. Can it happen here? Do you need to generate products or can you just count them? Again, the speed gain is huge.
You could use prime factorization, but I'm sure, these tricks alone are sufficient.
It appears to me that your algorithm is a bit too brute-force, and due to this, will consume an enormous amount of cpu time regardless of how you might rearrange it.
What is needed is an algorithm that implements a formula that calculates at least part of the solution, instead of brute-forcing the whole thing.
If you get stuck, you can use your favorite search engine to find a number of solutions, with varying degrees of efficiency.

Not getting output for simple java program to find greatest prime factor

class LargestPrimeFactor{
public static void main(String args[]){
long p=0L;
long n=600851475143L;
for(long i=2L;i<(n/2);i++){
if((BigInteger.valueOf(i)).isProbablePrime(1)){
if(n%i==0){
p=i;
}
}
}
System.out.println(p);
}
}
It's problem 3 from Project Euler. I compiled it and no errors showed up. But am not getting any output. Whats the reason?
It is working (just add a print method inside the loop to check i for example).
You are currently using the Brute-Force method:
http://www.mathblog.dk/project-euler-problem-3/
If you visit the link the guy tells you an alternative solution for it.
The problem I see without having much knowledge about this is
that the operations you currently do are way too many.
You got the value "600851475143" stored in a long datatype and you try to
reach the half (300425737571,5) using the int i (counter in your for-loop).
https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#MAX_VALUE
This tells us: "A constant holding the maximum value an int can have,
2^(31)-1." = 2147483647
This is just 0,00715 (0,7%) of what you actually need.
So this leads us to an "Overflow".
Think of using the alternative method (first link)
and change the counter of your for-loop to type "long".
int maximum value is 2147483647 which is smaller than 600851475143/2
when index i reaches max value it will wrap around and start with negative number (-2147483648)
you should make your index i a long value
You have an infinite loop on the second for iteration you can only see it when you add logging before the end of the loop. It's not because it's not printing the value, when you stare at the console the iterator is still circling through 6857.
Try running the code with extra logging below.
public static void main(String args[]) {
int p = 0;
long n = 600851475143L;
for (int i = 2; i < (n / 2); i++) {
if ((BigInteger.valueOf(i)).isProbablePrime(1)) {
if (BigInteger.valueOf(n % i).compareTo(BigInteger.valueOf(0)) == 0) {
p = i;
System.out.println("Check == true Iteration"+p);
}
System.err.println("Second iterator"+p);
}
}
System.out.println("Final Value of P: "+p);
}
EDITED
The int data type can store values upto 2,147,483,647. To store numbers beyond that, use long.
long n = 600851475143L;
Not 600851475143 L, as that one space before L causes the system to not register it.
Also, int i in the for loop should be long i.

BigInteger loops and logic not working as planned

so I'm trying to make some code where it basically factors really big numbers. I've tried to translate the code that worked using longs into BigIntegers but the result just returns a lot of 2s and 0s. Here it is.
package primes;
import java.math.BigInteger;
public class Primes {
public static void main(String[] args) {
BigInteger y = new BigInteger("0");
BigInteger count= new BigInteger("2");
BigInteger input = new BigInteger("12321");
BigInteger one = new BigInteger("1");
while(input.compareTo(input)!=1) {
y=input.mod(count);
System.out.println(y);
if(y.compareTo(y)==0) {
input=input.divide(count);
System.out.println(count);
} else if(y.compareTo(y)!=0) {
count.add(one);
}
}
}
}
Alright, I see the problem with the count.add(one); but I am still unsure as to how the compareTo function works. Just for clarifciation with what each of these loops are supposed to do, I'm just going to paste the code of the functioning script that works with longs.
package longprimes;
public class LongPrimes {
public static void main(String[] args) {
long input = 121L;
long count = 2;
long y;
while (input!=1){
y = input%count;
if(y==0){
input = input/count;
System.out.println(count);
}
else if(y!=0){
count++;
}
}
}
}
Seemingly what is happening when I updated the BigInteger code a little bit is that it would factor it but it wouldn't divide input so that it would just keep finding the remainder but in the case that it was 0, it didn't actually divide input to end the loop.
Looks like this is a homework assignment, so I'll just point out a few things:
input.compareTo(input)!=1 is probably not what you intended. Ideally, you want to finish that while loop when input is one. But compareTo will return -1, 0 or 1 if the number on the left is less, equal to, or greater than the other number. Consider what this condition actually returns.
y.compareTo(y)==0 is kind of the same thing. You're comparing a number y with itself. Ideally, you want to compare with zero.
count.add(one) is not really doing anything. Consider what happens when you simply do
1 + 2;
you're computing the result of adding one to count but you're also ignoring the result. You might want to save that result somewhere.

Average of n numbers in java

Using loop I want to calculate the average of n numbers in Java and when user enters 0 the loop ends.
Here is the code that I have written:
public class start {
public static void main(String[] args) {
System.out.println("Enter an int value, the program exits if the input is 0");
Scanner input = new Scanner (System.in);
int h = 0;
while (input.nextInt() == 0){
int inp = input.nextInt();
int j = inp;
int i = 0;
h = j + i;
break;
}
System.out.println("The total is: "+ h);
}
}
Am I making any logical error?
Don't name the sum h, but sum.
The while-condition is wrong
Why do you use inp and j and i?
There is an unconditional break - why?
You talk about the average. Do you know what the average is?
Your output message is not about average - it is about the sum.
"Am I making any logical error?"
Yes. This looks like a homework problem so I won't spell it out for you, but think about what the value of i is, and what h = j + i means in this case.
You also need to be careful about calling input.nextInt(). What will happen when you call it twice each time through the loop (which is what you are doing)?
Homework, right?
Calling input.nextInt() in the while loop condition and also to fill in int inp means that each trip through the loop is reading two numbers (one of which is ignored). You need to figure out a way to only read one number per loop iteration and use it for both the == 0 comparison as well as for inp.
Additionally, you've done the right thing having h outside the while loop, but I think you're confusing yourself with j and i inside the loop. You might consider slightly more descriptive names--which will make your code much easier to reason about.
You need to keep a counter of how many numbers you read so you can divide the total by this number to get the average.
Edited the while loop:
while(true){
int e=input.nextInt();
if(e==0) break;
h+=e;
numberOfItems++;
}
Your original implementation called nextInt() twice, which has the effect of discarding every other number (which is definitely not what you intended to do).
Assuming that you asking the user only once, to enter and if the number if zero you simply want to display the average. you need a variable declared outside the while loop that will keep adding different numbers entered by the user, along with a second variable which track the number of cases entered by the user and keep incrementing itself by one till number is not zero as entered by the user. And as the user Enters 0, the loop will break and here our Average will be displayed.
import java.util.Scanner;
public class LoopAverage
{
public static void main(String[] args0)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter any Integer value : ");
int value = -1, sum = 0, count = 0;
while((value = scan.nextInt()) != 0)
{
count++;
sum = sum + value;
}
System.out.println("Average : " + (sum / count));
}
}
Hope that might help,
Regards
yes, oodles of logical errors.
your while loop condition is wrong, you're consuming the first value
you enter and unless that number is 0 you never enter the loop at all
i var has no purpose
you're breaking after one iteration
you're not calculating a running total
you're not incrementing a count for the average dividend
you're not calculating an average
This looks like you threw some code together and posted it. The most
glaring errors would have been found just by attempting to run it.
Some other things to consider:
Make sure to check for divide by 0
If you do an integer division, you might end up with an incorrect
average, as it will be rounded. Best to cast either the divisor or
dividend to a float
variable names should be helpful, get into the habit of using them
I recommend you to refer to the condition of "while" loop: if condition meets, what would the program do?
(If you know a little bit VB, what is the difference between do...until... and do...while...?)
Also, when you call scanner.nextInt(), what does the program do? For each input, how should you call it?
Last but not least, when should you use "break" or "continue"?
For the fundamentals, if you are in a course, recommend you to understand the notes. Or you can find some good books explaining details of Java. e.g. Thinking in Java
Enjoy learning Java.

All possible values of int from the smallest to the largest, using Java

Write a program to print out all possible values of int data type from the smallest to the largest, using Java.
Some notable solutions as of 8th of May 2009, 10:44 GMT:
1) Daniel Lew was the first to post correctly working code.
2) Kris has provided the simplest solution for the given problem.
3) Tom Hawtin - tackline, came up arguably with the most elegant solution.
4) mmyers pointed out that printing is likely to become a bottleneck and can be improved through buffering.
5) Jay's brute force approach is notable since, besides defying the core point of programming, the resulting source code takes about 128 GB and will blow compiler limits.
As a side note I believe that the answers do demonstrate that it could be a good interview question, as long as the emphasis is not on the ability to remember trivia about the data type overflow and its implications (that can be easily spotted during unit testing), or the way of obtaining MAX and MIN limits (can easily be looked up in the documentation) but rather on the analysis of various ways of dealing with the problem.
class Test {
public static void main(String[] args) {
for (int a = Integer.MIN_VALUE; a < Integer.MAX_VALUE; a++) {
System.out.println(a);
}
System.out.println(Integer.MAX_VALUE);
}
}
Am I hired?
Simplest form (minimum code):
for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
System.out.println(i);
}
No integer overflow, no extra checks (just a little more memory usage, but who doesn't have 32 spare bits lying around).
While I suppose
for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++)
System.out.println(i);
has fewer characters, I can't really say that it is simpler. Shorter isn't necessarily simpler, it does have less code though.
I just have to add an answer...
public class PrintInts {
public static void main(String[] args) {
int i = Integer.MIN_VALUE;
do {
System.out.println(i);
++i;
} while (i != Integer.MIN_VALUE);
}
}
We don't want the body repeated (think of the maintenance!)
It doesn't loop forever.
It uses an appropriate type for the counter.
It doesn't require some wild third-party weirdo library.
Ah, and here I had just started writing
System.out.println(-2147483648);
System.out.println(-2147483647);
System.out.println(-2147483646);
Okay, just give me a few weeks to finish typing this up ...
The instructions didn't say I have to use a loop, and at least this method doesn't have any overflow problems.
Is there something tricky that I'm not catching? There probably is... (edit: yes, there is!)
class AllInts {
public static void main(String[] args) {
// wrong -- i <= Integer.MAX_VALUE will never be false, since
// incrementing Integer.MAX_VALUE overflows to Integer.MIN_VALUE.
for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
System.out.println(i);
}
}
}
Since the printing is the bottleneck, a buffer would improve the speed quite a lot (I know because I just tried it):
class AllInts {
public static void main(String[] args) {
// a rather large cache; I did no calculations to optimize the cache
// size, but adding the first group of numbers will make the buffer
// as large as it will ever need to be.
StringBuilder buffer = new StringBuilder(10000000);
int counter = 0;
// note that termination check is now <
// this means Integer.MAX_VALUE won't be printed in the loop
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
buffer.append(i).append('\n');
if (++counter > 5000000) {
System.out.print(buffer);
buffer.delete(0, buffer.length()-1);
counter = 0;
}
}
// take care of the last value (also means we don't have to check
// if the buffer is empty before printing it)
buffer.append(Integer.MAX_VALUE);
System.out.println(buffer);
}
}
Also, this version will actually terminate (thanks to Daniel Lew for pointing out that there was, in fact, something tricky that I wasn't catching).
The total run time for this version (run with -Xmx512m) was 1:53. That's over 600000 numbers/second; not bad at all! But I suspect that it would have been slower if I hadn't run it minimized.
When I first looked at this, my first question was 'how do you define smallest and largest'. For what I thought was the most obvious definition ('smallest' == 'closest to 0') the answer would be
for (int i = 0; i >= 0; i++) {
System.out.println(i);
System.out.println(-i-1);
}
But everyone else seems to read 'smallest' as 'minimum' and 'largest' as 'maximum'
Come on folks, it said using java. It didn't say use an int in the for loop. :-)
public class Silly {
public static void main(String[] args) {
for (long x = Integer.MIN_VALUE; x <= Integer.MAX_VALUE; x++) {
System.out.println(x);
}
}
}
Another way to loop through every value using an int type.
public static void main(String[] args) {
int i = Integer.MIN_VALUE;
do {
System.out.println(i);
} while (i++ < Integer.MAX_VALUE);
}
Given the overview of the best answers, I realized that we're seriously lacking in the brute-force department. Jay's answer is nice, but it won't actually work. In the name of Science, I present - Bozo Range:
import java.util.Random;
import java.util.HashSet;
class Test {
public static void main(String[] args) {
Random rand = new Random();
HashSet<Integer> found = new HashSet<Integer>();
long range = Math.abs(Integer.MAX_VALUE - (long) Integer.MIN_VALUE);
while (found.size() < range) {
int n = rand.nextInt();
if (!found.contains(n)) {
found.add(n);
System.out.println(n);
}
}
}
}
Note that you'll need to set aside at least 4 GB of RAM in order to run this program. (Possibly 8 GB, if you're on a 64-bit machine, which you'll probably require to actually run this program...). This analysis doesn't count the bloat that the Integer class adds to any given int, either, nor the size of the HashSet itself.
The maximum value for int is Integer.MAX_VALUE and the minimum is Integer.MIN_VALUE. Use a loop to print all of them.
Package fj is from here.
import static fj.pre.Show.intShow;
import static fj.pre.Show.unlineShow;
import static fj.data.Stream.range;
import static java.lang.Integer.MIN_VALUE;
import static java.lang.Integer.MAX_VALUE;
public class ShowInts
{public static void main(final String[] args)
{unlineShow(intShow).println(range(MIN_VALUE, MAX_VALUE + 1L));}}
At 1000 lines/sec you'll be done in about 7 weeks. Should we get coffee now?
Just improving the StringBuilder's approach a little:
2 threads + 2 buffers (i.e. StringBuilder): The main idea is that one thread fills one buffer while the other thread dumps the content of the other buffer.
Obviously, the "dumper" thread will always run slower than the "filler" thread.
If the interviewer was looking for all the Integer values possible in Java, You might try giving him a solution using Long:
class AllIntegers{
public static void main(String[] args) {
for (int i = Integer.MIN_VALUE; i < Long.MAX_VALUE; i++) {
System.out.println(i);
}
System.out.println(Long.MAX_VALUE);
}
}
This should print a range from -9223372036854775808 to 9223372036854775807 which is way more than you would achieve using Integer.

Categories