1

I need to write a program that finds all the palindrome perfect squares between two integers supplied as an input but that do not include the inputs supplied.

My program gets "killed" when you put in a large range of inputs i.e 10000 and 100000. How can i fix this please?

import static java.lang.Math.sqrt;
import java.util.Scanner;

public class PalinPerfect {

    public static void main(String[] args){

        Scanner user_input = new Scanner(System.in);
        String start_point;

        System.out.print("Enter start point N:\n");

        start_point = user_input.next();
        int start = Integer.parseInt(start_point);

        String finish_point;
        System.out.print("Enter ending point M:\n");

        finish_point = user_input.next();
        int finish = Integer.parseInt(finish_point);
        System.out.print( "The palindromic perfect squares are as follows:\n");

        for(int i=start; i <=finish; i++){

            int a,n1,n2=0;
            n1=i;

            for(a = 0; a <= i; a++) {

                if (a==Math.sqrt(n1)) {
                    n2=n1;
                }
            }
            int number = n2;
            int reversedNumber = 0;
            int temp=0;
            while(number > 0){
                temp = number % 10;
                number = number / 10;
                reversedNumber = reversedNumber * 10 + temp;
            }
                if(n1 == reversedNumber)
                    System.out.println(n1);

        }
    }
}
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
Steph
  • 13
  • 4
  • What is the purpose of your second `for` loop? – ajb Aug 26 '17 at 05:23
  • There is a loop to iterate between the start and end point. Then I have a loop to check for perfect squares and a loop to apply the reverse logic – Steph Aug 26 '17 at 05:25
  • works for me, the output: `10201 12321 14641 40804 44944 69696 94249` – Nir Alfasi Aug 26 '17 at 05:28
  • So if `n` is 99999, `Math.sqrt(n)` = 316.226, which isn't an integer Your plan is to loop through all the numbers from 1 to 99999 to see if any of them are equal to 316.226. You shouldn't need a loop to do that. Can you think of a better way to see if a number is an integer? – ajb Aug 26 '17 at 05:29
  • Also, your logic is faulty if the number isn't a perfect square. You keep going anyway to see if some previous number is a palindrome. – ajb Aug 26 '17 at 05:30
  • @alfasin The program doesn't use any memory. Also, when OP says the program gets "killed", this is most likely a homework assignment that's run on a test platform that only allows a certain amount of time. – ajb Aug 26 '17 at 05:32
  • Also works here, but you could implement it like `IntStream.rangeClosed(10000, 100000).filter(v -> { int x = (int) Math.sqrt(v); return new StringBuilder(String.valueOf(v)).reverse().toString().equals(String.valueOf(v)) && x * x == v; }).forEachOrdered(System.out::println);` – Elliott Frisch Aug 26 '17 at 05:34
  • @alfasin I doubt whether allocating more memory will make any difference. It seems to me that this program would be quite CPU-intensive, but memory would not be a bottleneck for its performance. – Dawood ibn Kareem Aug 26 '17 at 05:35
  • @ElliottFrisch what a wonderful insight to share with a beginner. – Dawood ibn Kareem Aug 26 '17 at 05:36
  • @DawoodibnKareem and ajb both of you are right, I wrote that comment before I start indenting and re-arranging the code so it was difficult to see what it does. After the edit it was clear that memory is indeed *not* the problem here, only CPU. – Nir Alfasi Aug 26 '17 at 05:50
  • Welcome to Stack Overflow! Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a [mcve]. Use the "edit" link to improve your *question* - do not add more information via comments. Thanks! – GhostCat Aug 26 '17 at 06:55
  • "Gets killed" is not a helpful problem description. I am sure you get some exception - that should be part of your question. – GhostCat Aug 26 '17 at 06:55
  • @GhostCat sorry for not giving a helpful description. The program ran on my machine but when it was uploaded on my schools online server to be marker the only feedback i got was "Program Killed". I will try and add more information next time. – Steph Aug 26 '17 at 07:21

2 Answers2

1

sqrt is an expensive operation and you're using it a lot. A different approach would be to do the exact opposite: calculating the square of a number and if it's in-range, see if it is a palindrome.

Naturally, this approach runs much faster:

public static void main(String[] args){

    Scanner user_input = new Scanner(System.in);
    String start_point;

    System.out.print("Enter start point N:\n");

    start_point = user_input.next();
    int start = Integer.parseInt(start_point);

    String finish_point;
    System.out.print("Enter ending point M:\n");

    finish_point = user_input.next();
    int finish = Integer.parseInt(finish_point);
    System.out.print( "The palindromic perfect squares are as follows:\n");

    for(int i = (int)Math.ceil(Math.sqrt(start)); i * i <= finish; i++){
        int number = i * i;
        int reversedNumber = 0;
        int temp = 0;
        while(number > 0){
            temp = number % 10;
            number = number / 10;
            reversedNumber = reversedNumber * 10 + temp;
        }
        if(i * i == reversedNumber)
            System.out.println(reversedNumber);
    }
}
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • Thank you so much for your help:) It really appreciate the help:) – Steph Aug 26 '17 at 05:52
  • Nit: I think this would return extra numbers before the start, e.g. if start is `8`, i would initially be `2`, and `2*2=4` is a palindrome, so that would be printed. – Andy Turner Aug 26 '17 at 06:48
  • @AndyTurner good catch of this edge-case, I've updated the answer and added `Math.ciel` around the call to `sqrt` – Nir Alfasi Aug 26 '17 at 06:54
  • @AndyTurner I just added an if loop to the code to only give answers between the start and finish point. Other than that the code works perfectly and i got 100 for the question for the assignment so Thank you alfasin:) – Steph Aug 26 '17 at 07:16
  • @Steph you mean that **I** got 100 for your assignment... :) – Nir Alfasi Aug 26 '17 at 13:26
  • @Steph Please work on learning correct terminology also. A loop is a piece of code that can potentially repeat itself multiple times. There's no such thing as an "if loop". – ajb Aug 27 '17 at 05:58
1

This is another simple and concise way to print palindrome square numbers.

Make sure you check isPalindrome operation first then only you check isPerfectSquare.

System.out.print("The palindromic perfect squares are as follows:\n");

        for (int i = start + 1; i < finish; i++) {
            if (isPalindrome(i) && isPerfectSquare(i) ) {
                System.out.println(i);
            }

        }

Define isPerfectSquare & isPalindrome methods as below

static boolean isPerfectSquare(int input) {
    int SquareRoot = (int) Math.sqrt(input);
    return ((SquareRoot * SquareRoot) == input);
}

static boolean isPalindrome(int input) {
    String str = Integer.toString(input);
    return new StringBuffer(str).reverse().toString().equals(str);
}
nagendra547
  • 5,672
  • 3
  • 29
  • 43