## Funny String

Sort 463 Discussions, By:

i have submitted my solution and except two test cases all others failed with message wrong answer, but when i tries test case #8 on local it all output in correct answer. can i know whats the issue?

Same thing with me!

Have you figured out why?

int main() {

    int n,count;
string s,r;
cin>>n;
while(n--)
{ count=0;
cin>>s;
r=s;reverse(r.begin(),r.end());
for(int i=1;i<s.length();i++)
{
if(abs(s[i]-s[i-1])==abs(r[i]-r[i-1]))
{count++;

}
}
if(count==s.length()-1)
{cout<<"Funny\n";
}else cout<<"Not Funny\n";

}

return 0;


}

Why do you use abs? I have seen a couple of examples using it and I still can't get it, I have tried using it in javascript but does not work

function processData(input) {
var arr = input.split(/[\n]+/);
var tn = parseInt(arr.shift()), t = 0;
while (t < tn) {
var s = arr[t];
var l = s.length;
var f = 1;
for (var i = 1; i < l; i++) {
if (Math.abs(s[i] - s[i - 1]) == Math.abs(s[l - i] - s[l - i - 1])) {
f = f + 1;
}
}

console.log(f == l ? 'Funny' : 'Not Funny');
t++;
}
}

• somananda + 1 comment

abs stand for absolute value.we used it bcz we need the length between two alphabets as a positive value.(obvious distance between two object never been a negative)

In addition to that, the problem states that |Si−Si−1|=|Ri−Ri−1|. Whatever the value in between both the bars "| value |" means that we take the positive value of it even if its negative.

You only have to iterate over half of the string ;-)

• BM

How is that possible? for a string of length 4 , we would have to make 3 comparisons, as the example shows. Can you please explain the logic.

[deleted]
• fhdiaze + 1 comment

I think this is because after the firs half ot the string all the next pairs you have already checked.

• MN

yes we just need to compare half of the string and the other half we would have already done. abs value is the clue for that

hi @jcasarrubias i resolve in this way. good luck

function processData(input) {
input = input.split('\n')
var n = input[0];
for (var z=1;z<=n;z++) {
var s = input[z].split('');
var r = input[z].split('').reverse();
var j = 1;
var i = 1;
while (j <= s.length-1) {
if (Math.abs(s[j].charCodeAt()-s[j-1].charCodeAt()) == Math.abs(r[j].charCodeAt()-r[j-1].charCodeAt())) {
i++;
}
j++;
}
if ( i == s.length) {
console.log('Funny')
} else {
console.log('Not Funny')
}
}

}

• luhego + 1 comment

You don't need to count, you can assume the strings are funny, if you find one difference you just break the loop and set the flag to false.

• SK

Hahaha :D A smart ass solution.

C Solution:

int main() {

char s[10000], r[10000];
int times;
scanf("%d", &times);
for (int t = 0; t < times; t++) {
scanf("%s", s);
int len = strlen(s);
for (int i = 0; i < len; i++) {
r[i] = s[strlen(s) - i - 1];
}
int funny = 1;
for (int i = 1; i < len; i++) {
if (abs(r[i] - r[i-1]) != abs(s[i] - s[i-1])) {
printf("Not Funny\n");
funny = 0;
break;
}
}
if (funny) {
printf("Funny\n");
}

}

return 0;
}

• ezeezegg + 1 comment

hi @etayluz i think that you can optimize this code more because you use 2 cycles for in my solution i use 1 for and while

function processData(input) {
input = input.split('\n')
var n = input[0];
for (var z=1;z<=n;z++) {
var s = input[z].split('');
var r = input[z].split('').reverse();
var j = 1;
var i = 1;
while (j <= s.length-1) {
if (Math.abs(s[j].charCodeAt()-s[j-1].charCodeAt()) == Math.abs(r[j].charCodeAt()-r[j-1].charCodeAt())) {
i++;
}
j++;
}
if ( i == s.length) {
console.log('Funny')
} else {
console.log('Not Funny')
}
}

}


You are able to optimize even further because you don't need to iterate through the entire string (or create a pair of arrays from the string either). I've also created variables for the if statement for improved readability.

const funnyString = s => {
for (let i = 0; i < Math.floor(s.length / 2); i++) {
let s1 = s[i].charCodeAt(0);
let s2 = s[i + 1].charCodeAt(0);
let r1 = s[s.length - i - 1].charCodeAt(0);
let r2 = s[s.length - i - 2].charCodeAt(0);
if (Math.abs(s1 - s2) !== Math.abs(r1 - r2)) return 'Not Funny';
}
return 'Funny';
}


I have done almost same still m getting segmentation fault in case 9. can u tell me why! here's my code.

int main() { int t,i,flag; char s[10000],r[10000]; scanf("%d",&t); for(;t--;) { flag=1; scanf("%s",&s);

for(i=0;i

for(i=1;i

if(flag==1)
printf("Funny\n");

}
return 0; }

• vijay_laxmi3 + 1 comment

hey! In this loop if i use len instead of strlen(s) it clears case 9 also. for(i=0;i but if i use it just like this it's not able to clear test case 9 and gives segmentation fault. can u tell why? what's the difference. afterall len=strlen(s) plz help me. thanks!

https://kb.iu.edu/d/aqsj

and you dont need 2 arrays actually

 int main() { char s[10000]; int t,i=1,j,f; scanf("%d",&t); while(t--) { scanf("%s",s); i=1; j=strlen(s)-2; f=1; while(i<=j&&f) { if(abs((s[i])-s[i-1])!=abs(s[j]-s[j+1])) { printf("Not Funny\n"); f=0; } i++;j--; } if (f) printf("Funny\n"); } return 0; 

} 

• rsingh52 + 1 comment

Overhead of reversing the string and storing it in another string can be avoided

• GS

int main() {

/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int T;
char in[10000];
int output[10];
scanf("%d",&T);
for(int j=0;j<T;j++)
{
scanf("%s",in);
int len=strlen(in)-1;
int x=1;
for(int i=0;i<len;i++)
{
if(abs(in[i]-in[i+1]) != abs(in[len-i]-in[len-1-i]))
{
x=0;
printf("Not Funny\n");
break;
}
}
if(x==1)
printf("Funny\n") ;
}
return 0;


}

same thing with me i cant understand why

• RC

Please let me know, if you have figured out why....

int main() {

    int n,count;
string s,r;
cin>>n;
while(n--)
{
count=0;

cin>>s;
r=s;reverse(r.begin(),r.end());
for(int i=1;i<s.length();i++)
{
if(abs(s[i]-s[i-1])==abs(r[i]-r[i-1]))
{count++;

}
}
if(count==s.length()-1)
{cout<<"Funny\n";
}else cout<<"Not Funny\n";

}

return 0;


}

same issue here, this is my solution on javascript I just can pass the first 2 tests I think is pretty streight forward, but still cant pass more than 2.

function processData(input) {
var arr = input.split(/[\n]+/);
var abc = 'abcdefghijklmnopqrstuvwxyz';
var tn = parseInt(arr.shift()), t = 0;

while (t < tn) {
var s = arr[t];
var l = s.length;
var f = true;

for (var i = 1; i < l; i++) {
var _s1 = abc.indexOf(s[i]);
var _s2 = abc.indexOf(s[i - 1]);
var _r1 = abc.indexOf(s[l - i]);
var _r2 = abc.indexOf(s[l - i - 1]);

if ((_s1 - _s2) != (_r1 - _r2)) {
f = false;
break;
}
}

console.log(f ? 'Funny' : 'Not Funny');
t++;
}
}


l - 1 - i and l - 1 - i - 1.

• piyus + 1 comment

take the absolute difference

yes I got from @somanada's response it worked, that was tricky but now make sense

:)

[deleted]

You only have to iterate over half of the string ;-)

Check this out , My sol : public static void main(String[] args) {

Scanner sc= new Scanner(System.in);
int t=sc.nextInt();

for(int i=0;i<t;i++)
{
int flag=0;
String s=sc.next();
int start=0,end=s.length()-1;

while(start<(s.length()-2))
{

int first=(int)s.charAt(start);
int last=(int)s.charAt(end);
int sec=(int)s.charAt(start+1);
int sec_last=(int)s.charAt(end-1);

if(Math.abs(first-sec)!=Math.abs(last-sec_last))
flag=1;

start++;
end--;
}

if(flag==0)
System.out.println("Funny");
else
System.out.println("Not Funny");
}


}

• RV

When your If condition is met, you should break from while, this will save few cycles.

And people keep asking me why I prefer scala over java ;-) Its actually the whole program, not only the part inside main ;-)

object Solution {
def main(args: Array[String]) = println((1 to readLine.toInt).map { _ =>
val s = readLine; val c = s.length - 1
(if((0 to s.length/2).forall(i => math.abs(s(i)-s(i+1)) == math.abs(s(c-i)-s(c-i-1)))) "" else "Not ") + "Funny"
}.mkString("\n"))
}


shorter != better

• LD

Shouldn't it be while (start < s.length()-1) ?

Excellent

Very good!!

• IB
[deleted]
• DV

Same issue is faced by me! :(

Same Problem ... My program Working Locallu Fine but when i copy the code it will show wrong answers...

• SP

I also faced the same issue. Its due to the canonical mode enabled in the tty where running the executable. If this mode is enabled, strings more than 4096 bytes can not be entered in to the tty. hackerrank team should use 'stty -icanon' command before running the test case. Thanks

• AZ

My code works

for r in xrange(int(raw_input())):
N = raw_input()
S = N[::-1]
print 'Funny' if all((abs(ord(N[i]) - ord(N[i - 1])) == abs(ord(S[i]) - ord(S[i - 1]))) for i in xrange(1, len(N))) else 'Not Funny'

• me_rishiverma + 1 comment

N = raw_input() # contains a string

N[i] is a character in the string

the subtraction operator '-' is not supported for strings

ord converts the string to an integer (ascii/unicode value) to perform the subtraction.

https://docs.python.org/2/library/functions.html#ord

• CX
v0lkan0 + 1 comment

thx for all, but you create in memory another string with same length

• Ninja_kx + 1 comment

Mine:

n=int(input())
for _ in range(n):
st=[str(x) for x in input().strip()]
diff=[abs(ord(a)-ord(b)) for a,b in zip(st,st[1:])]
print("Funny" if (diff==diff[::-1]) else "Not Funny")


Cool one Ninja_Kx. My soln

def funnyString(s):
# Complete this function
rev = s[::-1]
for i in range(len(s)-1):
if abs(ord(s[i+1]) - ord(s[i])) != abs(ord(rev[i+1]) - ord(rev[i])):
return "Not Funny"
return "Funny"


after every test case put count=0 if you dont do this then the count wont start from 0 but from the previous incremented values. :)

That was my problem and i was trying different methods for this one :p

• CS

man!! you just saved my life...

after taking input of number of test cases, try inserting cin.ignore();

Same with me too!!!! How can |x-c| = |c-x| = 21 possible???

[deleted]

I am facing the same issue. When I run the test cases at the local machine it works but not on their system. I am using C# for my code.

I have a equation : i - (i-1) = (n-(i+1)) - (n-i)

• cheick_ismo + 1 comment

My solution in java 7 pass all tests public class Solution {

public static boolean isFunny(String s){
String r= new StringBuilder(s).reverse().toString();
boolean isFunny=false;
int j=1;
while(Math.abs(s.charAt(j)-s.charAt(j-1))== Math.abs(r.charAt(j)-r.charAt(j-1)) && j<s.length()){
j++;
if(j==s.length()){
isFunny=true;
break;
}
}
return isFunny;
}
public static void main(String[] args) {

Scanner in= new Scanner(System.in);
int t = in.nextInt();
for(int i=0;i<t;i++){
String s = in.next();
String r= new StringBuilder(s).reverse().toString();
if(isFunny(s)==true)
System.out.println("Funny");
else
System.out.println("Not Funny");
}
}


}

We dont have to reverse the string, it can be achieved without reverse

int length = s.length();
int left = 0;
int right = length - 1;
boolean funny = true;
while (left < length - 1 && right > 0) {
if (Math.abs(((int) s.charAt(left + 1) - (int) s.charAt(left))) != Math
.abs(((int) s.charAt(right - 1) - (int) s.charAt(right)))) {
funny = false;
break;
}
left++;
right--;
}
System.out.println((left == length - 1 && right == 0 && funny) ? "Funny" : "Not Funny");


I had the same problem using Java. It was because the boolean value (which is initialized as true and is set to false if the condition is not met within the loop) was accidentally initialized outside the for loop that went over each string/line. Try initializing that inside the loop and see if that helps.

• techniker + 1 comment

Below is my solution, initially

boolean funny = true;


declaration was outside the while loop which was failing 8 test cases. I declared the variable inside the while loop & all the cases passed.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s;
StringBuilder reverse;

boolean funny = true;
reverse = new StringBuilder(s).reverse();
for(int i=1;i<s.length();i++){
System.out.println(s.charAt(i));
int modS = Math.abs(s.charAt(i)-s.charAt(i-1));
int modR = Math.abs(reverse.charAt(i)-reverse.charAt(i-1));

if(modS!=modR){
funny = false;
break;
}
}

if(funny){
System.out.println("Funny");
}else{
System.out.println("Not Funny");
}
}


Can be done without reverse

int length = s.length();
int left = 0;
int right = length - 1;
boolean funny = true;
while (left < length - 1 && right > 0) {
if (Math.abs(((int) s.charAt(left + 1) - (int) s.charAt(left))) != Math
.abs(((int) s.charAt(right - 1) - (int) s.charAt(right)))) {
funny = false;
break;
}
left++;
right--;
}
System.out.println((left == length - 1 && right == 0 && funny) ? "Funny" : "Not Funny");


same with me

• AK

it might be happening because you are not taking the absolute value; if you don't do so then "acxz" is funny and "aczx" is not funny; here is my code... import java.util.Scanner;

public class FunnyString {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int q = in.nextInt();
for(int a0 = 0; a0 < q; a0++){
String s = in.next();
String result = funnyString(s);
System.out.println(result);
}
in.close();
}

private static String funnyString(String s) {
for(int i=1;i<=s.length()/2;++i){
int diff1=0,diff2=0;
diff1=s.charAt(i)-s.charAt(i-1);
if(diff1<0)
diff1*=-1;
diff2=s.charAt(s.length()-i)-s.charAt(s.length()-1-i);
if(diff2<0)
diff2*=-1;
if(diff1!=diff2){
return "Not Funny";
}
}
return "Funny";
}


}

iterate from i = 0 to i = 1 + n/2 where n is length of string blank character is coming in that test case due to end of string

no need to reversing the string. we can do it simply by parsing from right to left.

using System; using System.Collections.Generic; using System.IO; using System.Linq; class Solution {

static string funnyString(string s){
// Complete this function

bool ans=false;
for(int i=1,j=s.Length-2;i<s.Length;i++,j--)
{
if(Math.Abs(s[j]-s[j+1])!=Math.Abs(s[i]-s[i-1]))
{
ans=true;
break;
}
}
return (ans?"Not Funny":"Funny");
}

static void Main(String[] args) {
for(int a0 = 0; a0 < q; a0++){
string result = funnyString(s);
Console.WriteLine(result);
}
}

• GR

YES SAME THING WITH ME

my solution, C++:

bool funny(string s) {

bool outp = true;
for (int i=1, j=s.length()-2; i<s.length(), j>=0; i++, j--) {

if ( abs(s[i]-s[i-1]) != abs(s[j]-s[j+1]) ) {
return false;
}
}
return outp;


}

Good answer. But if you want to reflect how the problem is worded then you can create the reversed string R pretty easily too:

void areYouFunny(string& S) {
string R(S.rbegin(), S.rend());
bool isFunny = true;

for (int i = 1; i < S.length() && isFunny; i++) {
isFunny = abs(S[i] - S[i-1]) == abs(R[i] - R[i-1]);
}

cout << (isFunny ? "Funny" : "Not Funny") << endl;
}


I took the same approach. However, we can simplify it a little bit by not using j. Anyway, this question does not worth 25 points.

Java submition

public static boolean isFunny(String asx) {
char[] chars = asx.toCharArray();
char[] chars2 = new     StringBuilder(asx).reverse().toString().toCharArray();
for (int i = 1; i < asx.length(); i++) {
if (Math.abs((int) chars[i] - (int) chars[i - 1]) != Math.abs((int) chars2[i] - (int) chars2[i - 1])) {
return false;
}
}
return true;
}

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 <t; a0++){
String n = in.nextLine().trim();
String result = (isFunny(n)==true) ? "Funny" : "Not Funny";
System.out.println(result);

}

}


}

• VR

# include

int main() { int t,count=0,i,j,n; char *s=(char *)malloc(10000*sizeof(char)); char *r=(char *)malloc(10000*sizeof(char)); scanf("%d",&t); while(t!=0) { scanf("%s",s); n=strlen(s); j=n-1; for(i=0;i

    }
for(i=1;i<n;i++)
{
if(abs(s[i]-s[i-1])!=abs(r[i]-r[i-1]))
{
count++;
break;
}
}

if(count==0)
printf("Funny\n");
else
printf("Not Funny\n");
t--;
}
return 0;


}

• UP

you can directly work with strings with charAt method, and instead of saving the reverse just put a counter at end. Also, you only need to go uptill half of string :)

• SC

hi JohnPas

what is the difference you see between your code and my code

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean funny = true;
int testCases = in.nextInt();

for(int i=0;i < testCases;i++){
String str = in.next();
String revStr = new StringBuilder(str).reverse().toString();
for(int j=1; j < str.length();j++){
if(Math.abs((str.charAt(j) - str.charAt(j-1))) != Math.abs((revStr.charAt(j) - revStr.charAt(j-1)))){
funny = false;
}
}
System.out.println(funny? "Funny":"Not Funny");
}
}


I believe the first explanation example is backwards. According to the formula provided: |Si−Si−1|=|Ri−Ri−1|

I believe the current example:

|c-a| = |x-z| = 2

|x-c| = |c-x| = 21

|z-x| = |a-c| = 2

should be reordered as the following:

|z-x| = |a-c| = 2

|x-c| = |c-x| = 21

|c-a| = |x-z| = 2

I am curious if anyone else agrees.

Nah, it's in the correct order as is. The formula is ran with initial value i=1, meaning it tests compares S_1 and S_0 to R_1 and R_0, then S_2 and S_1 to R_2 and R_1, etcetera.

This evaluates to the formula exactly in the explanation.

Not really, you start with the second character so: Si = c Si-1 = a R represents the reverse so, Ri = x Ri-1 = z Hope that helps

• Nicke + 1 comment

My solution in C#.

static string funnyString(string s)
{
for (int i = 0; i < s.Length / 2; i++)
{
int l = (s.Length - 1) - i;
int a = (int)s[i];
int b = (int)s[i + 1];
int c = (int)s[l];
int d = (int)s[l - 1];

if (Math.Abs(a - b) != Math.Abs(c - d))
return "Not Funny";
}
return "Funny";
}


public static void checkStringisFunny(String str) { char[] chars = str.toCharArray(); int j = chars.length-1;

  for(int i = 1 ;i<chars.length;i++)
{
if(Math.abs((int)chars[i]-(int)chars[i-1])== Math.abs((int)chars[j]-(int)chars[j-1]))
{
j--;
continue;
}else
{
System.out.println("Not Funny");
return;

}

}
System.out.println("Funny");

}

• chelBot + 1 comment

Here is how I did it in python.

n = int(raw_input())
for _ in range(n):
str_ = raw_input()
len_ = len(str_)
for i in range(1, len_):
s_diff = ord(str_[i]) - ord(str_[i - 1])
r_diff = ord(str_[len_ - i]) - ord(str_[len_ - i - 1])
if abs(s_diff) != abs(r_diff):
print "Not Funny"
break
else:
print "Funny"

• ElegantAlgorithm + 1 comment

And here's how I did it in Python 3:

t = int(input())
for a in range(t):
s = input()
TorF = all([abs(ord(s[i]) - ord(s[i-1])) == abs(ord(s[-i]) - ord(s[-i-1])) for i in range(1, len(s)//2+1)])
print('Funny' if TorF else 'Not Funny')

• DB

Reduced

for _ in range(int(input())):
s = input()
print(['Not Funny','Funny'][all([abs(ord(s[i]) - ord(s[i-1])) == abs(ord(s[-i]) - ord(s[-i-1])) for i in range(1, len(s)//2+1)])])

• DP
Devil_K + 1 comment

Java Solution

for(int i=0;i<s.length()-1;i++){
int a = s.charAt(i);
int b = s.charAt(s.length()-i-1);
int c = s.charAt(i+1);
int d = s.charAt(s.length()-i-2);
if(Math.abs(a-c)!=Math.abs(b-d)){
return "Not Funny";
}
}
return "Funny";


Great solution!! Hat's off!!

• A

Python oneliner:

[print(a) for a in list(map(lambda s: ['Not Funny', 'Funny'][(all([abs(ord(s[i+1])-ord(s[i])) == abs(ord(s[-i-2])-ord(s[-i-1])) for i in range(len(s)-1)]))], [input().strip() for _ in range(int(input().strip()))]))] #oneliner

• zee1s + 1 comment

Python

q=int(input())
for _ in range(q):
inp=input()
l=len(inp)
funny=1
alist=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']

for i in range(1,l):
if(abs(alist.index(inp[i])-alist.index(inp[i-1]))!=abs(alist.index(inp[l-i])-alist.index(inp[l-i-1]))):
print("Not Funny")
funny=0
break
if(funny):
print("Funny")

[deleted]
• VN
cakerusk + 1 comment

You can just iterate over half of the string as we check the absolute values so the rest will be repetition.

Java solution :

private static boolean isFunny(String given) {
int last = given.length() - 1;

for (int first = 1; first <= given.length()/2; first++, last--) 	{
if (Math.abs(given.charAt(first) - given.charAt(first - 1)) != Math.abs(given.charAt(last) - given.charAt(last - 1))) {
return false;
}
}

return true;
}