gudii9
asked on
hasOne challenge
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
I am not passing all tests
How to improve/modify my design, code and any other alternate approaches. please advise
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;
}
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
SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
The challenge description gives you a hint.
Print out values for n%10 and n/10 for several values of n.
How do the answers relate to n.
How do the answers relate to n.
Is it cheating to use String method? I remember krakatoa showed you how to do it on other challenges in the past.
The challenge specifically said to use % and / .
What are 13345/10 and 12345%10 ?
ASKER
13345/10 is 1334
and 12345%10 is 5
and 12345%10 is 5
ASKER
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
ASKER
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?
12345%10 is 5
12345/10 is 1234
The answer is there if you think about it.
ASKER
i have to loop through each digit and check if it is one or not by doing both % and / ?
What does the Challenge say about using the / operator?
ASKER
/ to discard the rightmost digit.
ASKER
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;
}
above pased all tests. any improvements or alternate approaches?
After the discard, there is a new rightmost digit to check.
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.
Like 12345
If n is a five digit number, then you have to do five tests.
The if statement is not the only looping control flow statement.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
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:
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
This checks the tens and hundreds digits of all numbers:
if ((n / 10) % 10 == 1) return true
if ((n / 100) % 10 == 1) return true
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.
ASKER
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;
}
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
ASKER
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]
[/code]my code passed for 21 as well
ASKER
Even it passed for 1 also
value is-->true
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;
}
}
value is-->true
ASKER
Even passed for 1001 also
value is-->true
[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;
}
}
[/code]value is-->true
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.
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.
Yeah, try passing your code 10000 and see if that works. (The values Codingbat selected aren't very good!)
My comment above here was wrong.
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.
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.
ASKER
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;
}
}
value is-->false
let me refine my code
You need to work on your pseudo code not your code.
You need a control loop to solve this problem.
You need a control loop to solve this problem.
ASKER
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;
}
any improvements or alternate approach for this?
cannot i use for loop for this which i am more habituated with?
ASKER
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
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
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.
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.
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.
ASKER
How to write using for loop?
value is-->false
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;
}
}
above give wrong resultvalue is-->false
ASKER
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;
}
}
value is-->falseeven i-- also give false as above
In general, this for loop:
is exactly equivalent to this code:
In this case, you have no "initialize expression," your "conditional expression" is n > 0, and your "increment expression" is n = n / 10.
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.
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?
How do you know when you have tested the last digit?
How many digits have you tested when you execute line 23?
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.
Presumably that is why you are doing these challenges: to learn useful things that you don't already know.
ASKER
"increment expression" is n = n / 10.i thought increment expression means i++/i--only
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.)
ASKER
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.*/
above passed one test
ASKER
public boolean hasOne(int n) {
for (int i=n; i>0;) {
if (n % 10 == 1)
return true;
n = n / 10;
}
return false;
}
fails some testsExpected 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
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.
ASKER
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.*/
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
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.
An interesting fact is the equivalency of
while(true){} loop and for(;;){} loop .
while(true){} loop and for(;;){} loop .
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.
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.
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.
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
After you get the for-loop solution posted, we can post the String methods solution and the recursive solution.
ASKER
ok
ASKER
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;
}
here is the for solution which passes all tests. Any improvements to it or alternative solutions to it?
Nope, looks good. Time to move on.
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;
}
Alternatively, we could use String methods.
public boolean hasOne(int n) {
String inputString = Integer.toString(n);
return inputString.contains("1");
}
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);
}
ASKER
lets say my number is 321.
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
public boolean hasOne(int n) {
if(n <= 0)return false;
if(n % 10 == 1)return true;
return hasOne(n/10);
}
using above recursion approach below lineif(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
SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
public boolean hasOne(int n) {
while (n > 0) {
if (n % 10 == 1)
return true;
n=n/10;
}
return false;
}
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;
}
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 belowpublic boolean hasOne(int n) {
while (n > 0) {
if (n % 10 == 1){
return true;
n=n/10;
}
}
return false;
}
ASKER
public boolean hasOne(int n) {
while (n > 0) {
if (n % 10 == 1){
return true;
n=n/10;
}
}
return false;
}
above give error saying
Compile problems:
Error: n=n/10;
^^^^^^
Unreachable code
i meant to say if(condition) statement without begin { and end } will implicitly cover only next line as its statement rightYes.
Unreachable codeYou 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?anchorAnswerId=41778800#a41778800
ASKER