Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

seeColor challenge

Hi,

I am working on below challenge
http://codingbat.com/prob/p199216

I wrote my code as below
public String seeColor(String str) {
if(str.indexOf("red",0)==1 && str.indexOf("red",1)==1)
return "red";
if(str.indexOf("blue",0)==1 && str.indexOf("blue",1)==1)
return "blue";
else
return "";
  
}

Open in new window


I am failing as below
Expected	Run		
seeColor("redxx") → "red"	""	X	    
seeColor("xxred") → ""	""	OK	    
seeColor("blueTimes") → "blue"	""	X	    
seeColor("NoColor") → ""	""	OK	    
seeColor("red") → "red"	""	X	    
seeColor("re") → ""	""	OK	    
seeColor("blu") → ""	""	OK	    
seeColor("blue") → "blue"	""	X	    
seeColor("a") → ""	""	OK	    
seeColor("") → ""	""	OK	    
seeColor("xyzred") → ""	""	OK	    
other tests
X	   

Open in new window


How to fix and improve my code. Thanks in advance
SOLUTION
Avatar of CPColin
CPColin
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

public String seeColor(String str) {
if(str.startsWith("red"))
return "red";
if(str.startsWith("blue"))
return "blue";
else
return "";
  
}

Open in new window


when i used startsWith() as above i passed all tests. How can i improve my code. Please advise
Not much room for improvement. I guess you could nest the ternary operator to shorten the code, but I doubt if there would be any noticeable in performance
return str.startsWith("red") ? "red" : str.startsWith("blue") ? "blue" : "";
I recommend not making the code harder to read unless there's a tangible benefit. In this case, that line would almost certainly produce the exact same performance as the separate if statements, so condensing the syntax like that is probably not a good idea.
Avatar of gudii9

ASKER

return str.indexOf("red")==0||str.indexOf("blue")==0?str.charAt(2)=='d'?"red":str.charAt(3)=='e'?"blue":"":"";

how and where to break above and below line to understand

return str.startsWith("red") ? "red" : str.startsWith("blue") ? "blue" : "";

simple syntax is as below right
   //
        // Get the maximum value
        //
        int min = a < b ? a : b;

How to relate with this syntax above two quoted  lines. Please advise
Did you try the code I posted? If, as a programmer, you intend looking at code (someone else's) in the hope of understanding it, then trying to explain what my code does would prove helpful to you in the long run. Can you see why it works?
Avatar of gudii9

ASKER

return str.startsWith("red") ? "red" : str.startsWith("blue") ? "blue" : "";

i think i understood above one now

if str.startsWith("red") is true then return as red
if str.startsWith("red") is false then go to inner ternary operator loop str.startsWith("blue") ? "blue" : ""


str.startsWith("blue") ? "blue" : "" works similar way
if str.startsWith("blue") is true then return as blue
if str.startsWith("blue") is false then return as ""

Did you try the code I posted?
yes. i tried and it is passing all tests.
I am not able to understand below. please advise
return str.indexOf("red")==0||str.indexOf("blue")==0?str.charAt(2)=='d'?"red":str.charAt(3)=='e'?"blue":"":"";
return str.indexOf("red")==0||str.indexOf("blue")==0?str.charAt(2)=='d'?"red":str.charAt(3)=='e'?"blue":"":""

Open in new window

is equivalent to
String retval;
Boolean t1=false;
if( str.indexOf("red")==0 ){
    t1=true;
}else if( str.indexOf("blue")==0 ){
    t1=true;
}
if( t1 ){
    if( str.charAt(2)=='d' ){
        retval="red";
    }else{
        if( str.charAt(3)=='e' ){
            retval="blue";
        }else{
            retval="";  // can never get here                                                                                                                                     
        }
    }
}else{
    retval="";
}
return retval;

Open in new window

which strikes me as unduely complicated compared to
if( str.indexOf("red")==0 ){
  retval="red";
}else if( str.indexOf("blue")==0 ){
  retval="blue";
}else{
  retval="";
}

Open in new window

Avatar of gudii9

ASKER

return str.indexOf("red")==0||str.indexOf("blue")==0?str.charAt(2)=='d'?"red":str.charAt(3)=='e'?"blue":"":""

as bolded is the true part of the ternary operator right
Avatar of gudii9

ASKER

how to break down similar to how you did when there are multiple ternary operations within one. please advise
The bolded part corresponds to
    if( str.charAt(2)=='d' ){
        retval="red";
    }else{
        if( str.charAt(3)=='e' ){
            retval="blue";
        }else{
            retval="";                                          
        }
    }
Avatar of gudii9

ASKER

else{
        if( str.charAt(3)=='e' ){
            retval="blue";
        }else{
            retval="";                                          
        }

Open in new window


why else block used why not one other if block. Please advise
: corresponds to else
Avatar of gudii9

ASKER

? is if right
more like the ){ but yes.
I don't agree with ozo's thinking this time that the equivalent of my code is a longwinded rendering like he has given. In code, you can't say that "one thing is like another", as it's all to do with clock cycles, and you can't compare different function calls like that in such cases.

What I am getting at gudii, is that I think your "problems" in these coding exercises are not so much to do with coding, but with understanding the question in plain language in the first place. That is why I am asking you if you can decipher what my code really means, on a "philosophical" level. If you feel you can't or don't want to do this, then simply say so. And if you are interested in how it works and why, then I will gladly explain. The point of my explanation would be to help you with understanding the problem in the first place, and not with the code as such, which will all fall into place for you I think once you really understand what's going on.
Avatar of gudii9

ASKER

What I am getting at gudii, is that I think your "problems" in these coding exercises are not so much to do with coding, but with understanding the question in plain language in the first place. That is why I am asking you if you can decipher what my code really means, on a "philosophical" level. If you feel you can't or don't want to do this, then simply say so.

this challenge i understood which happened to return red or blue if the given string starts with red or blue. I understood few approaches as well.  The approach you mentioned looks bit challenging to me to understand may be due to my lack understanding on bigger multiple ternary loops.
Avatar of gudii9

ASKER

more like the ){ but yes.
can you please elaborate on this?
The approach you mentioned looks bit challenging to me to understand may be due to my lack understanding on bigger multiple ternary loops.

Ternary is not complicated. It's like an if-else, but the difference with a ternary is that each time you use it you MUST give an else (which in ternary is the part that comes after the ":" operator).

But anyway, back to the pathology of how to deal with red, blue, "", and other strings (that we don't want).

My ternary is simple - by asking whether "red" OR "blue" is at position 0 of the string WE IMMEDIATELY EXCLUDE ANY String that ISN'T RED or BLUE. And that INCLUDES "". Think about that - when the ternary checks for red or blue at index 0, and finds one of them, then that can only mean that one of them is there - not "daffodil" or "elephant" or "green" or "purple" or even "" ! If the ternary test is passed, then ONLY red or blue can be there. So knowing that, you then just need another ternary (nested) to test whether it is red or blue.

(The only thing you need to remember when doing something like that, is that if they wanted you to test for the two colours "red" and "ruby", you would need to choose any other character than the ones at position 0 in each substring, otherwise you get a false positive returned. So in this case, you'd test whether e,u,b,d or y was at one of the other positions.
Actually, once you know the string must begin with either red or blue, you could test for "r" (or "b") at index 0 to confirm which.
Yes, of course you can do that. But I chose different indices to check, so that the questioner might ask "why did you choose those positions", and so understand more completely what is going on.
I agree with the idea of choosing indices for the very purpose you state (why choose those?). The answer to why is basically, once you know the string begins with only "red" or "blue", what test can be made to verify which one. It's kind of like the old balance scale puzzle where once you determine which coin (or marble, etc.) is the odd one, it's one more small step to determine if it's heavier or lighter. In fact all of the following options would confirm if the string was red or blue"
"r" at index 0
"re" at index 0
"red" at index 0
"e" at index 1
"ed" at index 1
"d" at index 2
"b" at index 0
"bl" at index 0
"blu" at index 0
"blue" at index 0
"l" at index 1
"lu" at index 1
"lue" at index 1
"u" at index 2
"ue" at index 2
"e" at index 3
Yes, it's obvious that you can do all of those. But you can only do the ones that are single characters using charAt(), otherwise you'd need substring again and I wanted to avoid that.
str.indexOf("red")==0||str.indexOf("blue")==0?str.charAt(2)=='d'?"red":str.charAt(3)=='e'?"blue":"":""
You test for red,
You test for blue
then you merge the results of those two tests together,
so you now need to re-separate them,
so you test for red again
and then test for blue again.

If you're going to go through all that, why not
  String[]redblue={"red","blue"};
  return str.indexOf("red")==0||str.indexOf("blue")==0?
  redblue[str.indexOf('e')/3]
  :"";
You test for red,
 You test for blue

Yes . . . but I don't test for "", that's half the point, saves a whole quiz. The other half of the point is that with the OR you don't need another if. And I don't introduce the new complication of a String[].

And how would it work if you were looking for 'red' and 'tan'?
If I test for red and it is true, I then know immediately that the return value should be "red"
I don't need to test for blue, combine that test with the test for red, and then test for red again then test for blue again.
If the test for red was false, and I don't return "red", then I now only need to test for "blue"
You'll have to explain to me again how your algo would work if you were asked to search for 'red' and 'tan' - two colours which share no common character.
return str.indexOf("red")==0?
               "red"
            :  str.indexOf("tan")==0?
               "tan"
               :
               "";
ozo and krakatoa,

Why make things more complicated than just using startsWith()? The code in this comment is passing all tests. Isn't that good enough?

Why also muddy the syntax by using the ternary operator? The if-else blocks are much easier to read and accomplish the same goal.
I was not suggesting http:#a40510146 as an alternative to http:#a40507397
I was suggesting it as an alternative to http:#a40503348, which was the subject of the current discussion.
In that case, could the two of you please take the discussion elsewhere? I don't think it's helping gudii9 get any closer to a solution.
@CPColin

I agree completely. My agenda was only to help the OP expand the thinking a little. As I said in a comment, seems his difficulty is in the profile of the questions themselves, and my ternary was simply another way of looking at what coding challenge asks be returned.

@ozo -

ozo2014-12-19 at 21:56:32ID: 40510146

You just changed your model. You were talking about a String[] and now you've dropped that idea. I don't see your String[] model - as it stands - working at all under the conditions I mentioned. Changing your plea to two distinct return statements is chalk compared to your earlier cheese.
gudii9 has a solution, but since then asked a question about http:#a40503348
gudii9 has a solution, but since then asked a question about http:#a40503348 

Right, well then why not let gudii ask about the code I posted, instead of going off on another idea, that you linked to mine. It's fair enough if you bring in a new idea unilaterally, but linking it erroneously to what I posted is unhelpful, and misleading for the OP.
>>But you can only do the ones that are single characters using charAt(), otherwise you'd need substring again and I wanted to avoid that<<
No need for substring. Instead of using charAt(), you could use indexOf() -
e.g. str.indexOf("ed") = 1 or str.indexOf("ue") = 2
Yes, I know. But you didn't say that in your earlier post. And seeing as the OP is the one with the understanding requirement here, it should have been clarified then.
I agree. I should have been much more explicit. :-(
Avatar of gudii9

ASKER

i just all the posts now. I think i need to read and re read few times to understand all above alternate approaches which all looks great.
Avatar of gudii9

ASKER

return str.indexOf("red")==0||str.indexOf("blue")==0?str.charAt(2)=='d'?"red":str.charAt(3)=='e'?"blue":"":""

Open in new window



above is same as below right

String retval;
Boolean t1=false;
if( str.indexOf("red")==0 ){
    t1=true;
}else if( str.indexOf("blue")==0 ){
    t1=true;
}
if( t1 ){
    if( str.charAt(2)=='d' ){
        retval="red";
    }else{
        if( str.charAt(3)=='e' ){
            retval="blue";
        }else{
            retval="";  // can never get here                                                                                                                                     
        }
    }
}else{
    retval="";
}
return retval;

Open in new window

Avatar of gudii9

ASKER

public String seeColor(String str) {
String retval;
Boolean t1=false;
if( str.indexOf("red")==0 ){
    t1=true;
}else if( str.indexOf("blue")==0 ){
    t1=true;
}
if( t1 ){
    if( str.charAt(2)=='d' ){
        retval="red";
    }else{
        if( str.charAt(3)=='e' ){
            retval="blue";
        }else{
            retval="";  // can never get here                                                                                                                                     
        }
    }
}else{
    retval="";
}
return retval;

}

Open in new window


above fails for input rxd and bxxxe(replacing middle characters with x in red and blue)
please advise
>>above fails for input rxd and bxxxe(replacing middle characters with x in red and blue)<<
What gets returned in those cases?
Avatar of gudii9

ASKER

public class test40 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		System.out.println("seeColor red is----"+seeColor("rxd"));
		System.out.println("seeColor blue----"+seeColor("bxxxe"));
	}
	
	public static String seeColor(String str) {
		String retval;
		Boolean t1=false;
		if( str.indexOf("red")==0 ){
		    t1=true;
		}else if( str.indexOf("blue")==0 ){
		    t1=true;
		}
		if( t1 ){
		    if( str.charAt(2)=='d' ){
		        retval="red";
		    }else{
		        if( str.charAt(3)=='e' ){
		            retval="blue";
		        }else{
		            retval="";  // can never get here                                                                                                                                     
		        }
		    }
		}else{
		    retval="";
		}
		return retval;

		}

}

Open in new window

when i run like above not getting anything as output as below

seeColor red is----
seeColor blue----

please advise
Isn't that what you would expect? Since "rxd" is not "red" and "bxxxe" is not "blue", the seeColor function is returning the empty string ("").
It looks like http:#a40533258 correctly returns "" for  input rxd and bxxxe
Avatar of gudii9

ASKER

oh i see since t1 is false it will return "" from below else block right? So the code is doing what it supposed to do then.

else{
    retval="";

please advise
Avatar of gudii9

ASKER

public class test40 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		System.out.println("seeColor red is----"+seeColor("rxd"));
		System.out.println("seeColor blue----"+seeColor("bxxxe"));
	}
	
	public static String seeColor(String str) {
		String retval;
		Boolean t1=false;
		if( str.indexOf("red")==0 ){
		    t1=true;
		}else if( str.indexOf("blue")==0 ){
		    t1=true;
		}
		if( t1 ){
		    if( str.charAt(2)=='d' ){
		        retval="red";
		    }else{
		        if( str.charAt(3)=='e' ){
		            retval="blue";
		        }else{
		            retval="";  // can never get here                                                                                                                                     
		        }
		    }
		}else{
		    retval="aaa";
		}
		return retval;

		}

}

Open in new window


now i got
seeColor red is----aaa
seeColor blue----aaa


i change to aaa instead of "" to confirm and it is indeed giving back aaa
           if( str.indexOf("red")==0 ){
At this point you already know that the function should return "red"; and there is no further need to check str.charAt(2) or str.charAt(3).
...unless you then proceed to mix up this condition with another condition, only to have to separate them again.
Avatar of gudii9

ASKER

no further need to check str.charAt(2) or str.charAt(3).

Above make sense