largest palindrome product in java - java

I have written a code for the fourth question of Euler Project.
The question is:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
Here is my code:
public class LargestPalindromeProduct {
private static int product;//integer palindrome number
private static String palindrome;//string palindrome
private static int largestPalindrome(){
for(int i = 100; i<=999; i++){
for(int k = 100; k<=999; k++){
product = i*k;
palindrome = Integer.toString(product);
for(int j = 0; j<= palindrome.length()-1; j++){
if(palindrome.charAt(j) == palindrome.length() - 1 - j){
return product;
}
}
}
}
return product;
}
public static void main(String[] args) {
int largestPalindrome = largestPalindrome();
System.out.println(largestPalindrome);
}
}
This code gives 998001 as the output.
Can you help me to find where the problem is?

You are returning the moment you get 1 match instead of continuing checking until ALL match.
if(palindrome.charAt(j) == palindrome.length() - 1 - j){
return product;
}
As #soong has pointed out the actual comparison is doing charAt() vs length
Better check how you are doing your comparisons.

Close, but for your pattern to work, you must try all combinations and return the largest one. Also, don't short circuit the method on a mis-match, just break out of the loop.
Try a couple changes similar to what i've added...
public class LargestPalindromeProduct {
private static int largestPalindrome() {
int max = 0;
for(int i = 100; i<=999; i++) {
for(int k = 100; k<=999; k++) {
int product = i*k;
if (product <= max) {
continue;
}
String palindrome = Integer.toString(product);
boolean good = true;
for(int j = 0; j<= palindrome.length()-1; j++) {
if(palindrome.charAt(j) != palindrome.charAt(palindrome.length() - 1 - j)) {
good = false;
break;
}
}
if (good)
max = product;
}
}
}
return max;
}
public static void main(String[] args) {
int largestPalindrome = largestPalindrome();
System.out.println(largestPalindrome);
}

What I did was start at 999999 and count downward, then test if the number was a palindrome, and if the number was a palindrome, test if it had 2 integer factors.
I'm not going to give you all the code, but here's one way to check for a palindrome that you might not have thought of.
public static boolean isPalindrome(int palindrome) {
StringBuilder builder = new StringBuilder(Integer.toString(palindrome));
builder.reverse();
return Integer.valueOf(builder.toString()) == palindrome;
}

Related

How to find prime numbers in an array of random numbers?

I have a problem with finding prime numbers in an array of randomly generated integers.
I tried using the 'for' loop to go through every element in my array to check whether it's a prime number or not. Although it prints some ints from the array, they are not prime numbers.
public static void main(String[] args) {
defineTable();
printPrimeNumbers();
}
private static int[] tab;
private static int[] defineTable(){
tab = new int[100];
for (int i = 0; i < tab.length; i++){
tab[i] = randomFill();
}
return tab;
}
private static int randomFill (){
Random rand = new Random();
int randomInt = rand.nextInt();
return randomInt;
}
private static void printPrimeNumbers(){
boolean isPrime = true;
for (int i = 0; i < tab.length; i++){
int num = tab[i];
for (int j = 2; j < num; j++){
if (num % j == 0){
isPrime = false;
break;
}
}
if(isPrime){
System.out.println(num + " jest liczbą pierwszą.");
}
}
}
Any solutions to this problem? I started learning Java 4 days ago on my own. So far everything goes well, I understand most of the basics. But this problem seems too complex for me, a beginner.
Edit: I translated most of the code's variables to English from Polish, as my native language is Polish, hope it's understandable.
You're only setting isPrime to true at the beginning of printPrimeNumbers. Once it finds the first composite number, it becomes false, and you never reset it to true again to test the next number.
when writing Java code, try to split the task into functions(should serve a single purpose only). For your code extract the logic of determining Prime into a separate method and pass the random number to check whether it's prime or not, if yes then print otherwise don't print or do nothing.
Please check the below code snippet
A simpler and efficient way to find the prime number
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
private static void printPrimeNumbers(){
for (int i = 0; i < tab.length; i++){
if(isPrime(tab[i])){
System.out.println(tab[i] + " jest liczbą pierwszą.");
}
}

PalindromeCheck efficiency for Int in Java

I have constructed two ways to check palindrome of a number. Which one is more efficient? By efficiency, I mean in terms of execution time and memory allocations.
First, I convert an Integer to string and check if it is a palindrome. The example of code is as follow.
public class Palindrome{
/*
Function palindromeCheck
Return type boolean
Parameters characterArray
Checks character array for palindrome
*/
public static boolean palindromeCheck(char[] palinCheck){
boolean palindrome = true;
int firstLen = 0;
int secondLen = palinCheck.length - 1;
while(palindrome == true && firstLen < secondLen ){
if(palinCheck[firstLen] != palinCheck[secondLen]){
palindrome = false;
}
else{
firstLen++;
secondLen--;
}
} //end of while
return palindrome;
}
/*Main Function
Calls palinDromeCheck function
Prints results
*/
public static void main(String[] args){
int palinCheck = 1221;
String dipendra = Integer.toString(palinCheck);
char[] dipendraChar = dipendra.toCharArray();
System.out.println(palindromeCheck(dipendraChar));
}
}
The second method is without converting it to string.
public class PalindromeNumber{
/*
Function: PalindromeCheck
parameters integer
ReturnType: boolean
Takes integer, checks if it is palindrome and returns accordingly
*/
public static boolean palindromeCheck(int number){
int firstNumber = number;
int secondNumber = 0;
while(number >= 1){
secondNumber = secondNumber* 10 + (number%10);
number = number/10;
}
return (firstNumber==secondNumber) ? true:false;
}
public static void main(String[] args){
System.out.println(palindromeCheck(111));
}
}
I bet the second algorithm would be faster, and obviously more space efficient. If you assume n be the number of digits of the input number, in the first algorithm:
Integer.toString requires n steps to convert it to String.
palindromeCheck requires n / 2 comparisons to check whether it's a palindrome.
But, the second algorithm would require n steps to compute the reverse number (involving only integer operations) and only 1 comparison to check.
Let's try.
On the following example (with one specific number, on my specific machine...) :
580 ms - Your first solution
323 ms - Your second solution
1045 ms - BrentR's solution
Note I modified the code a bit (but not the logic). You should also take care of spaces and indentation.
public class Palindrome {
public static boolean isPalindrome1(int n) {
char a[] = Integer.toString(n).toCharArray();
int i = 0;
int j = a.length - 1;
while (i < j) {
if (a[i++] != a[j--]) return false;
}
return true;
}
public static boolean isPalindrome2(int n) {
int p = n, q = 0;
while (n > 0) {
q = 10 * q + n % 10;
n /= 10;
}
return p == q;
}
public static boolean isPalindrome3(int n) {
String s = Integer.toString(n);
return s.equalsIgnoreCase(new StringBuilder(s).reverse().toString());
}
public static void main(String[] args) {
final int m = 10000000;
long t1, t2;
boolean q;
t1 = System.currentTimeMillis();
for (int n = 0; n < m; n++) {
q = isPalindrome1(123454321);
}
t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
t1 = System.currentTimeMillis();
for (int n = 0; n < m; n++) {
q = isPalindrome2(123454321);
}
t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
t1 = System.currentTimeMillis();
for (int n = 0; n < m; n++) {
q = isPalindrome3(123454321);
}
t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
}
}
Why are you re-inventing the wheel?
java.lang.StringBuilder already provides a string reverse method
String string = Integer.toString(10101);
boolean palindrome = string.equalsIgnoreCase(new StringBuilder(string).reverse().toString());

Printing Prime Numbers to N value

This program is supposed to print all the prime numbers up to an int that you enter, for example:
Enter a Number:
20
2
3
5
7
11
13
17
19
I just cannot get my program to work, I really don't know what to do, so if someone could review it and try to fix it, that would be greatly appreciated, thanks.
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
number = n;
}
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
}
}
You're already there actually. You've just got a mistake in the program-flow.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i; //<-- this return will terminate nextPrim
}
}
Things to fix/improve:
nextPrim would need to return a value within every possible program-branch. This means: consider the case where nextPrim doesn't find any number in the given range and steps out of the loop. Now the program would be stuck without any return-value.
Instead of returning the first prim-number found, you could print that found prim-number and keep the generator running. Nice, easy and solves the hassle with returning anything, since you now can simply declare nextPrim as void. I'd recommend renaming it to printPrims or something like that to make this change clear.
Passing number: You can save a bit of effort by only passing number once to the prim-generator. The simplest solution would be to pass it to nextPrim/printPrims. Now you can remove the instance-variable number and the constructor, which solves the issue with th e signature of the constructor.
1 is not a prim-number to be pedantic. So let's be pedantic and start the outer loop in printPrims with 2, so that 2 will be the first number that is checked for being a prim.
So let's put this into code:
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
matt.printPrims(number);
}
public void printPrime(int number) {
for (int i = 2; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
A few general hints:
Work through compiler errors. They tell you precisely where and what errors occur within your code.
Think about the flow of your program before even implementing it.
Break the task down into smaller tasks and implement these one after another. As an example: for this problem first print out all numbers in the range 2, number. Afterwards go a step further and add functionality to filter out prim-numbers. Now you've got two components that you can easily test independent of each other.
You were nearly there but your nextPrimes function was terminating prematurely when you returned i, try something like this:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner k = new Scanner(System.in);
System.out.print("Enter an integer:");
int number = k.nextInt();
printPrimesUptoN(number);
}
public static void printPrimesUptoN(int n){
for(int i=2;i<n;i++){
boolean isPrime = true;
for(int j=2;j<i;j++){
if(i % j == 0){
isPrime = false;
break;
}
}
if(isPrime)
System.out.println(i);
}
}
}
Try it here!
There's a few issues with your code, maybe we can fix it together. First things first, you're missing a return statement in nextPrime and there's no empty default constructor PrimeGenerator() because you created a single-arg constructor. Try this:
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// you probably want to pass your maximum value to the constructor
PrimeGenerator matt = new PrimeGenerator(number);
// without a loop of some sort this will only print a single prime number, e.g.
// Enter a Number:
// 20
// 2
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
this.number = n;
}
// you're using the argument as upper boundary for your prime detection while not increasing your lower boundary
// also you're checking if i is a prime here which you always start at 1. this should always return the same value because once you find a prime number you return
// you should consider using an algorithm like Sieve of Eratosthenes (or advanced verions thereof) to determine if a given number is prime
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
// you need to return something at the end of this method or throw an exception
throw new IllegalStateException("no more prime numbers available!");
}
}
This is not a solution which will yield the results you're expecting but it will compile at least. From that point you can move forward and fix the algorithmic issues.
Your original error was in.
PrimeGenerator matt = new PrimeGenerator();
Error:
PrimeGenerator.java:7: error: constructor PrimeGenerator in class PrimeGenerator cannot be applied to given types;
PrimeGenerator matt = new PrimeGenerator();
^
required: int
found: no arguments
reason: actual and formal argument lists differ in length
1 error
Notice that you had a method with the same name as you class, but I don't think you were using it as a constructor and if you were it took an int which you didn't give it. Your method on line 13 was:
public PrimeGenerator(int n) {
number = n;
}
Try doing
new PrimeGenerator().nextPrime(number);
Instead
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
new PrimeGenerator().nextPrime(number);
}
public void nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
Optionally, to use your original constructor, you could separate this out.
import java.util.Scanner;
public class PrimeGenerator {
private int number;
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// Initialize with a number.
PrimeGenerator pg = new PrimeGenerator(number);
pg.printPrimes();
}
// This is the constructer you were misusing.
public PrimeGenerator(int n) {
number = n;
}
public void printPrimes() {
// Actually use your private number variable.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
There are several issues:
Are you using an IDE? If so, which is it, else Why not?. If you consider yourself a beginner, be advised to used one, like Eclipse IDE or NetBeans IDE.
Regarding to your algorithm, at first glance, there is a compilation and a logic problems.
Compilation problem is when the execution of your class not work. In this case the method nextPrime(int number) MUST return an int. Although you put return clause, the method is not returning any value when prime is false. You could easily spot this problem with an IDE.
Another compilation problem, the sentinel or variable i is INSIDE the for loop, and you are printing it's value OUTSIDE of it. Once again, the IDE would help you with this problem.
Logic problem is, you are returning a value if and only if the flag prime is true, so, when calling the method (supposing is working) you only obtain ONE value when you call System.out.println(matt.nextPrime(number));
The correct implementation would have these considerations:
The method doesn't return, i.e public void nextPrime(number) { ..., which means you don't need print in the main method, just call it.
The method actually prints the numbers.
In this way, you can check if i % j is different of zero, then you don't need to process more dividers, breaking the for loop.
Print it.
That's it.
public static void main(String [] args) {
.
.
.
PrimeGenerator matt = new PrimeGenerator();
matt.nextPrime(number);
}
public void printPrime(int number) {
boolean prime = true;
for (int i = 2; i <= number; i++) {
prime = true;
for (int j = 2; j < i; j++) {
if (i % j != 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(i);
}
}
}

Wrong Answer for Project Euler 50

I am attempting Problem 50 of project Euler.
The prime 41, can be written as the sum of six consecutive primes:
41 = 2 + 3 + 5 + 7 + 11 + 13 This is the longest sum of consecutive
primes that adds to a prime below one-hundred. The longest sum of
consecutive primes below one-thousand that adds to a prime, contains
21 terms, and is equal to 953. Which prime, below one-million, can be
written as the sum of the most consecutive primes?
Here is my code:
public class consPrime
{
static int checker(int ar[],int num,int index) //returns no.of consecutive
{ //primes for the given num
while(true)
{
int temp=num;
for(int i=index;i>=0;i--)
{
temp=temp-ar[i];
if(temp==0)
{
return (index-i+1);
}
}
index--;
if(index==0)
return 0;
}
}
public static void main(String args[])
{
int n=100000;
int ar[]=new int[n];
int total=0;int flag;
for(int i=2;i<1000000;i++) //Generates an array of primes below 1 million
{
flag=1;
for(int j=2;j<=Math.sqrt(i);j++)
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
{
ar[total]=i;
total++;
}
}
int m=0;
int Big=0;
for(int i=total;i>=0;i--) //Prints the current answer with no.of prime
{
m=checker(ar,ar[i],i-1);
if(Big<=m)
{Big=m;
System.out.println(ar[i]+" "+Big);
}
}
}
}
Basically it just creates a vector of all primes up to 1000000 and then loops through them finding the right answer. The answer is 997651 and the count is supposed to be 543 but my program outputs 990707 and 75175 respectively. What might be wrong?
Several big problems:
Some minor problem first: learn to proper indent your code, learn to use proper naming convention. In Java, variable names uses camelCasing while type name uses PascalCasing.
Lots of problems in your logics: you loop thru the prime number array, until you hit zero or until looped thru all numbers in the array. However, please be awared that, there is underflow/overflow for integer. It is possible that the "temp" keeps on deducts and become negative and become positive and so-on-and-so-forth and hit zero. However that's not the correct answer
You only tried to find the consecutive numbers that ends at index - 1. For example, to check for prime number at index 10, you are finding consecutive primes from index 9 backwards. However consecutive prime sum up to your target number rarely (in fact almost never, except for 5) contains the "previous" prime number. The whole logic is simply wrong.
Not to mention the incorrect parameters you passed for checker, which is mentioned by comment of user #pm-77-1
Here is another approach that takes 43 ms.
It is based on the following approach:
1) The primes <= 1000000 are generated using a sieve
2) It iterates in O(n2) through all numbers and it counts the consecutive primes. The first loop changes the first element of the sequence, the second one takes the elements starting from that position and adds them to a sum. If the sum is prime and it consists of the biggest number of primes, than it is kept in a variable.
import java.util.ArrayList;
import java.util.List;
public class P50 {
private final static int N = 1_000_000;
public static void main(String[] args) {
boolean primes[] = generatePrimes(N);
List<Integer> primeIntegers = new ArrayList<Integer>();
for (int i = 0; i < primes.length; i++) {
if (primes[i]) {
primeIntegers.add(i);
}
}
int count = 0;
int sum = 0;
int finalSum = 0;
int finalCount = 0;
int totalPrimes = primeIntegers.size();
for (int start = 0; start < totalPrimes; start++) {
sum = 0;
count = 0;
for (int current = start; current < totalPrimes; current++) {
int actual = primeIntegers.get(current);
sum += actual;
if ( sum >= N ) {
break;
}
if ( primes[sum] ) {
if ( count > finalCount ) {
finalCount = count;
finalSum = sum;
}
}
count++;
}
}
System.out.println(finalSum);
}
private static boolean[] generatePrimes(int n) {
boolean primes[] = new boolean[n];
for (int i = 0; i < n; i++) {
primes[i] = true;
}
primes[0] = false;
primes[1] = false;
// i = step
for (int i = 2; i * i < n; i++) {
if (primes[i]) {
for (int j = i * i; j < n; j += i) {
primes[j] = false;
}
}
}
return primes;
}
}

Java backtraking problem

Hey guys. I've been strugling with a backtraking problem for hours. Can anyone lend me a hand? Here is the problem:
n camels numbered from 1 to n are the arranged order. I want to rearrange so that each camel has a diferent camel in front.
This is what I have so far:
import java.util.*;
public class NCamile{
static int size;
static int count;
static char[] arrN= new char[100];
public static void main(String[] args){
System.out.print("Enter word: ");
String numar = getInt();
size = numar.length();
count=0;
for(int i=0; i < size ; i++){
arrN[i] = numar.charAt(i);
}
backtraking(size);
}
public static void backtraking(int newsize){
if (newsize == 1){
return;
}
for(int i=0 ; i < newsize; i++){
backtraking(newsize - 1);
if(newsize == 2 ){
display();
}
rotate(newsize);
}
}
public static void rotate(int newsize){
int position = size - newsize;
for(int i = position + 1; i < newsize; i++){
char gigi;
gigi = arrN[i - 1];
arrN[i - 1] = arrN [i];
arrN[i] = gigi;
}
}
public static void display(){
if (count < 9){
System.out.print(" ");
}
System.out.print(++count+ ")" + " ");
for(int i = 0 ; i < size ; i++)
System.out.print(arrN[i]);
System.out.print(" ");
if(count % 10 == 0){
System.out.println(" ");
}
}
public static String getInt(){
Scanner scan = new Scanner(System.in);
String s = scan.next();
return s;
}
}
With this, the algorithems show me every posible solution to rearrange a string, but it dosen't respect the last condition of the problem. I've tried ading this:
for(int j = 0 ; j < size ; j++){
if (array[j] !=[array[j + 1] )
display()
}
But after I added it I got about 10 times more displayed words then it should have shown me
Can anyone give me an idea on what should I do?
If you're only asked to insure that
i) a single new arrangement is produced, and
ii)that new arrangement must satisfy the condition that each camel follows a camel different from the one it followed in the original arrangement,
then you can easily satisfy this just by reversing the list of camels.
Surely this is not optimized solution, but for simply gettin result I would consider checking all of the permutations. Method producing every permutation wouldn't be hard to write (see e.g. String permutation) and checking if some camel has the same backtraced won't be any effort at all.
--- edit
So... Few things mended, few not:
I worked on String, not char array. Char array is completely misunderstand in this problem. It's better to use String object (cause in fact, String is char array) or int array (this have been hard to me, cause I haven't found any permutation method to be applied with such parameter). So the main method looks now:
private static String word;
public static void main(String[] args)
{
System.out.print("Enter word: ");
Scanner scan = new Scanner(System.in);
word = scan.next();
permutation(word);
}
I deleted your class variables (length, count, etc...) cause they are unnecessary right now. Writing out String is quite simple and if you would like to change output format - use String.length property instead.
Permutation method is copied from mentioned source, and little modified. It looks following:
public static void permutation(String s)
{
permutation("", s);
}
private static void permutation(String prefix, String s)
{
int n = s.length();
if (n == 0)
{
if (camelFit(prefix))
System.out.println(prefix);
}
else
{
for (int i = 0; i < n; i++)
permutation(prefix + s.charAt(i),
s.substring(0, i) + s.substring(i + 1, n));
}
}
if you would uncomment line checking if (camelFit (prefix)) it would display every permutation of input String. But! We would like to print only these camel chains, which fits problem conditions. How do we check if given chain is so? Simple method:
private static boolean camelFit(String prefix)
{
for (int i = 0; i < word.length() - 1; i++)
{
char camel = word.charAt(i);
char camelFollow = word.charAt(i+1);
for (int j = 0; j < prefix.length() - 1; j++)
{
if (prefix.charAt(j)==camel && prefix.charAt(j+1)==camelFollow)
{
return false;
}
}
}
return true;
}
Maybe not so simple, because we have to check every pair of input chain (every follower and followed) with every pair of output chain. If there isn't any match between any two pairs - given chain is fine.
Please notice, that this solution is absolutely non-optimized. Finding permutations is O(n!) complexity and checking pairs is O(n^2) complexity. Final complexity is O(n^2)*O(n!) so very, very high.

Categories

Resources