Solved

hasOne  challenge

Posted on 2016-08-30
59
91 Views
Last Modified: 2016-09-03
Hi,

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

Psedo code:
1. for given number % with 10
2. if 1 return true
3. else return false

I wrote my code as below

public boolean hasOne(int n) {
  if(n%10==1){
  
 // if(n/10==1){
  return true;
 // }
  }
  return false;
  
}

Open in new window




I am not passing all tests
Expected      Run            
hasOne(10) → true      false      X      
hasOne(22) → false      false      OK      
hasOne(220) → false      false      OK      
hasOne(212) → true      false      X      
hasOne(1) → true      true      OK      
hasOne(9) → false      false      OK      
hasOne(211112) → true      false      X      
hasOne(121121) → true      true      OK      
hasOne(222222) → false      false      OK      
hasOne(56156) → true      false      X      
hasOne(56556) → false      false      OK      
other tests
X      

How to improve/modify my design, code and any other alternate approaches. please advise
0
Comment
Question by:gudii9
  • 25
  • 16
  • 9
  • +1
59 Comments
 
LVL 14

Assisted Solution

by:CPColin
CPColin earned 125 total points
ID: 41777190
You need to examine all the digits of the input and return true if you see a 1. Your code, as it's currently written, looks at only the right-most digit.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41777200
how to look 2nd 3rd 4th etc digits?
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41777201
The challenge description gives you a hint.
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41777322
Print out values for n%10 and n/10 for several values of n.

How do the answers relate to n.
0
 
LVL 27

Expert Comment

by:rrz
ID: 41777407
Is it cheating to use String method? I remember krakatoa showed you how to do it on other challenges in the past.
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41777418
The challenge specifically said to use % and / .
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41777419
What are  13345/10   and   12345%10  ?
0
 
LVL 7

Author Comment

by:gudii9
ID: 41777422
13345/10   is 1334
and   12345%10  is 5
0
 
LVL 7

Author Comment

by:gudii9
ID: 41777423
Expected      Run            
hasOne(10) → true      false      X      
hasOne(22) → false      false      OK      
hasOne(220) → false      false      OK      
hasOne(212) → true      false      X      
hasOne(1) → true      true      OK      
hasOne(9) → false      false      OK      
hasOne(211112) → true      false      X      
hasOne(121121) → true      true      OK      
hasOne(222222) → false      false      OK      
hasOne(56156) → true      false      X      
hasOne(56556) → false      false      OK      
other tests
X      

i am failing above four tests
0
 
LVL 7

Author Comment

by:gudii9
ID: 41777424
10 then  212 then 211112 then 56156. how to cover those test cases and 1 is hiding somewhere in the middle in them not at beginning?
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41777431
12345%10  is 5
12345/10   is 1234

The answer is there if you think about it.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41777433
i have to loop through each digit and check if it is one or not by doing both % and / ?
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41777435
What does the Challenge say about using the / operator?
0
 
LVL 7

Author Comment

by:gudii9
ID: 41777441
/ to discard the rightmost digit.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41777444
public boolean hasOne(int n) {
 if (n % 10 == 1) {

  // if(n/10==1){
  return true;
  // }
 } else {
  if ((n / 10) % 10 == 1) {
   return true;
  } else {
   if ((n / 100) % 10 == 1) {
    return true;
   }
  }
 }
 return false;

}

Open in new window

above pased all tests. any improvements or alternate approaches?
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41777446
After the discard, there is a new rightmost digit to check.
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41777448
That code is not correct.  Post your actual results, and try some longer cases.

Like 12345

If n is a five digit number, then you have to do five tests.
0
 
LVL 27

Expert Comment

by:rrz
ID: 41777469
The if statement is not the only looping control flow statement.  
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html
1
 
LVL 27

Accepted Solution

by:
d-glitch earned 250 total points
ID: 41778088
The problem statement gives you almost the complete pseudo code:
[Loop until you have checked all the digits or found a 1] 
     use % to get [and check] the rightmost digit, and
     [then use] / to discard the rightmost digit.

Open in new window

0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41778114
Your most recent code is not correct.  
It will fail for  1,  21,  301,  1001,  10001, and an infinite number of other cases.

This checks the tens digit of two digit numbers:
if(n/10==1)   return true 

Open in new window

This checks the tens and hundreds digits of all numbers:
if ((n / 10) % 10 == 1)    return true
if ((n / 100) % 10 == 1)   return true 

Open in new window

But you never check the units digit, you don't check anything higher than the hundreds digit, and you don't use the / operator to trim rightmost digits as the challenge suggested.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778302
public boolean hasOne(int n) {
  if(n%10==1){
  
 // if(n/10==1){
  return true;
 // }
  }
  
  else {
  if( (n/10)%10==1 ){
    return true;
  }
  else {
  if( (n/100)%10==1 ){
    return true;
  }}
  }
  return false;
  
}

Open in new window


Expected      Run            
hasOne(10) → true      true      OK      
hasOne(22) → false      false      OK      
hasOne(220) → false      false      OK      
hasOne(212) → true      true      OK      
hasOne(1) → true      true      OK      
hasOne(9) → false      false      OK      
hasOne(211112) → true      true      OK      
hasOne(121121) → true      true      OK      
hasOne(222222) → false      false      OK      
hasOne(56156) → true      true      OK      
hasOne(56556) → false      false      OK      
other tests
OK

my code passes all test cases in codingbat but looks like it fails other test cases mentioned by you. let me refine my code further
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778308
package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->"+hasOne(21));
		
	}
	
	public static boolean hasOne(int n) {
		  if(n%10==1){
		  
		 // if(n/10==1){
		  return true;
		 // }
		  }
		  
		  else {
		  if( (n/10)%10==1 ){
		    return true;
		  }
		  else {
		  if( (n/100)%10==1 ){
		    return true;
		  }}
		  }
		  return false;
		  
		}


}
[code]

Open in new window

[/code]

my code passed for 21 as well
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778310
Even it passed for 1 also
package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->"+hasOne(1));
		
	}
	
	public static boolean hasOne(int n) {
		  if(n%10==1){
		  
		 // if(n/10==1){
		  return true;
		 // }
		  }
		  
		  else {
		  if( (n/10)%10==1 ){
		    return true;
		  }
		  else {
		  if( (n/100)%10==1 ){
		    return true;
		  }}
		  }
		  return false;
		  
		}


}

Open in new window


value  is-->true
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778315
Even passed for 1001 also
[code]package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->"+hasOne(1001));
		
	}
	
	public static boolean hasOne(int n) {
		  if(n%10==1){
		  
		 // if(n/10==1){
		  return true;
		 // }
		  }
		  
		  else {
		  if( (n/10)%10==1 ){
		    return true;
		  }
		  else {
		  if( (n/100)%10==1 ){
		    return true;
		  }}
		  }
		  return false;
		  
		}


}

Open in new window

[/code]

value  is-->true
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41778363
What is your algorithm, approach, pseudo code?

How do you print out/find only the first/ones digit?
How do you print out/find only the second/tens digit?
How to print out the n digits that make up a number one at a time using the % and / operators?

How do you extend your approach to numbers with arbitrary numbers of digits?
How will you test all digits of a n-digit number like 1234567?
What is you control structure?
You can't do this without a loop, and you don't have one.

Stop trying to fix your code.  It is a mess.  Go back and think about the answers to the questions I have asked.
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41778422
Yeah, try passing your code 10000 and see if that works. (The values Codingbat selected aren't very good!)
0
 
LVL 27

Expert Comment

by:rrz
ID: 41778503
My comment above here was wrong.
The if statement is not the only looping control flow statement.
I meant to post;
The for statement is not the only looping control flow statement.
There is also the while statement. It will come in handy for this challenge.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778779
Yeah, try passing your code 10000 and see if that works. (The values Codingbat selected aren't very good!)

above gives false instead of true(which is wrong)
package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->" + hasOne(10000));

	}

	public static boolean hasOne(int n) {
		if (n % 10 == 1) {

			// if(n/10==1){
			return true;
			// }
		}

		else {
			if ((n / 10) % 10 == 1) {
				return true;
			} else {
				if ((n / 100) % 10 == 1) {
					return true;
				}
			}
		}
		return false;

	}

}

Open in new window


value  is-->false

let me refine my code
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41778796
You need to work on your pseudo code not your code.
You need a control loop to solve this problem.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 7

Author Comment

by:gudii9
ID: 41778800
There is also the while statement. It will come in handy for this challenge.

below passed all tests including 10000
public boolean hasOne(int n) {
  boolean result=false;

		while (n > 0) {
			if ((n % 10) == 1)
				result=true;
			n=(n/10);

		}
		return result;
	}

Open in new window


any improvements or alternate approach for this?
cannot i use for loop for this which i am more habituated with?
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778805
psedo code is
1. loop though given array using while loop until given number greater than zero
2. if reminder of given number modulus 10 is 1 return true
3. else go to next digit by doing / on given number and again check % to see is 1
4. loop till end.
5. return false if no one found as any digiy
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41778810
That took a long time, but it is perfect.  Yes, you can use any kind of loop you want.

The number of digits in an integer n is related to the logarithm of n to the base 10.
You could also assume that n has less than twenty (or some other large number) of digits.
Both of these techniques are less elegant and efficient than the while loop.
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41778818
The for loop isn't going to look or act all that different from the while loop. The one thing I would change is that as soon as you find a 1, you can return true right then and skip the rest of the loop.
1
 
LVL 7

Author Comment

by:gudii9
ID: 41778819
How to write using for loop?
package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->" + hasOne(10000));

	}

	public static boolean hasOne(
			int n) {/*
					 * 
					 * while (n > 0) { if (n % 10 == 1) return true; n=n/10;
					 * 
					 * } return false;
					 */
		// }

		for (int i = n; i>0; i++) {
			if (n % 10 == 1)
				return true;
			n = n / 10;

			return false;
		}
		return false;

	}
}

Open in new window

above give wrong result
value  is-->false
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778823
package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->" + hasOne(10000));

	}

	public static boolean hasOne(
			int n) {/*
					 * 
					 * while (n > 0) { if (n % 10 == 1) return true; n=n/10;
					 * 
					 * } return false;
					 */
		// }

		for (int i = n; i>0; i--) {
			if (n % 10 == 1)
				return true;
			n = n / 10;

			return false;
		}
		return false;

	}
}

Open in new window

value  is-->false

even i-- also give false as above
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41778827
In general, this for loop:

for ( [initialize expression] ; [conditional expression] ; [increment expression] ) {
   [do some work]
}

Open in new window


is exactly equivalent to this code:

[initialize expression]
while ( [conditional expression] ) {
   [do some work]
   [increment expression]
}

Open in new window


In this case, you have no "initialize expression," your "conditional expression" is n > 0, and your "increment expression" is n = n / 10.
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41778828
How do you now when to exit the loop?
How do you know when you have tested the last digit?

How many digits have you tested when you execute line 23?
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41778834
You may be more familiar with the for loop, but there are cases (and this is one of them) where it will result in ugly or inefficient code.

Presumably that is why you are doing these challenges: to learn useful things that you don't already know.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778868
"increment expression" is n = n / 10.
i thought increment expression means i++/i--only
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41778877
In for loops, it doesn't necessarily have to be only an increment or decrement; you can increment, decrement, divide, call Iterator.next(), or all sorts of other things. (I called it the "increment expression" because that's what the tutorial calls it.)
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778896
package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->" + hasOne(10000));

	}

	public static boolean hasOne(
			int n) {/*
					 * 
					 * while (n > 0) { if (n % 10 == 1) return true; n=n/10;
					 * 
					 * } return false;
					 */
		// }
		for (int i=n; i>0;) {
			if (n % 10 == 1)
				return true;
			n = n / 10;

			
		}
		return false;

	}
}
/*In general, this for loop:
for ( [initialize expression] ; [conditional expression] ; [increment expression] ) {
   [do some work]
}
is exactly equivalent to this code:
[initialize expression]
while ( [conditional expression] ) {
   [do some work]
   [increment expression]
}
In this case, you have no "initialize expression," your "conditional expression" is n > 0, and your "increment expression" is n = n / 10.*/

Open in new window


above passed one test
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778899
public boolean hasOne(int n) {
		for (int i=n; i>0;) {
			if (n % 10 == 1)
				return true;
			n = n / 10;

			
		}
		return false;

	}

Open in new window

fails some tests
Expected      Run            
hasOne(10) → true      true      OK      
hasOne(22) → false      Timed out      X      
hasOne(220) → false      Timed out      X      
hasOne(212) → true      Timed out      X      
hasOne(1) → true      Timed out      X      
hasOne(9) → false      Timed out      X      
hasOne(211112) → true      Timed out      X      
hasOne(121121) → true      Timed out      X      
hasOne(222222) → false      Timed out      X      
hasOne(56156) → true      Timed out      X      
hasOne(56556) → false      Timed out      X      
other tests
X      
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41778902
You can't have your conditional expression check i while your increment expression modifies n or your loop will never end. You have to modify the same variable you're checking.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41778917
package com.solution;

public class HasOne {
	public static void main(String[] args) {
		System.out.println("value  is-->" + hasOne(10000));

	}

	public static boolean hasOne(
			int n) {/*
					 * 
					 * while (n > 0) { if (n % 10 == 1) return true; n=n/10;
					 * 
					 * } return false;
					 */
		// }
		for (int n=n; n>0;) {
			if (n % 10 == 1)
				return true;
			n = n / 10;

			
		}
		return false;

	}
}
/*In general, this for loop:
for ( [initialize expression] ; [conditional expression] ; [increment expression] ) {
   [do some work]
}
is exactly equivalent to this code:
[initialize expression]
while ( [conditional expression] ) {
   [do some work]
   [increment expression]
}
In this case, you have no "initialize expression," your "conditional expression" is n > 0, and your "increment expression" is n = n / 10.*/

Open in new window

how to intialize in this case of for loop as while loop do not have intialization?

eclipse gives below error


Multiple markers at this line
      - Duplicate local variable n
      - The assignment to variable n has
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41778927
Either initialize a new variable i and use only that variable inside the loop or just skip the initialize expression entirely. It's optional and n is already initialized, so you don't need it. This pattern, by the way, where you don't need the initialize expression and your increment expression isn't a simple ++ or --, is why d-glitch suggested using a while loop in the first place.
0
 
LVL 27

Expert Comment

by:rrz
ID: 41779029
An interesting fact is the equivalency of
while(true){} loop and   for(;;){} loop .
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41779060
Actually rrz suggested the while loop, although I think we were all aware of the possibility.
The reason you are having trouble with the for loop is because there is no need or reason to use i inside the loop.
There is definitely no reason to set it to n.
One reasonable choice  to set it to the number of digits in n.
0
 
LVL 14

Expert Comment

by:CPColin
ID: 41779095
Oops, you're right. It was rrz. A reason you could want to use i inside the for loop, instead of n, is if your IDE is set to warn you when you change the value of a method parameter. At this point, though, I think we can all agree that the while loop does a better job of indicating what we're trying to do.
0
 
LVL 27

Expert Comment

by:rrz
ID: 41779120
although I think we were all aware of the possibility

Yes, even  CodingBat itself.  
http://codingbat.com/doc/java-for-while-loops.html  
Here are quotes from that page.  
The for-loop is a variant of the while-loop,
The for-loop can actually be understood as equivalent to a while-loop version
0
 
LVL 27

Expert Comment

by:rrz
ID: 41779172
After you  get the for-loop solution posted, we can post the String methods solution and the recursive solution.
0
 
LVL 7

Author Comment

by:gudii9
ID: 41779220
ok
0
 
LVL 7

Author Comment

by:gudii9
ID: 41782325
public boolean hasOne(int n) {/*
					 * 
					 * while (n > 0) { if (n % 10 == 1) return true; n=n/10;
					 * 
					 * } return false;
					 */
		// }
for (; n>0;) {
			if (n % 10 == 1)
				return true;
			n = n / 10;

			
		}
		return false;
	}

Open in new window


here is the for solution which passes all tests. Any improvements to it or alternative solutions to it?
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 41782388
Nope, looks good.  Time to move on.
0
 
LVL 27

Expert Comment

by:rrz
ID: 41782426
I did it a little differently.
public boolean hasOne(int n) {
for(;n > 0; n = n/10){
  if(n % 10 == 1)return true;
}
		return false;
}

Open in new window

  Alternatively, we could use String methods.
public boolean hasOne(int n) {
  String inputString = Integer.toString(n);
  return inputString.contains("1");
}

Open in new window

Just for fun, I wrote a solution using recursion.
public boolean hasOne(int n) {
  if(n <= 0)return false;
  if(n % 10 == 1)return true;
  return hasOne(n/10);
}

Open in new window

1
 
LVL 7

Author Comment

by:gudii9
ID: 41782479
lets say my number is 321.
public boolean hasOne(int n) {
  if(n <= 0)return false;
  if(n % 10 == 1)return true;
  return hasOne(n/10);
}

Open in new window

using above recursion approach below  line

  if(n % 10 == 1)return true;

returns true and method wil be terminated right?
After that how flow comes to below line to call same method again?

 return hasOne(n/10);

Please advise
0
 
LVL 27

Assisted Solution

by:rrz
rrz earned 125 total points
ID: 41782485
returns true and method wil be terminated right?
Yes.
After that how flow comes to below line to call same method again?
It doesn't when input is 321.  
If we put debug statements, then we can see flow.  
public class HasOne{
	public static void main(String[] args){
	    System.out.println(" first test ");
		System.out.println(" input 321 gives output of " + hasOne(321));
		System.out.println(" second test ");
		System.out.println(" input 1234 gives output of " + hasOne(1234));
		System.out.println(" third test ");
		System.out.println(" input 789165432 gives output of " + hasOne(789165432));
	}
	public static boolean hasOne(int n) {
		System.out.println(" input to hasOne method was " + n);
		if(n <= 0)return false;
        if(n % 10 == 1)return true;
        return hasOne(n/10);
    }
}

Open in new window

The output is:
 first test
 input to hasOne method was 321
 input 321 gives output of true
 second test
 input to hasOne method was 1234
 input to hasOne method was 123
 input to hasOne method was 12
 input to hasOne method was 1
 input 1234 gives output of true
 third test
 input to hasOne method was 789165432
 input to hasOne method was 78916543
 input to hasOne method was 7891654
 input to hasOne method was 789165
 input to hasOne method was 78916
 input to hasOne method was 7891
 input 789165432 gives output of true
0
 
LVL 7

Author Comment

by:gudii9
ID: 41783204
public boolean hasOne(int n) {
 while (n > 0) { 
		if (n % 10 == 1)
		 return true;
 n=n/10;
 } 
 return false; 
		 	}

Open in new window


above is technically equivalent to below right


public boolean hasOne(int n) {
 while (n > 0) { 
		if (n % 10 == 1){
		  return true;
                }
n=n/10;
 } 
 return false; 

	}

Open in new window

i meant to say if(condition) statement without  begin { and end } will implicitly cover only next line as its statement right like above not like below


public boolean hasOne(int n) {
 while (n > 0) {
            if (n % 10 == 1){
              return true;
                  n=n/10;
               }
 }
 return false;
                              
             

      }
0
 
LVL 7

Author Comment

by:gudii9
ID: 41783205
public boolean hasOne(int n) {
 while (n > 0) { 
		if (n % 10 == 1){
		  return true;
      n=n/10;
		}
 } 
 return false;
					 
		 

	}

Open in new window


above give error saying

Compile problems:


Error:      n=n/10;
      ^^^^^^
Unreachable code
0
 
LVL 27

Expert Comment

by:rrz
ID: 41783338
i meant to say if(condition) statement without  begin { and end } will implicitly cover only next line as its statement right
Yes.
Unreachable code
You just have to make the compiler happy.
Why not? do it like you did at
https://www.experts-exchange.com/questions/28966679/hasOne-challenge.html#a41778800
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now