How to calculate prime fibonacci numbers? - java

(This is an extension from my previous question).
How to print a text notification beside prime fibonacci numbers?
Task:
The section of the assignment I am having difficulty with reads as follows:
Determine which of the first 20 Fibonacci numbers are prime numbers.
Put a “this is a prime” text notification in the printout from the Basic challenge.
Store the FibPrimes in an array called FibPrimes.
Problem:
I cannot seem to figure out how to take each individual fibonacci number, determine it is prime, put the prime fibonacci numbers in an array, and print the output. I was able to make a working program previously, but I didn't use code to calculate the primes, I manually entered them into an array (see previous attempt at bottom).
Attempt:
Here is what I have attempted:
The code that is relevant to this question is emphasized with comments.
package fibonaccinumbers;
public class FibonacciNumbers {
public static void main(String[] args) {
// Creation of Fibonacci Numbers Array.
// Let i represent the index number.
int [] FibNums = new int[20];
FibNums[0] = 0;
FibNums[1] = 1;
// Will add on each successive FibNums.
// Will be used to calculate average.
int FibSum = 1;
// RELEVANT TO QUESTION.
// Creation if Fibonacci Primes Array.
// Let n represent the index number.
int [] FibPrimes = new int[7];
int n=0;
// Printing first two fibonacci numbers.
System.out.println(0);
System.out.println(1 + "*");
// Printing remaining fibonacci numbers up to 20th term.
for (int i=2; i<FibNums.length;i++){ // Begin number generation loop.
FibNums[i] = FibNums[i-1] + FibNums[i-2];
// Checks if the fibonacci number is odd.
// A number is not odd if two divides into it evenly.
boolean oddcheck = true;
if (FibNums[i]%2==0){
oddcheck = false;
}
// RELEVANT TO QUESTION.
// A prime number can only be divided by 1 and inself.
// Divide FibNums[i] by every number inbetween.
// If a number divides evenly, it is not a prime (exception: 2).
// Else, the number is a prime.
boolean primecheck;
for (int divisor = 2; divisor < FibNums[i]/2; divisor++){
if (FibNums[i] % divisor == 0){
primecheck = false;
} else {
primecheck = true;
}
// REVELANT TO QUESTION.
// Add FibNums[i] to the FibPrimes[n] array if it is a prime.
if (primecheck == false){
FibPrimes[n] = FibNums[i];
n = n + 1;
}
// RELEVANT TO QUESTION.
// If any element in the FibPrimes array is equal to the FibNums
// array, then the number is a prime.
for (n=0; n<FibPrimes.length; n++){
if (FibNums[i] == FibPrimes[n]){
System.out.print("This is a prime." + " ");
}
}
// Prints odd fibonacci numbers with a star beside it.
// Prints even fibonacci numbers with no star beside it.
if (oddcheck == true){
System.out.println(FibNums[i] + "*");
} else {
System.out.println(FibNums[i]);
}
FibSum = FibSum + FibNums[i];
} // End number generation loop.
System.out.print ( "The average is" + " " + FibSum/20);
}
}
Output:
0
1*
The average is 0The average is 0The average is 0The average is 0This is a prime. 8
This is a prime. 8
The average is 013*
13*
13*
13*
The average is 321*
This is incorrect.
Previous Attempt:
This solution "worked", but in order to not take the "lazy route" I must do the calculations using code. Only relevant snippets are shown:
// Creation if Fibonacci Primes Array.
// Ideally, this should be caulculated.
int [] FibPrimes = new int[7];
FibPrimes[0] = 2;
FibPrimes[1] = 3;
FibPrimes[2] = 5;
FibPrimes[3] = 13;
FibPrimes[4] = 89;
FibPrimes[5] = 233;
FibPrimes[6] = 1597;
// If any element in the FibPrimes array is equal to the FibNums
// array, then the number is a prime.
for (int n=0; n<FibPrimes.length; n++){
if (FibNums[i] == FibPrimes[n]){
System.out.print("This is a prime." + " ");
}
}
Output:
0
1*
1*
This is a prime. 2
This is a prime. 3*
This is a prime. 5*
8
This is a prime. 13*
21*
34
55*
This is a prime. 89*
144
This is a prime. 233*
377*
610
987*
This is a prime. 1597*
2584
4181*
The average is 547
This is the desired output! However, I cannot use this because I must calculate the prime fibonacci numbers using code. This is the "lazy route".
Thank you.

Just 10 mins on google and you will be able to create something simple and fast.
Using the mathematical formulas below :
which you can find more one this paper you can make your prime fibonacci sequence. In addition you will need a way to check which numbers in the sequence are primes so a quick way is through AKS algorithm
Here is a full example of all the above :
public class FibonacciSequence {
public static void main(String[] args) {
for (int i = 1; i <= 20; i++) {
int num = (int) ((getY_1(i) - getY_2(i)) / Math.sqrt(5));
if (isPrime(num)) {
System.out.print("This is a prime : ");
}
System.out.println(num);
}
}
public static double getY_1(int N) {
return Math.pow((1 + Math.sqrt(5.0)) / 2.0, N);
}
public static double getY_2(int N) {
return Math.pow((1 - Math.sqrt(5.0)) / 2.0, N);
}
public static boolean isPrime(int num) {
if (num == 2 || num == 3)
return true;
if (num % 2 == 0 || num % 3 == 0) {
return false;
}
int i = 5;
int s = 2;
while (i * i <= num) {
if (num % i == 0) {
return false;
}
i += s;
s = 6 - s;
}
return true;
}
}
Of course you can exclude the value (1) if you don't feel like identifying it as a prime :P.
Output :
This is a prime : 1
This is a prime : 1
This is a prime : 2
This is a prime : 3
This is a prime : 5
8
This is a prime : 13
21
34
55
This is a prime : 89
144
This is a prime : 233
377
610
987
This is a prime : 1597
2584
4181
6765
P.S : I had free time :P

Related

Java Basics - Extract digits from a number

I'm new to Java, so still trying to figure out the syntax and code execution,
I'm working on a very simple algorithm which is basically to return/print true or false statement if a number is divisible by the sum of its digits.
public class Main {
public static void main(String[] args) {
divisableNumber();
}
static void divisableNumber() {
int num = 2250;
int sumOfDigits = 0;
while (num > 0) {
System.out.println(num);
int remainder = num %10 ;
sumOfDigits += remainder;
System.out.println("line17");
System.out.println(sumOfDigits);
num = num /10;
}
System.out.println(num);
// if(num % sumOfDigits == 0) {
// System.out.println( num);
// } else {
// System.out.println(num + "is not divisable by sum of digits");
// }
}
//*****Explanation*********
// java divides by 10 without remainder.
// Hence, can see that with each iteration number is losing its unit digit( it happens end of each loop line21)
// basically with each iteration we are checking what is the remainder of the input divided by 10
// Eventually, we are adding the remainder ( which is the unit digit at each iteration)
}
``
I don't understand why the loop zeros out the variable and how to overcome it ( i could have written another variable inside the loop , but it seems not clean ).
Can anyone help ?
[enter image description here][1]
[1]: https://i.stack.imgur.com/rZbOW.png
Your code prints 0 every time since it divides the number to 10 until it becomes 0 inside the while loop. Remember that any positive number below 10 divided by 10 gives the result 0 in Java.
You calculated the sum of digits correctly but did not check if it divides the number correctly. In order to achieve that, you need to store a copy of number at the start and check if it is divisible by sumOfDigits.
You can achieve the solution with the following code, it is very similar but structured a little better.
class Main
{
// Function to check if the
// given number is divisible
// by sum of its digits
static String divisableNumber(long n)
{
long temp = n; // store a copy of number
// Find sum of digits
int sum = 0;
while (n != 0)
{
int k = (int) n % 10; // get remainder of division of 10
sum += k; // add digit sum
n /= 10; // divide number by 10
}
// check if sum of digits divides n
if (temp % sum == 0)
return "YES";
return "NO";
}
// This is where the execution begins always (main function)
public static void main(String []args)
{
long n = 123; // better to declare number here and give it as a parameter to function
System.out.println(isDivisible(n)); // print the result of divisible or not
}
}

How does this program to calculate Armstrong numbers between two intervals work step by step?

class Armstrong {
public static void main(String[] args) {
int low = 999, high = 99999;
for(int number = low + 1; number < high; ++number) {
int digits = 0;
int result = 0;
int originalNumber = number;
// number of digits calculation
while (originalNumber != 0) {
originalNumber /= 10;
++digits;
}
originalNumber = number;
// result contains sum of nth power of its digits
while (originalNumber != 0) {
int remainder = originalNumber % 10;
result += Math.pow(remainder, digits);
originalNumber /= 10;
}
if (result == number)
System.out.print(number + " ");
}
}
How does this program work? It would be very helpful. Program to find Armstrong between two intervals? Can someone explain step by step? Help me out.
Steb-by-step Explanantion
Initialize the start and end of the interval with 999 and 9999
You can change these numbers but ensure that low is always lesser than high:
int low = 999;
int high = 99999;
for (int number = low + 1; // Create a variable number and assign it one number greater than low
number < high; // This loop should keep repeating until number is less than high(end of the interval)
++number // After each repetition, increment the value of number by 1
) {
Create a variable digits to store the number of digits in number.
For example, if number is 100, this will be later set as 3 as the algorithm proceeds:
int digits = 0;
Create a variable result that will store the sum of powers of numbers:
int result = 0;
Copy the value of number to a local variable originalNumber because it has to be modified:
int originalNumber = number;
The logic of calculating number of digits in a number is keep dividing it by 10 until the number is 0.
Every time you divide any number by 10, the last digit is stripped out. So every time the last digit is stripped out, increment digit by 1 (digit++)
// number of digits calculation
while (originalNumber != 0) // Continue this while loop till originalNumber is not 0
{
originalNumber /= 10; // Divide the number by 10. Dividing a number by 10 removes its last digit.
++digits; // One digit was removed in the above step, which means it has to be counted, so increment digit by 1
}
// For example, for originalNumber = 423,
// 423 / 10 = 42 : digits = 1 (first loop)
// 42 / 10 = 4 : digits = 2 (second loop)
// 4 / 10 = 0 : digits = 3 (third loop)
// Now originalNumber has become 0, so the while loop condition originalNumber != 0 will be false and the loop will stop.
// Now we have digits = 3, which is the number of digits in 423
// When program reaches here, digits will have the number of digits in the
// number "originalNumber"
Copy number again to originalNumber because we want to modify the number
again and originalNumber has become 0 because of the digit counting loop above:
originalNumber = number;
An Armstrong number is a number which is equal to the sum of digits to the power of its number of digits.
e.g.: in 153, (1^3) + (5^3) + (3^3) = 153. We are obtaining the cube of each digit(1, 5, 3) because 153 has 3 digits 1, 5, 3.
If it was say 50, we would check ( 5^2 + 0^2) because 50 has 2 digits (50 is not Armstrong, because 25 + 0 = 25 which is not equal to 50)
We saw above dividing a number by 10 removes the last digit (423 / 10 = 42)
Similarly, if we only want this last digit, we can get it by modulus 10 (% 10): (423 % 10 = 3) (42 % 10 = 2) (4 % 10 = 4)
// Let's assume originalNumber is 153
while (originalNumber != 0) // Same as above, keep looping till the originalNumber is not 0(i.e. all digits have been removed)
{
Extract the last digit to remainder, (for 153: 153 % 10 = 3) (for 15: 15 % 10 = 5)
int remainder = originalNumber % 10;
Now we have the last digit, we need to raise this digit to the number of
digits i.e. 3(for 153): (3^3) = 27. We do this using Math.pow(3, 3). Add this number to result. In the end after each loop's number's power is added, at the end of the loop, result will contain their sum:
result += Math.pow(remainder, digits);
originalNumber /= 10; // Remove the last digit (same as above, for 153: 153 / 10 = 15)
// After this line finishes, one rightmost digit will be removed, this will keep
// happening till originalNumber = 153 becomes 15, then 1, then 0.
// When originalNumber is 0, loop stops and we will have the total sum in result
}
For an Armstrong number like 153, result will also contain 153. For a non-Armstrong number it will contain something else.
if (result == number) // For 153, both will be equal.
System.out.print(number + " "); // This will only execute if result is equal to number, or in other words, only if the number is Armstrong
}
Improvements
As per single responsibility principle, each function or class must exactly do one thing. You have a monolithic main() method that:
Defines the interval
Counts the digit of each number in the interval
Calculate the sum of powers of digits
Check if number is Armstrong and print it.
I would prefer breaking down each operation to a separate method, so that it improves readability and maintainability while respecting single-responsibiliy principle:
class Armstrong {
public static int countDigits(int number) {
int digits = 0;
while (number != 0) {
number /= 10;
++digits;
}
return digits;
}
public static int digitPowerSum(int number, int power) {
int result = 0;
while (number != 0) {
int remainder = number % 10;
result += Math.pow(remainder, power);
number /= 10;
}
return result;
}
public static boolean isArmstrong(int number) {
int digits = countDigits(number);
int sum = digitPowerSum(number, digits);
return sum == number ; // will return true if both numbers are equal else false
}
public static ArrayList<Integer> armstrongNumbersBetween(int low, int high) {
ArrayList<Integer> numbers = new ArrayList<>();
for(int number = low + 1; number < high; number++) {
if (isArmstrong(number)) {
numbers.add(number);
}
}
return numbers;
}
public static void main(String[] args) {
int low = 999, high = 99999;
ArrayList<Integer> numbers = armstrongNumbersBetween(low, high);
for(int number : numbers) {
System.out.print(number + " ");
}
}
}
Here, each method does exactly one thing and this helps in better reusability. You just have to call the required methods to perform a specific operation.
If something is unclear, let me know.

How to print prime numbers up to the user's entered integer?

Good afternoon everyone,
I'm currently trying to create a program that does the following:
Develop a code that will print all prime numbers up to the user's entered
number. An example of the output:
Enter an integer (2 or above): 19
The prime numbers up to you integer are:
2
3
5
7
11
13
17
19
Unfortunately, there is also a list of "requirements" that need to be met as well:
If the user enters a number below 2, your program should print a message that the number is not valid, and then stop.
A number is a prime number if it is not divisible by any number except 1 and itself.
For this program, in order to test a number to see if it is prime, you should try to divide the number by every value from 2 up to the number-1, to see if it divides evenly or not. For example:
--To see if 5 is a prime number:
5 does not divide evenly by 2
5 does not divide evenly by 3
5 does not divide evenly by 4
therefore 5 is a prime number
--To see if 9 is a prime number:
9 does not divide evenly by 2
9 divides evenly by 3
therefore 9 is not a prime number
This program requires you to write nested loops (that is, a loop inside a loop). One loop will be used to count from 2 up to the user's number so that you can test each of these numbers to see it it is prime. For each of these numbers, x:
A nested loop will check all values from 2 up to x-1 to see if x divides evenly by any of them.
You will need to use a Boolean variable (also referred to as a flag variable) to help you determine whether or not to print a number to the screen
The question above is in regards to my code so far below:
import java.util.*;
public class Something3 {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
//Variable declaration.
int limit, number;
//get input till which prime number to be printed
System.out.print("Enter an integer (2 or above): ");
limit = kbd.nextInt();
kbd.close();
//Will print prime numbers till the limit (user entered integer).
number = 2;
if (limit >=2) {
System.out.println("The prim numbers up to your interger are: " + limit+"\n");
for(int i = 0; i <= limit;){
//print prime numbers only
if(isPrime(number)){
System.out.println(number +"\n");
i++;
}
number = number + 1;
}
}
else
System.out.println("Number is not vaild");
}
//Prime number is not divisible by any number other than 1 and itself
//return true if number is prime.
public static boolean isPrime(int number){
for(int i=2; i==number; i++){
if(number%i == 0){
return false; //Number is divisible, thus not prime.
}
}
return true;//The number is prime.
}
}
Is the limit variable I'm using the issue? Any help would be much appreciated.
your isPrime() method is returning wrong result. for loop condition is wrong i==number it should be i < number
public static boolean isPrime(int number){
for(int i=2; i*i <= number; i++){
if( number % i == 0){
return false; // Number is divisible, thus not prime.
}
}
return true; //The number is prime.
}
To check a number prime or not you don't have to check divisbility from 2 to N, all you need to check upto sqrt(N).
To find prime numbers in a range(N) use Sieve of Eratosthenes
Your actual problem was number variable. Here's your solution. There's no need of variable number. Below is your solution
import java.util.*;
public class Something3 {
public static void main(String[] args) {
Scanner kbd = new Scanner(System.in);
// Variable declaration.
int limit;
// get input till which prime number to be printed
System.out.print("Enter an integer (2 or above): ");
limit = kbd.nextInt();
kbd.close();
if (limit >= 2) {
System.out.println("The prim numbers up to your interger are: "
+ limit + "\n");
for (int i = 1; i <= limit; i++) {
// print prime numbers only
if (isPrime(i)) {
System.out.println(i);
}
}
} else
System.out.println("Number is not vaild");
}
// Prime number is not divisible by any number other than 1 and itself
// return true if number is prime.
public static boolean isPrime(int n) {
if (n % 2 == 0)
// The only even prime is 2.
return (n == 2);
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
}
import java.util.Scanner;
class prime
{
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
System.out.println("enter the value of n");
int n=sc.nextInt();
for(int i=2;i<=n;i++)
{
int count=0;
for(int j=1;j<=i;j++)
{
if(i%j==0)
{
count++;
}
}
if(count==2)
{
System.out.println(i+" ");
}
}
}
}

Prime Number Finder has a mind of its own?

I am making a prime number finder, that would find the prime numbers for a given number that the user inputs. What I have now seems to either miss primes, or add non-primes to the ArrayList. My code seems logical to me, and I'm confused as to why this is happening. Can anyone tell me what I am doing wrong? Or maybe a simpler way to do this (I feel like I am over-complicating)? Some examples of errors would be: Enter 21, only 3 shows as a prime. Enter 11000, 25 and 55 show up (not prime obviously). Thanks in advance!
import java.util.*;
public class PrimeFactors {
public static void main(String args[]) {
long num;
Scanner in = new Scanner(System.in);
System.out.println("\n\n\nThis program finds the prime factors of a given number.\n");
System.out.print("Please enter the number: ");
num = in.nextLong();
System.out.println("\nThe prime factors are: " + primeFactor(num) + "\n");
}
public static ArrayList<Long> primeFactor(long n) {
long output = 0;
long guess = 2;
ArrayList<Long> primeFactors = new ArrayList<Long>();
while (guess <= n) {
long primes = 0;
long i = 2;
long x = 0;
long rt = 1;
long duplicate = 0;
output = n % guess;
// Finds the sqrt.
while (x <= n) {
x = rt * rt;
rt++;
}
// Finds odd factors.
if ((output == 0) && (guess % 2 != 0)) {
// This divides the odd factor by an incrementing number that is not 1 or the number itself.
while (i < rt) {
primes = primes + (guess % i);
// If the sum of the remainders to the division is not 0, then the number is prime.
// I used duplicate to make sure it didn't just go through once and count as prime.
if (primes != 0){
// There were duplicates, so I added them for the division later.
duplicate = duplicate + guess;
// This was used to wait for the while loop to finish, then find if the amount of times the guess went through was equal to its value - 1 and another 1 for the final number (primes are only divisible by one and itself).
if (i == (factors - 1)) {
if ((duplicate / guess) == (guess- 2)) {
primeFactors.add(guess);
}
}
}
i++;
}
}
guess++;
}
return primeFactors;
}
}
The math and logic you're doing here is very strange and I don't quite follow what's happening.
To that end, I would vote +1 for making the code simpler. This can be done with two simple methods. The first method will find factors for a number and run them through a prime checker. If they are a factor and pass the prime check, they get added to the array.
Bonus points: increase the speed of the algorithm by only searching through the bottom half of each of the factor checker and prime checker. Logic being that any value beyond half a number cannot be a factor of that number.
More bonus points for speed, increment by 2 skipping all multiples of 2, since they are automatically not prime. Good luck!
import java.util.ArrayList;
import java.util.Scanner;
/***************************************************
*
* #file: PrimeFactors.java
* #date: Mar 17, 2013
* #author: AaronW
*/
/**
*
* #author AaronW
*/
public class PrimeFactors {
public PrimeFactors() {
}
/**
*
* #param args
*/
public static void main(String[] args) {
long num;
Scanner in = new Scanner(System.in);
System.out.println("\n\n\nThis program finds the prime factors of a given number.\n");
System.out.print("Please enter the number: ");
num = in.nextInt();
System.out.println("\nThe factors are: " + findFactors((double)num) + "\n");
}
public static ArrayList<Integer> findFactors(Double num) {
ArrayList<Integer> factors = new ArrayList<Integer>();
for (int x = 1; x <= num; x++) {
System.out.println("Testing " + num + " % " + x + " = " + num % x);
// First, let's see if a number is factor of your target number
if (num % x == 0) {
System.out.println(x + " is a factor");
// Now that we know it's a factor, let's test to see if it's prime
if (isPrime(x)) {
// If it's prime, add it to the ArrayList
System.out.println("And " + x + " is prime.");
factors.add(x);
} else {
System.out.println("But " + x + " is not prime.");
}
} else {
System.out.println(x + " is not a factor");
}
}
return factors;
}
public static boolean isPrime(double num) {
// Let's start by assuming everything is prime and try to prove that false
// If we fall through the loop without proving it false, we have a prime
boolean prime = true;
for (int x = 2; x < num; x++) {
// if our target number can be divided by any number between 1 and itself, it is not prime
if (num % x == 0) {
prime = false;
}
}
return prime;
}
}
For a start, instead of
long x = 0;
long z = 1;
while (x <= n) {
x = z * z;
z++;
}
while (j < z) {
You can just do this
z = (int) Math.Sqrt(n)
while (j <= z) {
Then for each j I would check if it divides n with no remainder.
If it divides n with no remainder, divide n by j and add j to the prime factors. Then instead of incrementing j, try the same j again, for instance for 9 you do 3 twice for its factors.
Anything more complex than that is unnecessary - you will try each j until it can divide into n no more, and you will always try primes before composites formed of those primes, so you know off the bat you'll end up with only prime factors.
OK, there are a few problems with your code:
j, x, j & n, poorly named variables make for hard work debugging.
Where are your System.out.println() calls so you can see what is going on in your code?
The square root of n would be a more optimal point to stop looking for prime up to n.
Can I suggest you look at this: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes for a rapid way of finding primes.
One suggestion to make the code simpler. In you primeFactors method, first findout is it a factor, which I believe you are already doing, then call another method to determine if this is a prime. If that is prime add to the list.
I'll give you some pseudo-code for a simple to implement (not efficient) algorithm:
the value to factorize is N
keep going until N is equal to one
start at 2 and find lowest number X that divides N evenly
X is one factor
N/X is your new N to factor
Your variable names are inconsistent. factors is particularly bad, as it is only a guess of a single factor. Call it guess instead.
The arithmetic you do with factors, primes, and dup are also strange. Why are you adding to dup or primes? Try being your own computer, and executing your algorithm for the number 12; you'll see that you don't have a correct algorithm at all.
You've foreclosed the possibility of repeated factors by incrementing factors at the end.

Tips to solve problem #41 of project euler

I'm trying to solve Problem 41of project Euler in Java, by counting the number from 99888888 to 80000000(which took very long time :( ), I got 98765431 as an answer, but I'm getting that answer not correct. Could anyone please tell me the reason of not getting the correct answer and how can I speed my program?
A pandigital number doesn't needs to contain all numbers from 1 to 9, but all from 1 to length.
So, you'll need to try all permutations from 1 to 9 starting with 1 digit and going up, filtering all prime numbers and, then, taking largest one.
The only possible prime pandigital numbers are those with length 1, 4, & 7 because every other pandigital number has the sum of its digits divisible by 3.
So, you'd only need to test for 7! = 5040 permutations.
To obtain a solution in a "reasonable" time, you need the following observations based on the special property that a number is divisible by 3 if the sum of its digits is divisible by 3:
divisible by
1+2+3+4 = 10 -
1+2+3+4+5 = 15 3
1+2+3+4+5+6 = 21 3
1+2+3+4+5+6+7 = 28 -
1+2+3+4+5+6+7+8 = 36 3
1+2+3+4+5+6+7+8+9 = 45 3
So, a "big" prime pandigital number has 4 or 7 digits. (a prime number bigger than 3 is not divisible by 3)
Because you want to obtain the biggest number, it's better to start with the 7-digit numbers and continue to check the 4-digit numbers only if the number was not found. For sure, a 4-digit number exists, because it is specified: 2143.
Now, a possible solution looks like this:
public class P41 {
public static void main(String[] args) {
boolean wasFound = false;
for (int nr = 7654321; nr >= 1234567; nr -= 2) { // even != prime
if (isPandigital(nr) && isOddPrime(nr)) {
System.out.println(nr);
wasFound = true;
break;
}
}
if (!wasFound) {
/* not <=, because 1234 is even */
for (int nr = 4321; nr > 1234; nr -= 2) {
if (isPandigital(nr) && isOddPrime(nr)) {
System.out.println(nr);
break;
}
}
}
}
private static boolean isOddPrime(int x) {
int sqrt = (int) Math.sqrt(x);
for (int i = 3; i <= sqrt; i += 2) {
if (x % i == 0) {
return false;
}
}
return true;
}
private static int getNumberOfDigits(int x) {
int count = 0;
while (x > 0) {
count++;
x /= 10;
}
return count;
}
private static boolean isPandigital(int x) {
int numberOfDigits = getNumberOfDigits(x);
Set<Integer> digits = new HashSet<Integer>();
for (int i = 1; i <= numberOfDigits; i++) {
digits.add(i);
}
for (int i = 1; i <= numberOfDigits; i++) {
digits.remove(x % 10);
x /= 10;
}
if (digits.size() == 0) {
return true;
} else {
return false;
}
}
}
Time: 8 ms.
Here is the problem statement:
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime. What is the largest n-digit pandigital prime that exists?
I wrote a program that started with 987654321 and counted down. I checked that the number was pandigital, and if it was, checked if it was prime.
It took 66 seconds on my Windows 8.1 computer to find the largest prime pandigital.
When I tested the other way around, first prime, then pandigital, the program took way longer than 66 seconds. I cancelled it.
When I applied GregS' tip about discounting all 9 digit and 8 digit pandigital numbers, and started counting down from 7654321, my brute force algorithm took 13 milliseconds.

Categories

Resources