HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Funny String Java Solution

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
javasolutionstringfunny

Problem

I'm a little rusty in Java, but I'm using it to get ready for interviews. Here's the problem description from HackerRank:


Problem Statement


Suppose you have a string \$S\$ which has length \$N\$ and is indexed from \$0\$
to \$N−1\$. String \$R\$ is the reverse of the string \$S\$. The string \$S\$ is funny
if the condition \$|S_i−S_{i−1}|=|R_i−R_{i−1}|\$ is true for every \$i\$ from 1 to
\$N−1\$.


(Note: Given a string str, stri denotes the ascii value of the ith
character (0-indexed) of str. |x| denotes the absolute value of an
integer x)


Input Format


First line of the input will contain an integer T. T testcases follow.
Each of the next T lines contains one string S.


Constraints



  • \$1 \le T \le 10\$



  • \$2 \le\$ length of S \$\le 10000\$





Output Format


For each string, print Funny or Not Funny in separate lines.

This passing solution took me about 20 minutes, so that might be a bit long given the difficulty of the problem. I'm open to critiques on my speed too.

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {
    private static boolean isFunny (String s)
    {
        String rev = reverse(s);
        boolean stillEq = true;
        for (int i = 2; i  0)
            return s.charAt(s.length()-1) + reverse(s.substring(0, s.length()-1));
        else
            return "";
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int tests = sc.nextInt();
        for (int i = 0; i < tests; ++i)
        {
            String out = isFunny(sc.next()) ? "Funny" : "Not Funny";
            System.out.println( out );
        }
    }

Solution

-
Bug

The main loop starts at i = 2. That is, s.charAt(1) - s.charAt(0) is never attended to. Suspicious, isn't it?

-
Naming

A name comp (and comp2) presumes that it carries some information about comparison. It obviously doesn't. diff and rdiff sound better.

-
Algorithm

Reversal of the string just wastes time. You may work the same string from both directions simultaneously:

for (int i = 1; i < s.length(); ++i) {
    diff = s.charAt(i) - s.charAt(i - 1);
    rdiff = s.charAt(s.length() - 1 - i) - s.charAt(s.length() - 1 - (i-1));
    ...


-
Returning the comparison result is an anti-pattern.

return stillEq;


achieves the same result as

if (stillEq)
    return true;
else
    return false;


in a much cleaner way.

  • If you insist on reversing a string, better come up with an iterative method. Java cannot eliminate tail recursion.

Code Snippets

for (int i = 1; i < s.length(); ++i) {
    diff = s.charAt(i) - s.charAt(i - 1);
    rdiff = s.charAt(s.length() - 1 - i) - s.charAt(s.length() - 1 - (i-1));
    ...
return stillEq;
if (stillEq)
    return true;
else
    return false;

Context

StackExchange Code Review Q#105565, answer score: 12

Revisions (0)

No revisions yet.