I need some help optimizing this program. I am trying to figure out the largest prime factor for input. However, it occasionally has timeout issues, so I am interested in figuring out how to optimize it.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class PFactor() {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
long n = in.nextLong();
System.out.println(pMod(n));
}
}
public static int pMod(long d) {
long maxVal = 0;
for (long i = 2; i <= d; i++) {
if (d % i == 0) {
boolean prime = pCount(i);
if (prime == true) {
max = i;
}
} else {
max = max;
}
}
return (int)max;
}
public static boolean pCount(long inLong) {
int count = 0;
for (long s = 1; s <= inLong; s++) {
if (inLong % s == 0) {
count++;
}
}
if (count == 2) {
return true;
} else {
return false;
}
}
}
Do you know how to optimize this code so that it does not have as many timeouts? I need this ready soon for something at work, so I decided to reach out to see if I could get some help, as I can't seem to figure it out myself where it needs further optimization.
I actuallly found a solution guys after a bit of tinkering with it! you were all very helpful though! Thanks for helping!
Related
I'm trying to create a code where the user inputs a number, and the program returns whether the number is prime or not. This is my first code in Java, so I'm still learning! The code compiles but when I run it, it doesn't have an option to input.
import java.util.Scanner;
public class Prime {
public void main(String[] args)
{
Scanner reader = new Scanner(System.in);
int number = reader.nextInt();
if (isPrime(number) == true)
{
System.out.println(number+"is a prime number");
}
else
{
System.out.print(number+"is not a prime number");
}
}
public boolean isPrime(int number)
{
int counter = 0;
boolean result = true;
for (int n = 2; n <= 9; n++) {
if (number % n == 0 && n != number) {
counter = 1;
} else {
counter = 2;
}
if (counter == 1){
result = true;
}
else result = false;
}
return (result);
}
}
The issue here is regarding the main method which is missing the static keyword, so there is no app entry without that.
Please change the main method from
public void main(String[] args)
To
public static void main(String[] args)
Also, add static to the isPrime method in order to everything work.
This problem arised because of no Entry point was found by the java compiler
Code Snippet
Run Code Here
import java.util.Scanner;
public class Prime {
public static void main(String[] args)
{
Scanner reader = new Scanner(System.in);
int number = reader.nextInt();
if (isPrime(number) == true)
{
System.out.println(number+"is a prime number");
}
else
{
System.out.print(number+"is not a prime number");
}
}
static public boolean isPrime(int number)
{
int counter = 0;
boolean result = true;
for (int n = 2; n <= 9; n++) {
if (number % n == 0 && n != number) {
counter = 1;
} else {
counter = 2;
}
if (counter == 1){
result = true;
}
else result = false;
}
return (result);
}
}
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
long n,a;
boolean b;
try{
Scanner sc = new Scanner(System.in);
n = sc.nextLong();
for ( long i = 0; i<n; i++){
a = sc.nextLong();
for ( long j = (a+1); j<1000000000; j++){
b = isPalindrome(j);
if ( b == true){
System.out.println(j);
break;
}
}
}
} catch ( Exception e){
return;
}
}
public static boolean isPalindrome(long n){
String intStr = String.valueOf(n);
return intStr.equals(new StringBuilder(intStr).reverse().toString());
}
}
Whats wrong with my Palindrome code?
In SPOJ, the first two test cases are compiling but for the next one and onwards it's showing the wrong answer.
First test case:
2
808
2133
output:
818
2222
The reason is that neither int neither long are big enough to store a given positive integer K of not more than 1000000 digits - 1000000 digits is well 101000000, while Long.MAX_VALUE is only 263-1.
Thus you have to use BigInteger.
The following code seems to work (no more NZEC), but it ends up with time limit exceeded.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
class Main {
public static void main(String[] args) throws java.lang.Exception {
int n = Integer.parseInt(readLine());
for (int i = 0; i < n; i++) {
BigInteger a = new BigInteger(readLine()).add(BigInteger.ONE);
if (a.signum() == -1) {
a = BigInteger.ZERO;
}
while (a.toString().length() <= 1000000) {
if (isPalindrome(a.toString())) {
System.out.println(a);
break;
}
a = a.add(BigInteger.ONE);
}
}
}
private static boolean isPalindrome(String intStr) {
int l = intStr.length();
for (int i=0, j=l-1; i < l/2+1; i++, j--) {
if (intStr.charAt(i) != intStr.charAt(j)) {
return false;
}
}
return true;
}
private static String readLine() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
return br.readLine();
}
}
I'm trying to solve this question:
https://www.hackerrank.com/contests/projecteuler/challenges/euler003/submissions/code/2977447
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of a given number N?
Input Format
First line contains T, the number of test cases. This is followed by T lines each containing an integer N.
Output Format
For each test case, display the largest prime factor of N.
Constraints
1≤T≤10
10≤N≤1012
and my code below gets a timeout error for the fifth test (which we don't know about the actual content). any thought why did it fail the test? thanks
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
/* Author: Derek Zhu
* 1and1get2#gmail.com
* https://www.hackerrank.com/contests/projecteuler/challenges/euler003
* */
// The part of the program involving reading from STDIN and writing to STDOUT has been provided by us.
public class Solution {
public static boolean D = true;
static BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
static StringBuilder out = new StringBuilder();
public static void main(String[] args) throws NumberFormatException,
IOException {
int numOfCases = Integer.parseInt(in.readLine());
for (int i = 0; i < numOfCases; i++){
calculateCase(Long.parseLong(in.readLine()));
}
}
private static void calculateCase(Long input) throws IOException{
if (D) System.out.println("Processing: " + input);
long largestPF = prime(input);
if (D) System.out.print("Final calculate: ");
System.out.println(largestPF);
}
private static long prime(long n){
long i = 2;
while ( n % i != 0 && i < n){
i ++;
}
if (D) System.out.println("found i: " + i);
if (i < n){
return prime(n/i);
} else {
return n;
}
}
public static int primeFactors(BigInteger number) {
BigInteger copyOfInput = number;
int lastFactor = 0;
for (int i = 2;
BigInteger.valueOf(i)
.compareTo(copyOfInput) <= 0; i++) {
if (copyOfInput.mod(BigInteger.valueOf(i))
.compareTo(BigInteger.ZERO) == 0)
{
lastFactor = i;
copyOfInput = copyOfInput
.divide(BigInteger.valueOf(i));
i--;
}
}
return lastFactor;
}
}
Thanks #ajb
as it turns out, taking another method would be much efficient.
private static long method2(long NUMBER){
long result = 0;
for(int i = 2; i < NUMBER; i++) {
if(NUMBER % i == 0 && isPrime(NUMBER / i)) {
result = NUMBER / i;
break;
}
}
return result;
}
private static boolean isPrime(long l) {
for(long num = 2, max = l / 2 ; num < max; num++) {
if(l % num == 0) {
return false;
}
}
return true;
}
complete code with comparison of time can be found here:
https://github.com/1and1get2/hackerrank/blob/master/Contests/ProjectEuler%2B/003_LargestPrimeFactor/src/Solution.java
if (NUMBER<2){
return -1;
}
int result = 0;
for (int i =2; NUMBER>i; i++ ){
if (NUMBER%i==0){
result = NUMBER / i;
if (result/1==result && result/result==1 && result%2!=0 && result%3!=0 && result%5!=0 && result%7!=0){
break;
}
}
}
return result;
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
int count,k=0,n=0;
long arr[]=new long[1000000];
long arr1[]=new long[1000000];
long arr2[]=new long[10000000];
for(int a0 = 0; a0 < t; a0++){
arr[a0] = in.nextLong();
}
for(int i=0;i<t;i++)
{
for(int j=2;j<=arr[i];j++)
{
if(arr[i]%j==0)
{
arr1[k]=j;
k++;
}
}
for(int l=0;l<k;l++)
{
count=0;
for(int m=1;m<=arr1[l];m++)
{
if(arr1[l]%m==0)
{
count++;
}
}
if(count==2)
{
arr2[n]=arr1[l];
n++;
}
}
Arrays.sort(arr2);
System.out.println(arr2[arr2.length-1]);
}
}
}
This question already has answers here:
What is a StackOverflowError?
(16 answers)
Closed 7 years ago.
I am trying to solve a problem which asks to find the smallest prime palindrome, which comes after a given number which means that if the input is 24, the output would be 101 as it is the smallest number after 24 which is both prime and a palindrome.
Now my code works perfectly for small values but the moment I plug in something like 543212 as input, I end up with a StackOverFlowError on line 20, followed by multiple instances of StackOverFlowErrors on line 24. Here is my code :
package nisarg;
import java.util.Scanner;
public class Chef_prime_palindromes {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long num = input.nextLong();
isPalindrome(num + 1);
}
public static boolean isPrime(long num) {
long i;
for (i = 2; i < num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
public static void isPalindrome(long num) {
String word = Long.toString(num);
int i;
for (i = 0; i < word.length() / 2; i++) {
if (word.charAt(i) != word.charAt(word.length() - i - 1)) {
isPalindrome(num + 1);
}
}
if (i == word.length() / 2) {
if (isPrime(num)) {
System.out.println(num);
System.exit(0);
} else {
isPalindrome(num + 1);
}
}
}
}
All shown exiting solutions use recursion and have the problem that at some point they will reach the point where a StackOverflowException will occur.
A better solution which would also be parallelizable would be to change it into a loop.
It could be something like:
package nisarg;
import java.math.BigInteger;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;
public class Chef_prime_palindromes {
private static final CopyOnWriteArrayList<BigInteger> PRIMESCACHE
= new CopyOnWriteArrayList<>();
public static void main(String[] args) {
try (Scanner input = new Scanner(System.in)) {
BigInteger num = new BigInteger(input.nextLine());
initPrimes(num);
for (num = num.add(BigInteger.ONE);
!isPrimePalindrome(num);
num = num.add(BigInteger.ONE));
System.out.println(num.toString());
}
}
private static void initPrimes(BigInteger upTo) {
BigInteger i;
for (i = new BigInteger("2"); i.compareTo(upTo) <= 0 ; i = i.add(BigInteger.ONE)) {
isPrime(i);
}
}
public static boolean isPrimePalindrome(BigInteger num) {
return isPrime(num) && isPalindrome(num);
}
// could be optimized
public static boolean isPrime(BigInteger num) {
for (int idx = PRIMESCACHE.size() - 1; idx >= 0; --idx) {
if (num.mod(PRIMESCACHE.get(idx)).compareTo(BigInteger.ZERO) == 0) {
return false;
}
}
if (!PRIMESCACHE.contains(num)) {
PRIMESCACHE.add(num);
}
return true;
}
public static boolean isPalindrome(BigInteger num) {
String word = num.toString();
int i;
for (i = 0; i < word.length() / 2; i++) {
if (word.charAt(i) != word.charAt(word.length() - i - 1)) {
return false;
}
}
return true;
}
}
A new String object is created in each recursive call and placed onto stack (the place where all variables created in methods are stored until you leave the method), which for a deep enough recursion makes JVM reach the end of allocated stack space.
I changed the locality of the String object by placing it into a separate method, thus reducing its locality and bounding its creation and destruction (freeing of stack space) to one recursive call.
package com.company;
import java.util.Scanner;
public class Chef_prime_palindromes {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long num = input.nextLong();
isPalindrom(num + 1);
}
public static boolean isPrime(long num) {
long i;
for (i = 2; i < num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
private static void isPalindrom(long num) {
for (; ; ) {
if (isPalindrome(num)) {
if (isPrime(num)) {
System.out.println(num);
System.exit(0);
} else {
num++;
}
} else {
num++;
}
}
}
public static boolean isPalindrome(long num) {
String string = String.valueOf(num);
return string.equals(new StringBuilder(string).reverse().toString());
}
}
First thing you should be aware of is the fact that your resources are limited. Even if your implementation was precise and all recursive calls were correct, you may still get the error. The error indicates your JVM stack ran out of space. Try to increase the size of your JVM stack ( see here for details).
Another important thing is to look for the distribution of prime and palindrome numbers. Your code runs by testing every num+1 against palindrome property. This is incorrect. You test for palindrome only when the number is prime. This will make the computation much much easier (and reduce recursive calls). I have edited your code accordingly and got the closest palindrome number after 543212 (1003001) . Here it is:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long num = input.nextLong();
//isPalindrome(num+1);
nextPrimePalindrome(num+1);
}
public static void nextPrimePalindrome(long num)
{
boolean flag=true;
while(flag)
{
if(isPrime(num))
if(isPalindrome(num))
{
System.out.println(num);
flag=false;
}
num++;
}
}
public static boolean isPrime(long num){
long i;
for(i=2;i<num;i++){
if(num%i == 0){
return false;
}
}
return true;
}
public static boolean isPalindrome(long num)
{
String word=Long.toString(num);
for(int i=0;i<word.length()/2;i++)
if(word.charAt(i)!=word.charAt(word.length()-i-1))
return false;
return true;
}
}
I'm supposed to write a code which checks if a given number belongs to the Fibonacci sequence. After a few hours of hard work this is what i came up with:
public class TP2 {
/**
* #param args
*/
public static boolean ehFibonacci(int n) {
int fib1 = 0;
int fib2 = 1;
do {
int saveFib1 = fib1;
fib1 = fib2;
fib2 = saveFib1 + fib2;
}
while (fib2 <= n);
if (fib2 == n)
return true;
else
return false;
}
public static void main(String[] args) {
int n = 8;
System.out.println(ehFibonacci(n));
}
}
I must be doing something wrong, because it always returns "false". Any tips on how to fix this?
You continue the loop while fib2 <= n, so when you are out of the loop, fib2 is always > n, and so it returns false.
/**
* #param args
*/
public static boolean ehFibonacci(int n) {
int fib1 = 0;
int fib2 = 1;
do {
int saveFib1 = fib1;
fib1 = fib2;
fib2 = saveFib1 + fib2;
}
while (fib2 < n);
if (fib2 == n)
return true;
else
return false;
}
public static void main(String[] args) {
int n = 5;
System.out.println(ehFibonacci(n));
}
This works. I am not sure about efficiency..but this is a foolproof program,
public class isANumberFibonacci {
public static int fibonacci(int seriesLength) {
if (seriesLength == 1 || seriesLength == 2) {
return 1;
} else {
return fibonacci(seriesLength - 1) + fibonacci(seriesLength - 2);
}
}
public static void main(String args[]) {
int number = 4101;
int i = 1;
while (i > 0) {
int fibnumber = fibonacci(i);
if (fibnumber != number) {
if (fibnumber > number) {
System.out.println("Not fib");
break;
} else {
i++;
}
} else {
System.out.println("The number is fibonacci");
break;
}
}
}
}
you can also use perfect square to check whether your number is Fibonacci or not. you can find the code and some explanation at geeksforgeeks.
you can also see stackexchange for the math behind it.
I'm a beginner but this code runs perfectly fine without any issues. Checked with test cases hopefully it'll solve your query.
public static boolean checkMember(int n) {
int x = 0;
int y = 1;
int sum = 0;
boolean isTrue = true;
for (int i = 1; i <= n; i++) {
x = y;
y = sum;
sum = x + y;
if (sum == n) {
isTrue=true;
break;
} else {
isTrue=false;
}
}
return isTrue;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.print(checkMember(n));
}