Prime generating number finder not producing correct output - java

I'm working on this problem:
Consider the divisors of 30: 1,2,3,5,6,10,15,30.
It can be seen that for every divisor d of 30, d+30/d is prime.
Find the sum of all positive integers n not exceeding 100 000 000
such that for every divisor d of n, d+n/d is prime.
and I thought for sure I had it, but alas, it's apparently giving me the wrong answer (12094504411074).
I am fairly sure my sieve of Eratosthenes is working (but maybe not), so I think the problem is somewhere in my algorithm. It seems to get the right answer for n = 30 (1+2+6+10+22+30 = 71 - is this correct?), but as numbers get larger, it apparently stops working.
Here is my Java code:
import java.util.HashSet;
public class Generators {
static HashSet<Integer> hSet = new HashSet<Integer>();
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 100000000;
sieveErat(n + 1); //Fill a hashSet with prime numbers
System.out.println("Sieve complete");
int check = 0;
long sum = 3;
for(int i = 2; i <= n; i++){
int numDivisors = 0;
int numPrimeChecks = 0;
boolean done = false;
if(!hSet.contains(i+1)){ //i+1 must be a prime number for i to be prime generating
continue;
}
else{
for(int j = 2; j < i/2; j++){
if(i%j == 0){
numDivisors++;
check = j + i/j;
if(hSet.contains(check)){
done = true;
numPrimeChecks++;
}
}else{
break;
}
}
if(numPrimeChecks == numDivisors && done){
sum += i;
}
}
}
System.out.println(sum);
}
public static void sieveErat(int N){
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
//count++;
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i*i <= N; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime[i]) {
for (int j = i; i*j <= N; j++) {
isPrime[i*j] = false;
// count--;
}
}
}
for(int i = 2; i < isPrime.length; i++){
if(isPrime[i]){
hSet.add(i);
}
}
// System.out.println(count);
}
}

The maths of your sieve looks fine to me. I hacked it around to use a BitSet which is much more space efficient. Is 5761455 primes below 100,000,000 correct?
Once I got your code working I got the same figure you get (12094504411075) what figure should you be getting?
I think this bit is wrong (I have changed the variable names to match the question for clarity)
for(int d = 2; d < Math.sqrt(n+3); d++) {
if (n % d == 0) {
numDivisors++;
int check = d + n / d;
if (primes.get(check)) {
// **** What does done mean??? ****
//done = true;
numPrimeChecks++;
} else {
// **** Added! Got a divisor that did not check. No point in going on.
break;
}
} else {
// **** Why break here??? ****
//break;
}
}
NB I have edited this code to reflect what we finally decided was a correct solution.
Why are you breaking out of the d loop as soon as you hit a d that does not divide n? Surely that cannot be right.
However, I think you can break out of the d loop when you have a divisor that does not check.
Also, what is your intended functionality of done? It seems to have no real function.
And, why do you start sum at 3?
Removing the break I now get the value 1739023853139. Is this correct?
Added
Here's my sieve. Identical to yours but builds a BitSet which is a much more efficient structure than a HashSet in this case:
public static BitSet sieveOfEratosthenes(int n) {
BitSet isPrime = new BitSet(n);
// Iniially all numbers are prime.
for (int i = 2; i <= n; i++) {
isPrime.set(i);
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i * i <= n; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime.get(i)) {
for (int j = i; i * j <= n; j++) {
isPrime.clear(i * j);
}
}
}
//System.out.println("Found " + isPrime.cardinality() + " primes");
return isPrime;
}

Related

Print a prime triangle in JAVA

I am trying to print a triangle of 0s and 1s. You get a number N. If N was 5 the triangle should look like:
1
11
111
11101
I get wrong output with 27 for example
1
11
111
11101
11101010
11101010001
11101010001010
11101010001010001
11101010001010001010
Lines ending with non-prime numbers are not printed, the prime numbers are printed as 1s, non-prime as 0s. I have a problem because some lines ending with 0s are printed.
import java.util.Scanner;
public class PrimeTriangle {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner (System.in);
int n = Integer.parseInt(input.nextLine());
boolean isPrime=false;
boolean nums[]=new boolean[n];
for (int i=0; i<=2; i++) {
nums[i]=true;
// System.out.print(nums[i]);
}
for (int i=4; i<=n; i++) {
int m=i/2;
for (int j=2; j<=m; j++) {
if (i%j==0) {
isPrime=false;
break;
}
else {
isPrime=true;
}
}
nums[i-1]=isPrime;
}
char[] digits = new char[n];
for (int i=0; i<n; i++) {
if (nums[i]) {
digits[i]='1';
}
else {
digits[i]='0';
}
}
for (int i=0; i<n; i++) {
if (digits[i]==1) {
System.out.println (new String (digits, 0, i+1));
/*for (int j=0; j<i; j++) {
System.out.print(digits[i]);
}
System.out.println(); */
}
}
}
}
Use Sieve of Eratosthenes to build a char[] of 0's and 1's, then print all substrings ending in 1.
static void printPrimeTriangle(int n) {
char[] primes = new char[n];
Arrays.fill(primes, '1');
for (int sqrt = (int) Math.sqrt(n) + 1, i = 1; i < sqrt; i++)
if (primes[i] == '1')
for (int prime = i + 1, j = prime * 2 - 1; j < n; j += prime)
primes[j] = '0';
for (int i = 0; i < n; i++)
if (primes[i] == '1')
System.out.println(new String(primes, 0, i + 1));
}
Test
printPrimeTriangle(80);
Output
1
11
111
11101
1110101
11101010001
1110101000101
11101010001010001
1110101000101000101
11101010001010001010001
11101010001010001010001000001
1110101000101000101000100000101
1110101000101000101000100000101000001
11101010001010001010001000001010000010001
1110101000101000101000100000101000001000101
11101010001010001010001000001010000010001010001
11101010001010001010001000001010000010001010001000001
11101010001010001010001000001010000010001010001000001000001
1110101000101000101000100000101000001000101000100000100000101
1110101000101000101000100000101000001000101000100000100000101000001
11101010001010001010001000001010000010001010001000001000001010000010001
1110101000101000101000100000101000001000101000100000100000101000001000101
1110101000101000101000100000101000001000101000100000100000101000001000101000001
....:....1....:....2....:....3....:....4....:....5....:....6....:....7....:....8
#kalina199
Here is my approach at it - I was able to reduce it to just one loop :)
package bg.Cholakov;
import java.util.Scanner;
public class PrimeTriangle {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine());
int[] array = new int[n];
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0, j = 1; i < n; i++, j++) {
array[i] = j;
if (isPrime(array[i])) {
array[i] = 1;
stringBuilder.append(String.valueOf(array[i]));
System.out.println(stringBuilder);
} else {
array[i] = 0;
stringBuilder.append(String.valueOf(array[i]));
}
}
}
static boolean isPrime(int number) {
for (int i = 2; i <= number / 2; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
Problems in your code:
You have set the value of isPrime to true within the loop. You can not tell if the number is prime until you have divided it with each counter of the loop and found that it is not divisible by any of the loop counters. Therefore, it should be done only when the loop is finished.
In the declaration, for (int i=4; i<=n; i++), you have declared i=4 for the number 5 i.e. you want to set nums[4] to true if 5 is prime or false if 5 is not prime. It means that you want to test 5 (not 4) for the primality. In your code, you have tested 4 for primality.
Given below is the corrected code:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the limit: ");
int n = Integer.parseInt(input.nextLine());
boolean nums[] = new boolean[n];
for (int i = 0; i <= 2; i++) {
nums[i] = true;
}
for (int i = 3; i < n; i++) {
int num = i + 1, m = num / 2, j;
for (j = 2; j <= m; j++) {
if (num % j == 0) {
nums[i] = false;
break;
}
}
// If j>m, it means that the loop did not terminate because of `break`
if (j > m) {
nums[i] = true;
}
}
// Display nums[] for testing
System.out.println(Arrays.toString(nums));
for (int j = 0; j < n; j++) {
if (nums[j] == false) {
continue;
} else {
for (int i = 0; i <= j; i++) {
if (nums[i] == true) {
System.out.print("1");
} else {
System.out.print("0");
}
}
System.out.println();
}
}
}
}
A sample run:
Enter the limit: 15
[true, true, true, false, true, false, true, false, false, false, true, false, true, false, false]
1
11
111
11101
1110101
11101010001
1110101000101
Additional notes:
I have removed an unnecessary variable, boolean isPrime. The array, boolean nums[] is sufficient in itself. I've also printed nums[] so that you can actually see what values have been set in this array.
A boolean variable has only two values, true and false. Therefore, if you check one value of a boolean variable in if, the else part becomes true for the other value e.g. in the following code, else if (nums[j]==true) is unnecessary and it can simply be written as else.
if (nums[j]==false) {
continue;
} else if (nums[j]==true) {
//...
}
A better approach:
You can make your code much cleaner by using a separate function to determine if a number is prime.
You do not need to check prime by dividing the number by each integer up to half of its value; you just need to divide the number by integers up to its square root. Check this to learn more about it.
Notice how my code looks cleaner by using the ternary operator. Check this to learn more about the ternary operator.
public class Main {
public static void main(String[] args) {
final int N = 5;
StringBuilder sb;
for (int i = 1; i <= N; i++) {
sb = new StringBuilder();
for (int j = 1; j <= i; j++) {
sb.append(j == 1 || isPrime(j) ? 1 : 0);
}
if (sb.charAt(sb.length() - 1) != '0') {
System.out.println(sb);
}
}
}
static boolean isPrime(int n) {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
Output:
1
11
111
11101
As per your requirement, even though 1 is not a prime number, a 1 should be printed for it. Also, as per this requirement, we do not need to test 0 or a negative integer for primality. Therefore, I have not put any check for 0, or 1 or a negative number in the method, isPrime to keep it clean and just relevant for this requirement.
I created an int array containing 1s and 0s and printed the triangle with two nested for loops. The outer loops is i

Extracting Prime Numbers

I need to create a method that will mark the prime numbers and return the count of the prime numbers.
I went this far:
private static int[] extractPrimesNumbers(int[] array, int countOfPrimeNumbers) {
int[] primeNumber = new int[countOfPrimeNumbers];
int position = 0;
for (int j = 2; j < array.length; j++) {
for(int key : array) {
if(j == 2) {
array[position] = j;
}
boolean isDividedByJ = j % j == 0;
boolean isDividedbyTwo = j % 2 != 0;
if(isDividedByJ && isDividedbyTwo) {
array[position] = j;
position++;
j++;
}
}
I don't know how to mark none prime numbers. I was thinking the good way is marking the none prime with 0, then calculate the amount of value from position/index which are higher than 0.
Worth to mention this all things needs to be in one method using array. Can't use any standard solution for Prime using external boolean methods.
just return an array of the numbers that are prime, no need to mark. and the diff in the cont of the new array and the old one gives you a cont of the non prime as well.
Here is my solution approach.
1) First crete a very simple method to check whether a number is prime or not. See below:
public static boolean checkPrime(int number) {
if (number <= 1) {
return false;
}
System.out.println(number);
for (int i=2; i <= Math.sqrt(number); i++) {
if(number % i == 0) {
System.out.println(i);
return false;
}
}
return true;
}
2) Create another method that will loop through your array and call the above method:
public static int numOfPrimesInArray(int[] arr){
int counter = 0;
for (int num: arr){
if (checkPrime(num)) counter++;
}
return counter;
}
3) Then simply call this from your main method:
public static void main(String[] args){
int[] nums = {1,2,3,5,6,7,8,9,10};
int primes = numOfPrimesInArray(nums);
System.out.println(primes);
}
If I did not make any mistake when writing this shoul give you the number of primes in your array.
I solved the problem with Python. I tried a couple of alternatives and this one is the quickest. Still, I encountered a memory overflow at 1000000.
n = int(input("Type a number"))
primes = 0
for j in range(2,n+1):
for k in range(2,j):
if j%k==0:
primes = primes +1
#print(j)
break
print(n-1-primes)

How would I write a function in Java that prints out perfect numbers less than n?

I am attempting to write a function in Processing that prints out all perfect numbers less than n for my homework pset. However, I am having trouble finding an algorithm that matches the problem.
I have written a for-loop that cycles through all of the numbers between 1 and n. Since the sum of all of its divisors equals the perfect number, I made an if-statement checking the remainders of n and then adding them onto a sum variable, called "result." Then, at the end of this loop, if result equals to n, I printed it out.
void perfect(int n) {
int result = 0;
for(int i = 1; i < n; i++) {
if(n % i == 0) {
result = result + i;
}
}
if( result == n) {
println(n);
}
}
Currently, my code is not printing out anything. When I removed the if-statement towards the end, it printed out all of the values of n, but not perfect numbers. I believe that there is an error somewhere in my code that is making it so that n is never equal to "result."
you will have to use nested for-loop to get all the perfect numbers from 1 to n. As below:
int i, sum = 1;
System.out.print("Perfect nos from 1 to n are 1,");
for (int j = 2; j <= n; j++)
{
sum = 1;
for (i = 2; i < j; i++)
{
if (j % i == 0)
sum = sum + i;
}
if (j == sum)
System.out.print(j + ",");
}

Project Euler #49 Java

The question is -
The arithmetic sequence, 1487, 4817, 8147, in which each of the terms
increases by 3330, is unusual in two ways: (i) each of the three terms
are prime, and, (ii) each of the 4-digit numbers are permutations of
one another.
There are no arithmetic sequences made up of three 1-, 2-, or 3-digit
primes, exhibiting this property, but there is one other 4-digit
increasing sequence.
What 12-digit number do you form by concatenating the three terms in
this sequence?
I've written this code -
package Problems;
import java.util.ArrayList;
import java.util.LinkedList;
public class Pro49 {
private static boolean isPrime(int n){
if(n%2 == 0) return false;
for(int i = 3; i<= Math.sqrt(n); i++){
if(n%i == 0) return false;
}
return true;
}
private static boolean isPerm(int m, int n){
ArrayList<Integer> mArr = new ArrayList<>();
ArrayList<Integer> nArr = new ArrayList<>();
for(int i = 0; i<4; i++){
mArr.add(m%10);
m /= 10;
}
for(int i = 0; i<4; i++){
nArr.add(n%10);
n /= 10;
}
return mArr.containsAll(nArr);
}
public static void main(String[] args) {
LinkedList<Integer> primes = new LinkedList<>();
for(int i = 1001; i<10000; i++){
if(isPrime(i)) primes.add(i);
}
int k = 0;
boolean breaker = false;
for(int i = 0; i<primes.size() - 2; i++){
for(int j = i + 1; j<primes.size() - 1; j++){
if(isPerm(primes.get(i), primes.get(j))) {
k = primes.get(j) + (primes.get(j) - primes.get(i));
if(k<10000 && primes.contains(k) && isPerm(primes.get(i), k)) {
System.out.println(primes.get(i) + "\n" + primes.get(j) + "\n" + k);
breaker = true;
break;
}
}
if(breaker) break;
}
if(breaker) break;
}
}
}
I added the print line System.out.println(primes.get(i) + "\n" + primes.get(j) + "\n" + k); to check the numbers. I got 1049, 1499, 1949 which are wrong. (At least 1049 is wrong I guess).
Can any one point out where my code/logic is wrong?
Any help is appreciated.
I think where your logic is going wrong is your isPerm method. You are using AbstractCollection#containsAll, which, AFAIK, only checks if the parameters are in the collection at least once.
i.e. it basically does
for(E e : collection)
if(!this.contains(e)) return false;
return true;
Therefore, for example, 4999 will be a permutation of 49 because 49 contains 4 and 9 (while it is clearly not based on your example).
The reason why your method seems to work for these values is that you are looping a fixed amount of time - that is, 4. For a number like 49 you will end up with {9, 4, 0, 0} instead of {9, 4}. Do something like this:
while(n != 0) {
nArr.add(n%10);
n /= 10;
}
and you will get the correct digit Lists (and see that containsAll won't work.)
Add the 4-digit restriction elsewhere (e.g. in your loop.)
Maybe you could check the occurrences per digit.
For example:
int[] occurrencesA = new int[10], occurrencesB = new int[10];
for(; m != 0; m /= 10)
occurrencesA[m % 10]++;
for(; n != 0; n /= 10)
occurrencesB[n % 10]++;
for(int i = 0; i < 10; i++)
if(occurrencesA[i] != occurrencesB[i]) return false;
return true;
I found a possible alternative for isPerm
private static boolean isPerm(int m, int n){
ArrayList<Integer> mArr = new ArrayList<>();
ArrayList<Integer> nArr = new ArrayList<>();
final String mS = Integer.toString(m);
final String nS = Integer.toString(n);
if(mS.length() != nS.length()) return false;
for(int i = 0; i<mS.length(); i++){
mArr.add(m%10);
m /= 10;
}
for(int i = 0; i<nS.length(); i++){
nArr.add(n%10);
n /= 10;
}
return (mArr.containsAll(nArr) && nArr.containsAll(mArr));
}
This is giving me the correct answer. Another alternative is posted by some other person below.

Calculate factorial of 50 using array only in java

I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184

Categories