Why is my method repeating when I run - java

public class PalindromicPrimes {
public static void main (String[] args) {
userInt();
System.out.println("The palindromic primes less than " + userInt() +
" are:");
for (int i = 0; i <= userInt(); i++) {
if (isPrime() && isPalindrome()) {
System.out.println(i);
}
}
}
private static boolean isPrime() {
if (userInt() == 2 || userInt() == 3) {
return true;
}
if (userInt() % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(userInt()) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (userInt() % i == 0) {
return false;
}
}
return true;
}
private static boolean isPalindrome() {
if (userInt() < 0)
return false;
int div = 1;
while (userInt() / div >= 10) {
div *= 10;
}
while (userInt() != 0) {
int x = userInt();
int l = x / div;
int r = x % 10;
if (l != r)
return false;
x = (x % div) / 10;
div /= 100;
}
return true;
}
private static int userInt() {
Scanner s = new Scanner(System.in);
System.out.print("Enter a positive integer: ");
int userInt = s.nextInt();
return userInt;
}
}
is there a different way of getting the user input? or can I keep it this way?
when it runs it just keeps prompting the user input.

rearrange it like this:
public static void main (String[] args) {
//get it and save it here!
int userValue = userInt();
System.out.println("The palindromic primes less than " + userValue +
" are:");
for (int i = 0; i <= userValue; i++) {
if (isPrime(userValue) && isPalindrome(userValue)) {
System.out.println(i);
}
}
}
then also update all the methods that care about this "userInt" value.
Every time you call userInt() you're telling the code to get a new value from the command line.

Try this:
public static void main (String[] args) {
int value = userInt();
System.out.println("The palindromic primes less than " + value +
" are:");
for (int i = 0; i <= value; i++) {
if (isPrime() && isPalindrome()) {
System.out.println(i);
}
}
}
The term userInt() is a function invocation that prompts the user for input. Odds are you only want to do this once. You're doing it multiple times.

You should store the result of userInt() in a variable.
int typed = userInt();
And then use this variable to reference what the user typed instead of calling userInt() again.
System.out.println("The palindromic primes less than " + typed +
" are:");
for(int i = 0; i < typed; i++) ...

You keep calling userInt(). That is the problem.
I don't understand your logic. So I have not modified that code. But the code runs.
import java.util.Scanner;
public class PalindromicPrimes {
public static void main (String[] args) {
int x = userInt();
System.out.println("The palindromic primes less than " + x +
" are:");
for (int i = 0; i <= x; i++) {
if (isPrime(i) && isPalindrome(i)) {
System.out.println(i);
}
}
}
private static boolean isPrime(int a) {
if (a == 2 || a == 3) {
return true;
}
if (a % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(a) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (a % i == 0) {
return false;
}
}
return true;
}
private static boolean isPalindrome(int a) {
if (a < 0)
return false;
int div = 1;
while (a / div >= 10) {
div *= 10;
}
while (a != 0) {
int x = a;
int l = x / div;
int r = x % 10;
if (l != r)
return false;
x = (x % div) / 10;
div /= 100;
}
return true;
}
private static int userInt() {
Scanner s = new Scanner(System.in);
System.out.print("Enter a positive integer: ");
int userInteger = s.nextInt();
return userInteger;
}
}
Remember, don't use the same names for variable and function. In the function userInt(), you have used a variable int userInt, to get the result from the scanner. This might be aa recursive call sometimes. Be careful with that.

Related

How to let the scanner stop receiving input?

I am trying to get the sum of the prime digit of an integer, but I cannot stop the scanner from getting input.
Here are my codes.
import java.util.Scanner;
public class Exercise {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer: ");
int a = input.nextInt();
System.out.println(Sum(a));
input.close();
}
public static int Sum(int a) {
int sum = 0;
int remainder;
int remainder2;
while (a >= 0) {
remainder = a % 10;
int prime = Prime(remainder);
sum += prime;
a = a / 10;
}
return sum;
}
public static int Prime(int remainder) {
int m = remainder / 2;
int flag = 0;
if (remainder != 0 && remainder != 1 && remainder != 2) {
for (int i = 2; i <= remainder / 2; i++) {
if (remainder % i == 0) {
flag = 1;
break;
}
}
}
if (flag == 1) {
remainder = 0;
}
return remainder;
}
}
It seems your program is going in an infinite loop before input.close(); is called.
change the while to stop at >0
while (a > 0)
and try again.

Java program not outputting correct values

I'm trying to create a simple program that determines if a number can be written as n^x and what n and x are. Ex: 81 = 3^4. My program correctly identifies numbers that can be written as n^x but the values for n and x are way off. (this is just supposed to be an exercise). The logic in my coding is kind of confusing so here's basically what it is. First it finds a number that can divide into a (the chosen number), then it figures out if the a can be divided by the number until it reaches 1. Then it figures out how many times it takes to reach 1. I can't find any problems with the logic. Here's my code.
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
int a = scan1.nextInt();
scan1.close();
int i = 2;
boolean y = false;
int x = 0;
for (; i <= Math.sqrt(a); i++) {
if (a % i == 0) {
int n = i;
for (; n <= a; n *= i) {
if (a % n != 0) {
y = false;
break;
}
x++;
y = true;
}
}
}
if (y == true) {
System.out.println(a + " = " + i + " ^ " + x);
}
else {
System.out.println("Your number cannot be represented as n^x");
}
}
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
int a = scan1.nextInt();
scan1.close();
int i = 2;
boolean y = false;
int x = 0;
for(; i <= Math.sqrt(a); i++) {
if (a % i == 0) {
int n = i;
for (; n <= a; n *= i) {
if (a % n != 0) {
y = false;
}
y = true;
x = n;
break;
}
}
}
i--;
if (y == true) {
System.out.println(a + " = " + i + " ^ " + x);
}
else {
System.out.println("Your number cannot be represented as n^x");
}
}
Use a do-while for the outer loop and you won't need i--; at the end.

Can't figure out the error Luhn check

Its supose to tell me if a card is valid or invalid using luhn check
4388576018402626 invalid
4388576018410707 valid
but it keeps telling me that everything is invalid :/
Any tips on what to do, or where to look, would be amazing. I have been stuck for a few hours.
It would also help if people tell me any tips on how to find why a code is not working as intended.
im using eclipse and java
public class Task11 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a credit card number as a long integer: ");
long number = input.nextLong();
if (isValid(number)) {
System.out.println(number + " is valid");
} else {
System.out.println(number + " is invalid");
}
}
public static boolean isValid(long number) {
return (getSize(number) >= 13) && (getSize(number) <= 16)
&& (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37))
&& (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 == 0;
}
public static int sumOfDoubleEvenPlace(long number) {
int result = 0;
long start = 0;
String digits = Long.toString(number);
if ((digits.length() % 2) == 0) {
start = digits.length() - 1;
} else {
start = digits.length() - 2;
}
while (start != 0) {
result += (int) ((((start % 10) * 2) % 10) + (((start % 10) * 2) / 2));
start = start / 100;
}
return result;
}
public static int getDigit(int number) {
return number % 10 + (number / 10);
}
public static int sumOfOddPlace(long number) {
int result = 0;
while (number != 0) {
result += (int) (number % 10);
number = number / 100;
}
return result;
}
public static boolean prefixMatched(long number, int d) {
return getPrefix(number, getSize(d)) == d;
}
public static int getSize(long d) {
int numberOfDigits = 0;
String sizeString = Long.toString(d);
numberOfDigits = sizeString.length();
return numberOfDigits;
}
public static long getPrefix(long number, int k) {
String size = Long.toString(number);
if (size.length() <= k) {
return number;
} else {
return Long.parseLong(size.substring(0, k));
}
}
}
You should modiffy your isValid() method to write down when it doesn't work, like this:
public static boolean isValid(long number) {
System.err.println();
if(getSize(number) < 13){
System.out.println("Err: Number "+number+" is too short");
return false;
} else if (getSize(number) > 16){
public static boolean isValid(long number) {
System.err.println();
if(getSize(number) < 13){
System.out.println("Err: Number "+number+" is too short");
return false;
} else if (getSize(number) > 16){
System.out.println("Err: Number "+number+" is too long");
return false;
} else if (! (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37)) ){
System.out.println("Err: Number "+number+" prefix doesn't match");
return false;
} else if( (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 != 0){
System.out.println("Err: Number "+number+" doesn't have sum of odd and evens % 10. ");
return false;
}
return true;
}
My guess for your problem is on the getPrefix() method, you should add some logs here too.
EDIT: so, got more time to help you (don't know if it's still necessary but anyway). Also, I corrected the method I wrote, there were some errors (like, the opposite of getSize(number) >= 13 is getSize(number) < 13)...
First it will be faster to test with a set of data instead of entering the values each time yourself (add the values you want to check):
public static void main(String[] args) {
long[] luhnCheckSet = {
0, // too short
1111111111111111111L, // too long (19)
222222222222222l // prefix doesn't match
4388576018402626l, // should work ?
};
//System.out.print("Enter a credit card number as a long integer: ");
//long number = input.nextLong();
for(long number : luhnCheckSet){
System.out.println("Checking number: "+number);
if (isValid(number)) {
System.out.println(number + " is valid");
} else {
System.out.println(number + " is invalid");
}
System.out.println("-");
}
}
I don't know the details of this, but I think you should work with String all along, and parse to long only if needed (if number is more than 19 characters, it might not parse it long).
Still, going with longs.
I detailed your getPrefix() with more logs AND put the d in parameter in long (it's good habit to be carefull what primitive types you compare):
public static boolean prefixMatched(long number, long d) {
int prefixSize = getSize(d);
long numberPrefix = getPrefix(number, prefixSize);
System.out.println("Testing prefix of size "+prefixSize+" from number: "+number+". Prefix is: "+numberPrefix+", should be:"+d+", are they equals ? "+(numberPrefix == d));
return numberPrefix == d;
}
Still don't know what's wrong with this code, but it looks like it comes from the last test:
I didn't do it but you should make one method from sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 and log both numbers and the sum (like i did in prefixMatched() ). Add logs in both method to be sure it gets the result you want/ works like it should.
Have you used a debugger ? if you can, do it, it can be faster than adding a lot of logs !
Good luck
EDIT:
Here are the working functions and below I provided a shorter, more efficient solution too:
public class CreditCardValidation {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = 0;
long array[] = new long [16];
do
{
count = 0;
array = new long [16];
System.out.print("Enter your Credit Card Number : ");
long number = in.nextLong();
for (int i = 0; number != 0; i++) {
array[i] = number % 10;
number = number / 10;
count++;
}
}
while(count < 13);
if ((array[count - 1] == 4) || (array[count - 1] == 5) || (array[count- 1] == 3 && array[count - 2] == 7)){
if (isValid(array) == true) {
System.out.println("\n The Credit Card Number is Valid. ");
} else {
System.out.println("\n The Credit Card Number is Invalid. ");
}
} else{
System.out.println("\n The Credit Card Number is Invalid. ");
}
in.close();
}
public static boolean isValid(long[] array) {
int total = sumOfDoubleEvenPlace(array) + sumOfOddPlace(array);
if ((total % 10 == 0)) {
for (int i=0; i< array.length; i++){
System.out.println(array[i]);}
return true;
} else {
for (int i=0; i< array.length; i++){
System.out.println(array[i]);}
return false;
}
}
public static int getDigit(int number) {
if (number <= 9) {
return number;
} else {
int firstDigit = number % 10;
int secondDigit = (int) (number / 10);
return firstDigit + secondDigit;
}
}
public static int sumOfOddPlace(long[] array) {
int result = 0;
for (int i=0; i< array.length; i++)
{
while (array[i] > 0) {
result += (int) (array[i] % 10);
array[i] = array[i] / 100;
}
}
System.out.println("\n The sum of odd place is " + result);
return result;
}
public static int sumOfDoubleEvenPlace(long[] array) {
int result = 0;
long temp = 0;
for (int i=0; i< array.length; i++){
while (array[i] > 0) {
temp = array[i] % 100;
result += getDigit((int) (temp / 10) * 2);
array[i] = array[i] / 100;
}
}
System.out.println("\n The sum of double even place is " + result);
return result;
}
}
I also found a solution with less lines of logic. I know you're probably searching for an OO approach with functions, building from this could be of some help.
Similar question regarding error in Luhn algorithm logic:
Check Credit Card Validity using Luhn Algorithm
Link to shorter solution:
https://code.google.com/p/gnuc-credit-card-checker/source/browse/trunk/CCCheckerPro/src/com/gnuc/java/ccc/Luhn.java
And here I tested the solution with real CC numbers:
public class CreditCardValidation{
public static boolean Check(String ccNumber)
{
int sum = 0;
boolean alternate = false;
for (int i = ccNumber.length() - 1; i >= 0; i--)
{
int n = Integer.parseInt(ccNumber.substring(i, i + 1));
if (alternate)
{
n *= 2;
if (n > 9)
{
n = (n % 10) + 1;
}
}
sum += n;
alternate = !alternate;
}
return (sum % 10 == 0);
}
public static void main(String[] args){
//String num = "REPLACE WITH VALID NUMBER"; //Valid
String num = REPLACE WITH INVALID NUMBER; //Invalid
num = num.trim();
if(Check(num)){
System.out.println("Valid");
}
else
System.out.println("Invalid");
//Check();
}
}

Consecutive factor test

A positive number n is consecutive-factored if and only if it has factors, i and j where i > 1, j > 1 and j = i +1. I need a function that returns 1 if its argument is consecutive-factored, otherwise it returns 0.For example, 24=2*3*4 and 3 = 2+1 so it has the function has to return 1 in this case.
I have tried this:
public class ConsecutiveFactor {
public static void main(String[] args) {
// TODO code application logic here
Scanner myscan = new Scanner(System.in);
System.out.print("Please enter a number: ");
int num = myscan.nextInt();
int res = isConsecutiveFactored(num);
System.out.println("Result: " + res);
}
static int isConsecutiveFactored(int number) {
ArrayList al = new ArrayList();
for (int i = 2; i <= number; i++) {
int j = 0;
int temp;
temp = number %i;
if (temp != 0) {
continue;
}
else {
al.add(i);
number = number / i;
j++;
}
}
System.out.println("Factors are: " + al);
int LengthOfList = al.size();
if (LengthOfList >= 2) {
int a =al(0);
int b = al(1);
if ((a + 1) == b) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
}
Can anyone help me with this problem?
First check if its even, then try trial division
if(n%2!=0) return 0;
for(i=2;i<sqrt(n);++i) {
int div=i*(i+1);
if( n % div ==0) { return 1; }
}
return 0;
very inefficient, but fine for small numbers. Beyond that try a factorisation algorithm from http://en.wikipedia.org/wiki/Prime_factorization.
I have solved my problem with the above code. Following is the code.
public class ConsecutiveFactor {
public static void main(String[] args) {
// TODO code application logic here
Scanner myscan = new Scanner(System.in);
System.out.print("Please enter a number: ");
int num = myscan.nextInt();
int res = isConsecutiveFactored(num);
System.out.println("Result: " + res);
}
static int isConsecutiveFactored(int number) {
ArrayList al = new ArrayList();
for (int i = 2; i <= number; i++) {
int j = 0;
int temp;
temp = number % i;
if (temp != 0) {
continue;
}
else {
al.add(i);
number = number / i;
j++;
}
}
Object ia[] = al.toArray();
System.out.println("Factors are: " + al);
int LengthOfList = al.size();
if (LengthOfList >= 2) {
int a = ((Integer) ia[0]).intValue();
int b = ((Integer) ia[1]).intValue();
if ((a + 1) == b) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
}

Largest prime factor program takes aaaages - Java

So this is problem 3 from project Euler. For those who don't know, I have to find out the largest prime factor of 600851475143. I have the below code:
import java.lang.Math;
// 600851475143
public class LargestPrimeFactor {
public static void main(String[] stuff) {
long num = getLong("What number do you want to analyse? ");
long[] primes = primeGenerator(num);
long result = 0;
for(int i = 0; i < primes.length; i++) {
boolean modulo2 = num % primes[i] == 0;
if(modulo2) {
result = primes[i];
}
}
System.out.println(result);
}
public static long[] primeGenerator(long limit) {
int aindex = 0;
long[] ps = new long[primeCount(limit)];
for(long i = 2; i < limit + 1; i++) {
if(primeCheck(i)) {
ps[aindex] = i;
aindex++;
}
}
return ps;
}
public static boolean primeCheck(long num) {
boolean r = false;
if(num == 2 || num == 3) {
return true;
}
else if(num == 1) {
return false;
}
for(long i = 2; i < Math.sqrt(num); i++) {
boolean modulo = num % i == 0;
if(modulo) {
r = false;
break;
}
else if(Math.sqrt(num) < i + 1 && !modulo) {
r = true;
break;
}
}
return r;
}
public static int primeCount(long limit) {
int count = 0;
if(limit == 1 || limit == 2) {
return 0;
}
for(long i = 2; i <= limit; i++) {
if(primeCheck(i)) {
count++;
}
}
return count;
}
public static long getLong(String prompt) {
System.out.print(prompt + " ");
long mrlong = input.nextLong();
input.nextLine();
return mrlong;
}
}
But when I test the program with something (a lot) smaller than 600851475143, like 100000000, then the program takes its time - in fact, 100000000 has taken 20 minutes so far and is still going. I've obviously got the wrong approach here (and yes, the program does work, I tried it out with smaller numbers). Can anyone suggest a less exhaustive way?
public static void main(String[] args) {
long number = 600851475143L;
long highestPrime = -1;
for (long i = 2; i <= number; ++i) {
if (number % i == 0) {
highestPrime = i;
number /= i;
--i;
}
}
System.out.println(highestPrime);
}
public class LargestPrimeFactor {
public static boolean isPrime(long num){
int count = 0;
for(long i = 1; i<=num/2 ; i++){
if(num % i==0){
count++;
}
}
if(count==1){
return true;
}
return false;
}
public static String largestPrimeFactor(long num){
String factor = "none";
for(long i = 2; i<= num/2 ; i++){
if(num % i==0 && isPrime(i)){
factor = Long.toString(i);
}
}
return factor;
}
public static void main(String[] args) {
System.out.println(largestPrimeFactor(13195));
}
}
I have done several dozen of the challenges on Project Euler. Some of the questions can be solved with brute force (they recommend not to do this) but others require "out of the box" thinking. You cannot solve that by problem with brute force.
There is lots of help on the web to lead you in the right direction, for example:
http://thetaoishere.blogspot.com.au/2008/05/largest-prime-factor-of-number.html
The number of prime factors a number can have is always less than sqrt of that number so that there is no need to iterate through the number n to find its largest prime factor.
See this code.
public class LargestPrimeFactor {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
long num=sc.nextLong();
if(num>0 && num<=2)
{
System.out.println("largest prime is:-" + num);
System.exit(0);
}
int i=((Double)Math.sqrt(num)).intValue();
int j=3;
int x=0;
//used for looping through the j value which can also be a prime. for e.g in case of 100 we might get 9 as a divisor. we need to make sure divisor is also a prime number.
int z=0;
//same function as j but for divisor
int y=3;
int max=2;
//divisor is divisible
boolean flag=false;
//we found prime factors
boolean found=false;
while(x<=i)
{
y=3;
flag=false;
if(num % j ==0)
{
if(j>max)
{
for(z=0;z<Math.sqrt(j);z++)
{
if(j!=y && j % y==0)
{
flag=true;
}
y+=2;
}
if(!flag)
{
found=true;
max=j;
}
}
}
j+=2;
x++;
}
if(found){
System.out.println("The maximum prime is :- " + max);
}
else
{
System.out.println("The maximum prime is :- " + num);
}
}
}
change
for(long i = 2; i <= limit; i++)
to
// add the one for rounding errors in the sqrt function
new_limit = sqrt(limit) + 1;
// all even numbers are not prime
for(long i = 3; i <= new_limit; i+=2)
{
...
}
Factoring 1,000,000 for example instead of iterating 1,000,000 times
the thing only needs to do around 500 iterations.

Categories