Prime Number test in java - java

public static boolean isPrime(int number)
{
boolean result = true;
if (number == 0)
{
result = false;
}
for (int i=2; i < number/2; i++)
{
if (number % i == 0)
{
result = false;
}
}
return result;
}
Any ideas why when int number = 4, the result returns as true? What can I do to fix this? I am happy with the code I have but why does 4 return as true?

for (int i=2; i < number/2; i++)
If you enter 4 here, it will never enter the loop because
2 < 4 / 2
never equates to true (2 is not smaller than 2).
Instead, use <=.

Effective way how to do this method is :
(sorry for duplication, but after some time, someone can find this topic and not previous one)
public static boolean isPrime(int number) {
//Everything less or equal 1 is not prime number
if (number <= 1) {
return false;
}
//2 is very special case, so I check it separately
if (number == 2) {
return true;
}
//This will help me rid off all even numbers
if (number % 2 == 0) {
return false;
}
//It is important to count the sqrt before using it in for-loop condition.
//If you use it in for-loop condition, it will be counted every single iteration.
int square = (int) Math.sqrt(number);
//I already checked %2, so now I need to check only odd numbers
for (int i = 3; i <= square; i += 2) {
if (number % i == 0) {
//If I find one number, I do not have to continue
return false;
}
}
return true;
}

Your for loop never executes when number = 4. This is because:
for (int i=2; i < number/2; i++)
Executes when i == 2 and i < 2. That will never happen if number == 4, because then it'll be i < 4 / 2 which is i < 2. To solve this, remove the /2 or do something else... not quite sure what you're going for there.

When number==4 the boolean condition of the first if is false and the first evaluation of the for condition is also false. So the result is the value you used to initialize result (true).

Also, you might want to return the result instead of storing it in a variable because the code will continue to execute after the first conditional... So here is the working solution:
public static boolean isPrime(int number) {
if (number <= 1) { /* Since 1 isn't technically a prime number */
return false;
}
for (int i=2; i <= number/2; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}

Another solution:
public static boolean isPrime(int number) {
if (number < 2) {
return false;
}
for (int i=2; i <= (int)Math.sqrt(number); i++) {
if (number % i == 0) {
return false;
}
}
return true;
}

Better and faster version of your code:
public static boolean isPrime(int number) {
if (number <= 1) {
return false;
}
for (int i=2; i*i <= number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}

Related

Why is my program not continuing after the first 10 Palindromic numbers? And also Why is my isPrime method not returning false for the number 4?

I'm not sure why my ct is not going all the way to 100 even though I clearly set it to go until it reaches 100.
public class PalindromicPrime
{
public static void main(String [] args)
{
int ct = 0;
while(ct < 100)
{
if(isPalindrome(ct) && isPrime(ct))
{
if(ct % 10 != 0)
{
System.out.print(ct + " ");
}
else
{
System.out.print("\n");
}
}
ct++;
}
public static boolean isPalindrome(int p)
{
int palindrome = p;
int reverse = 0;
while (palindrome != 0)
{
int remainder = palindrome % 10;
reverse = reverse * 10 + remainder;
palindrome = palindrome / 10;
}
if (p == reverse)
{
return true;
}
return false;
}
I'm assuming my isPrime code is wrong since I'm getting a 4 in my output. What's wrong with this method?
public static boolean isPrime(int p)
{
for(int i = 2; i < p/2; i++)
{
if(p % i == 0)
{
return false;
}
}
return true;
}
}
First change you should do in your method isPrime() is change this line
for(int i = 2; i < p/2; i++)
to
for(int i = 2; i <= p/2; i++) // you can easily find the reason why it is necessary(=)
And also you are printing palindromic numbers less than 100 which are prime,not first 100 palindrome numbers, if you want to print first 100 palindrome numbers you can take another counter which will keep track of the numbers printed.
You can modify your main method like this:
public static void main(String [] args)
{
int ct = 0,n=0; // n to count numbers printed/found
while(n < 100) // change the condition to check n<100
{
if(isPalindrome(ct) && isPrime(ct))
{
System.out.print(ct + " ");
if(n % 10 == 0)
{
System.out.println();
}
n++; // incementing n after a number is found!
}
ct++;
}
}
Your palindrome method is fine. It's your isPrime method that's not working because to check if a number is prime, you're supposed to test factors up to the square root of the number. So a simple change in the condition should do it,
public static boolean isPrime(int p)
{
for(int i = 2; i <= Math.sqrt(p); i++)
{
if(p % i == 0)
{
return false;
}
}
return true;
}
}
Change your isPrime function to following (replace < with <= as 4/2 is 2 and loop will not run at all for p=4):
public static boolean isPrime(int p) {
for (int i = 2; i <= p / 2; i++) {
if (p % i == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
int ct = 2;
int count = -1;
while (count < 99) {
if (isPalindrome(ct) && isPrime(ct)) {
count++;
if (count % 10 == 0) {
System.out.print("\n" );
}
System.out.print(ct + " ");
}
ct++;
}
}
The only numbers that are palindrome and prime and less than 100 are:
1 2 3 5 7 11
Try changing the value of 100 to 102. Then you get the following output as 101 is the next palindromic prime after 11:
1 2 3 5 7 11 101

Checking if number is ugly

I'm doing this problem:
Write a program to check whether a given number is an ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7.
Note that 1 is typically treated as an ugly number.
Here's my attempt:
public class Solution {
public boolean isUgly(int num) {
if (num == 1) {
return true;
}
for (int i = 7; i <= num / 2; i++) {
if (isPrimeFactor(i, num)) {
return false;
}
}
return true;
}
public boolean isPrimeFactor(int candidate, int num) {
return isPrime(candidate) && isFactor(candidate, num);
}
public boolean isPrime(int num) {
if (num == 2) {
return true;
}
if (num % 2 == 0) {
return false;
}
for (int i = 3; i <= Math.sqrt(num); i += 2) {
if (num % i == 0) {
return false;
}
}
return true;
}
public boolean isFactor(int candidate, int num) {
return (num % candidate == 0);
}
}
Unfortunately, it fails on test input -2147483648. It returns true when it should be false.
Any idea what I've done wrong?
You simply forgot the following emphasized condition:
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.
Therefore, you just need to add a check for negative numbers inside your isUgly method:
if (num <= 0) {
return false;
}
As a side-note, you could perhaps improve a little the performance by swapping the conditions inside isPrimeFactor and testing isFactor(candidate, num) && isPrime(candidate) instead of isPrime(candidate) && isFactor(candidate, num). This is because it is faster to determine whether a number is a factor of another than determining if a number is a prime number.
I could propose a different but a lot faster solution O(logn) for this problem:
public static boolean isUgly(int num) {
if (num < 1) return false;
int temp;
do {
temp = num;
if (num % 2 == 0) num /= 2;
if (num % 3 == 0) num /= 3;
if (num % 5 == 0) num /= 5;
} while (temp != num);
return num == 1;
}
or an even faster approach in terms of modular checks (by splitting the do while loop):
public static boolean isUgly(int num) {
if (num < 1) return false;
int temp;
do {
temp = num;
if (num % 2 == 0) num /= 2;
} while (temp != num);
do {
temp = num;
if (num % 3 == 0) num /= 3;
} while (temp != num);
do {
temp = num;
if (num % 5 == 0) num /= 5;
} while (temp != num);
return num == 1;
}

Finding prime numbers in an array of 10 numbers

Once I took from the user 10 numbers and placed them in an array of size 10, I want to check for each number in the array if it is prime or not and count how many prime numbers there is. Here is what I tried to do:
int count=0;
for(int r=0;r<10;r++) {
for(int t=2; t < array[r];t++) {
if(array[r] % t != 0) {
count++;
}
}
}
array[r] is already filled with numbers at this point, so all I need to do is to check for each number if it is prime or not.
Here is another way you can check for prime numbers. It does not increment by 1, so it is faster.
int count=0;
for(int r=0;r<10;r++){
if (isPrime(array[r])) count++;
}
And the method:
public static boolean isPrime(int n) {
if(n < 2) return false;
if(n == 2 || n == 3) return true;
if(n%2 == 0 || n%3 == 0) return false;
int sqrtN = (int)Math.sqrt(n)+1;
for(int i = 6; i <= sqrtN; i += 6) {
if(n%(i-1) == 0 || n%(i+1) == 0) return false;
}
return true;
}
int a[] = {0,1,2,3,4,5,6,7,8,9};
int count=a.length;
boolean flag=true;
for(int i=0;i<a.length;i++)
{
for(int j=2;j<a[i];j++)
{
if(a[i]%j==0)
{
flag=false;
break;
}
}
if(flag==false)
{
count--;
}
}
System.out.println(count);

Solution of twoTwo riddle on codingBat in Java

The question is about Solving this problem from codingBat in Java.
Problem Statement:
Given an array of ints, return true if every 2 that appears in the array is next to another 2.
twoTwo({4, 2, 2, 3}) → true
twoTwo({2, 2, 4}) → true
twoTwo({2, 2, 4, 2}) → false
First of all going by the problem statement that every 2 that appears in the array is next to another 2. then
do you think as suggested the outcome for the first inputs shown above
should be true?
twoTwo({4, 2, 2, 3}) → true
Because as I see it it the first 2 itself that appears in the array is next to 4 not 2
am I confused or it's a wrongly stated question? I had to grapple with the problem to somehow get the right code to crack the problem as below but it seems a hotch potch:
public boolean twoTwo(int[] nums) {
if(nums.length==0)
{
return true;
}
if(nums.length==1)
{
return !(nums[0]==2);
}
if((nums.length==2))
{
if((nums[1]==2)&&(nums[0]==2))
return true;
else
return false;
}
for(int i=0;i+2<nums.length;i++)
{
if((nums[i]!=2)&&(nums[i+1]==2)&&(nums[i+2]!=2))
return false;
}
if((nums[nums.length-2]!=2)&&(nums[nums.length-1]==2))
return false;
return true;
}
Any efficient alternate solutions are welcome.
Thanks!
Here's how I would do it. It's a bit easier to follow I think:
public boolean twoTwo(int[] nums)
{
for (int i=0; i<nums.length; i++)
{
if (nums[i] != 2)
continue;
if (i >= 1 && nums[i-1] == 2)
continue;
if (i < (nums.length-1) && nums[i+1] == 2)
continue;
return false;
}
return true;
}
The solution I got to the problem is below:
public boolean twoTwo(int[] nums) {
final int length = nums.length;
for (int i = 0; i < length;){
int count = 0; // Used to count following 2's
while(i < length && nums[i++] == 2){
count++;
}
if(count == 1){ // No adjacent 2's! Set doesn't work.
return false;
}
}
return true; // Didn't come across a lone 2
}
The way that I handle this, is that I count all the adjacent 2's. If the count is not 1, we are good. This means that there was either no 2 at that index, or a group of 2's was present. This holds, since we traverse the array in a single direction.
A good thing about this solution is that it will work for an array of any size. Note that it would have a linear complexity, even though 2 loops are present. They both just traverse using the same index value, only ever sweeping over the array once.
If at any time we find a 2, then check the following only to find there are 0 following 2's (denoted by count), we return false.
public boolean twoTwo(int[] nums) {
for (int i=0; i<nums.length; i++) {
if(nums[i] == 2) { //If current number is 2
if (
// if prev or next is not 2 return true
!(i-1>=0 && nums[i-1] == 2) &&
!(i+1<nums.length && nums[i+1] == 2)
) { return false; }
}
}
return true;
}
For the sake of simplicity and clean code, this code forces the check
i-1>=0 and i+1<nums.length in every iteration.
This can be avoided by iterating from (1...nums.length-1) and checking the edge cases separately.
I know this is an old question, but I came up with a new solution. Short, and with no complicated conditionals.
public boolean twoTwo(int[] nums) {
int position = -2;
boolean result = true;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 2) {
result = position == i - 1;
position = i;
}
}
return result;
}
Next to means either before or after. Loop through each number and check the values before and after to see if there's an adjacent 2. The special cases are when you're checking the 1st and last element because there won't be an element before or after to check.
public boolean twoTwo(int[] nums) {
if(nums.length == 1 && nums[0] == 2)
return false;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == 2) {
if(i == 0) { // check the next element
if(nums[i+1] != 2)
return false;
}
else if(i == (nums.length - 1)) { // check the previous element
if(nums[i-1] != 2)
return false;
}
else { // check both
if(nums[i+1] != 2 && nums[i-1] != 2)
return false;
}
}
}
return true;
}
Here is mine solution to two two's problem. I think my solution is clear i.e. understandable.
package codingbat.array2;
public class TwoTwo
{
public static void main(String[] args)
{
}
public boolean twoTwo(int[] nums)
{
boolean twoTwo = true;
for (int i = 0; i < nums.length; i++)
{
if (2 == nums[i])
{
if (i > 0 && 2 == nums[i - 1]
|| nums.length > i+1 && 2 == nums[i+1])
{
twoTwo = true;
i++;
}
else
{
twoTwo = false;
break;
}
}
}
return twoTwo;
}
}
public boolean twoTwo(int[] nums) {
for(int i = 0 ; i < nums.length; i++ ) {
int count = 0;
if(nums[i] == 2 ) {
while(i+1 < nums.length && nums[i+1] == 2 ) {
count ++;
i++;
}
if (count == 0 ) {
return false;
}
}
}
return true;
}
public boolean twoTwo(int[] nums) {
for(int i = 0;i<nums.length;i++)
if(nums[i]==2 && !isTwoBeforeOrAfter(nums,i))
return false;
return true;
}
private boolean isTwoBeforeOrAfter(int[] nums,int i){
return i+1<nums.length && nums[i+1]==2 || i-1>=0 && nums[i-1]==2;
}
public boolean twoTwo(int[] nums) {
float two = 0;
double count = 0;
for (int i = 0; i < nums.length; i++) {
if (i < nums.length - 2 && nums[i] == 2 && nums[i + 1] == 2 && nums[i + 2] == 2) {
return true;
}
if (i < nums.length - 1 && nums[i] == 2 && nums[i + 1] == 2) {
count++; //count the pair
}
if (nums[i] == 2) {
two++;
}
}
return ((count * 2) == two);
//each pair contain 2 ,two"s .so pair*2=total two counts
//count
}
public boolean twoTwo(int[] nums) {
boolean two = false;
boolean result = true;
for (int i=0; i<nums.length; i++) {
if (nums[i] == 2) {
if (two) {
result = true;
} else {
result = false;
}
two = true;
} else {
two = false;
}
}
return result;
}
Here's my solution. Enjoy.
public boolean twoTwo(int[] nums)
{
//If the length is 2 or more
if (nums.length >= 2)
{
//If the last char is a 2, but the one before it is not a char, we return false;
if (nums[nums.length - 1] == 2 && nums[nums.length - 2] != 2)
{
return false;
}
//If larger than three, we create a for loop to test if we have any 2s that are alone.
if (nums.length >= 3)
{
for (int i = 1; i < nums.length-1; i++)
{
//If we find a two that is alone, we return false;
if ((nums[i] == 2) && (nums[i-1] != 2 && nums[i+1] != 2))
{
return false;
}
}
}
//If we don't return false, we return true;
return true;
}
//If we have less than two characters, we return true if the length is 0, or \
//One the one number there is not a 2.
else
{
return ((nums.length == 0) || !(nums[0] == 2));
}
}
public boolean twoTwo(int[] nums) {
int len = nums.length;
Boolean check = false;
int count = 0;
for(int i=0; i<len ; i++){
if(nums[i]==2){
count++;
if((i<len-1 && nums[i+1]==2) || (i>0 && nums[i-1]==2)) check = true;
else check = false;
}
}
if(count==0) check = true;
return check;
}
public boolean twoTwo(int[] nums) {
int count = 0;
for (int i = 0; i < nums.length; i++)
if (nums[i] == 2) count++;
else if (count == 1) return false;
else count = 0;
return count != 1;
}
Every time we encounter a 2, we increase the counter of consecutive 2s.
When it's not a 2 — but the counter indicates that there was a single 2 before it —, we know we've found a lonely 2.
Otherwise the search continues, resetting the 2-counter.
easy to understand)
static boolean twoTwo(int[] nums) {
int len = nums.length;
boolean result = true;
boolean found = false;
for(int i=0; i<len; i++){
//if it not 2, no meaning to go true other if-s
if(nums[i] !=2) {found = false; continue;}
// if current element is 2 and found is true(last element is 2)
if(nums[i] ==2 && found) result = true;
// if current element is 2, but last element not
if(nums[i] ==2 && !found){
found = true;
result = false;
}
}
return result;
}
This might be easier to follow if the other suggestions confuse you..
public boolean twoTwo(int[] nums) {
int len = nums.length;
if(len == 0) return true; // no 2's to worry about
if(len == 1) return nums[0] != 2; // make sure it's not a single 2
for(int i = 1; i < len -1; i++){ // loop for each except edge cases
if(nums[i] == 2 && nums[i-1] != 2 && nums[i+1] != 2) return false; // check surrounding
}
if(nums[len - 1] == 2) return nums[len - 2] == 2; //if last num is 2 check for 2 before it
return true; // made it here it's true
}
that one was tough for me... here's mine:
public boolean twoTwo(int[] nums) {
boolean two = false, res = true;
for (int i : nums) {
if (i == 2) {
if (two)
res = true;
else {
two = true;
res = false;
}
} else {
two = false;
}
}
return res;
}
One more alternative. Here is the main idea:
Convert array into String. Add a character different from "2" at the beginning and end of the string, to avoid going out of bounds.
Look for standalone "2" - if element of the string is equal to 2, check whether chars immediately before and after are also equal to "2". If they are it means that not all "2" are adjacent, and therefore method returns false.
public boolean twoTwo(int[] nums) {
// convert array to string
String text = "";
for (int i = 0; i < nums.length; i++) {
text += String.valueOf(nums[i]);
}
text = " " + text + " ";
// find standalone "2"
for (int i = 1; i < text.length() - 1; i++) {
if (text.charAt(i) == '2' && text.charAt(i - 1) != '2' && text.charAt(i + 1)
!= '2') {
return false;
}
}
return true;
}

Trouble with factor generator

I'm having some trouble in completing this factor generator from my programming class. It's supposed to take a number, and print out all the factors using the nextFactor method. When I set the number to factor to let's say 150, it prints out "1 2 3 5", where it's supposed to print "2 3 5 5". So, where should I go from here? I've looked at Java - Factor Generator program nextfactor method, but it didn't awnser any of my inqueries
public class FactorGenerator
{
//user inputs int from scanner in FactorTester class
public FactorGenerator(int i)
{
num = i;
}
//Checks to see if num can be factored, but does not factor it.
//Goes through all possible factors of num and returns true if the remainder == 0
public boolean hasMoreFactors()
{
for(int i = 1; i < num; i++)
{
//check if the remainder is anything other then 0
if(num % i == 0)
{
return true;
}
}
return false;
}
//Actually factors num and prints out the factor at the end of every loop.
public void nextFactor()
{
for(int i = 1; i < num; i++)
{
//check if the remainder is anything other then 0
if(num % i == 0)
{
System.out.println(i);
num /= i;
}
}
System.out.println("Done.");
}
private int num;
}
try this factors can duplicate so you need to loop until you have extracted all the instances of that factor
public void nextFactor()
{
for(int i = 2; i <= num; i++)
{
//check if the remainder is anything other then 0
while (num >= i && num % i == 0)
{
System.out.println(i);
num /= i;
}
}
System.out.println("Done.");
}
an alternative way is to do the increment in the body of the loop
public void nextFactor()
{
for(int i = 2; i <= num;)
{
//check if the remainder is anything other then 0
if (num % i == 0)
{
System.out.println(i);
num /= i;
} else {
i++;
}
}
System.out.println("Done.");
}
For starters, it will always print out 1 because any integer / 1 will always have remainder of zero. You can start i from 2 instead of 1 in your for if you want to skip 1.
I'd suggest something like this: (note this is based in part on BevynQ's answer below):
for(int i = 2; i <= num; i++){
while (num >= i && num % i == 0) {
System.out.println(i);
num /= i;
}
}

Categories

Resources