This question already has answers here:
How do you get absolute values and square roots
(6 answers)
Check if int is between two numbers
(11 answers)
Closed 1 year ago.
I am new to JAVA, and I have a question about one of the practice assignments.
The question is:
Given an int n, return true if it is within 10 of 100 or 200.
Why do the codes below have errors (bad operand types for binary operator '<=' or '<')?
public boolean nearHundred(int n) {
return (90 <= n <= 110) || (190 <= n <= 210);
}
public boolean nearHundred(int n) {
return (89 < n < 111) || (189 < n < 211);
}
I finally figured out the solution, but I was wondering if there is a better solution for the "absolute" value.
public boolean nearHundred(int n) {
if(n <= 100){
return (100-n)<=10;
}
if (n>=100 && n <= 200){
return (n-100) <=10 || (200-n) <=10;
}
if (n > 200){
return (n-200)<=10;
} else {
return false;
}
}
Thank you very much for your help!
add &&s between your operations so switch return (90 <= n <= 110) || (190 <= n <= 210);
to something like
return (90 <= n && n <= 110) || (190 <= n && n <= 210);
(you can't change operations like that)
Java cannot chain logical operations like a > b > c. You need to use && to connect two parts.
90 <= n && n <= 110 || 190 <= n && n <= 210
"and" is executed before "or", you don't need parenthesis, but you can add them for readability.
(90 <= n && n <= 110) || (190 <= n && n <= 210)
In you case you can also get the absolute value after subtraction:
Math.abs(100 - n) <= 10 || Math.abs(200 - n) <= 10
Alternately you can use Range class from the Guava library:
Range.closed(90, 110).contains(n) || Range.closed(190, 210).contains(n)
Apache Commons Lang has a similar class as well.
You can try Math.abs()
The java.lang.Math.abs(int a) returns the absolute value of an int value
Reference: https://www.tutorialspoint.com/java/lang/math_abs_int.htm
You can use the Range class:
Range<Integer> lowerRange = Range.between(90,110);
Range<Integer> upperRange = Range.between(190,210);
return lowerRange.contains(n) || upperRange.contains(n);
Related
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I wrote in an exam a backtracking code that moving between cell and counting paths, the conditions are if the next cell is i+k or j+k or i-k or j-k.
the code somehow is still going out of bounds even due I tried to prevent it from doing so.
I tried adding fixing the code by adding +1 in the checking valid move in the "if" conditions.
public class Test3
{
public static int howManyPaths(int [][] mat)
{
return howManyPaths(mat,0,0,0);
}
private static int howManyPaths(int [][] mat, int i, int j, int count)
{
if(i == mat.length-1){return count;}
if(j == mat[i].length-1){return howManyPaths(mat,i+1,0,count);}
count = pathCount(mat,i,j);
return howManyPaths(mat,i,j+1,count);
}
private static int pathCount(int [][] mat, int i, int j)
{
int k = mat[i][j];
if(i < mat.length-1 && mat[i][j] == mat[i+k][j] && i+k < mat.length-1){
return 1 + pathCount(mat,i+k,j);}
if(j < mat[i].length-1 && mat[i][j]==mat[i][j+k] && j+k < mat[i].length-1){
return 1 + pathCount(mat,i,j+k);}
if(i > 0 && mat[i][j]==mat[i-k][j] && i-k > 0){
return 1 + pathCount(mat,i-k,j);}
if(j > 0 && mat[i][j]==mat[i][j-k] && j-k > 0){
return 1 + pathCount(mat,i,j-k);}
return 1;
}
}
the expected is how many paths and the actual results are "out of bounds".
Edited with the fixet code still not working
In your code,
if(i < mat.length-1 && mat[i][j] == mat[i+k][j]){
return 1 + pathCount(mat,i+k,j);}
what will it be, if i+k>=mat.length? Or,
if(j < mat[i].length-1 && mat[i][j]==mat[i][j+k]+1){
return 1 + pathCount(mat,i,j+k);
what will it be, if j+k>=mat[i].length? Or,
if(i > 0 && mat[i][j]==mat[i-k][j]){
return 1 + pathCount(mat,i-k,j);}
what will it be, if i-k<0? Or,
if(j > 0 && mat[i][j]==mat[i][j-k]){
return 1 + pathCount(mat,i,j-k);}
what will it be, if j-k<0?
Handle these cases as well. See, being i>0, still i-k can be less than or equal to 0. This is the trick in your case.
Hope you got it now.
Edit:
After you editing your code still it is getting the same exception as you are accessing the indexes and then checking if the index is a valid one.
Not this:
if(i < mat.length-1 && mat[i][j] == mat[i+k][j] && i+k < mat.length-1)
Instead, you must write:
if(i < mat.length-1 && i+k < mat.length-1 && mat[i][j] == mat[i+k][j])
Same for others as well.
By doing this, you will be able to get rid of java.lang.ArrayIndexOutOfBoundsException
I'm doing a hackernet challenge where n is an int input. The conditions are:
If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5, print Not Weird
If n is even and in the inclusive range of 6 to 20, print Weird
If n is even and greater than 20, print Not Weird.
Im sure the code makes logic and dont think theres syntax. It gives the correct responses and hackernet still says its incorrect so ive come here to see if anyone can see what the problem is
public static void main(String[] args)
{
int N = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20)
{
System.out.print("weird");
}
else
{
System.out.print("not weird");
}
}
The problem is the logic in your else condition, which would also catch values of N which are less than 2. Try this version:
if (N % 2 != 0)
{
System.out.print("weird");
}
else if (N >= 2 && N <= 5 || N > 20)
{
System.out.print("not weird");
}
else if (N >= 6 && N <= 20)
{
System.out.print("weird");
}
else
{
// NOTE: if the code still fails, remove this else condition
System.out.print("unexpected value of N");
}
Note: To get your code to pass the Hackernet task, you might have to completely remove the else condition. I added it for completeness, but Hackernet might test N=1 to see if nothing gets printed.
Read this condition :
if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20)
as
if (N % 2 != 0 || (N % 2 == 0 && N >= 6 && N <= 20))
Then see how operator precedence changes the behaviour and yield desired results.
Check the following one
public static void main(String[] args)
{
int N = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if(N%2!=0) {
System.out.print("weird");
}else if(N>=2 && N<=5) {
System.out.print("not weird");
}else if(N>=6 && N<=20) {
System.out.print("weird");
}else if(N>20) {
System.out.print("not weird");
}
}
For the technical part: start by reading about
precedence of java operators and then make your code easier to read.
Pushing that many conditions into a single if is not helpful. You see it yourself: you think the code is correct, but probably it isn't. And now you look to other people to explain your overly complex code back to you. And of course, all the other answers do all that for you ... but beyond that:
The "real" answer here is: learn how to test your code.
Instead of having a main that somehow asks for a number, and then makes decisions, write a method boolean isWeird() that takes a number and returns true/false according to your requirements.
And then simply test that method with all reasonable cases. And then check if that result is as expected.
Using JUnit, you could write something like
assertThat(isWeird(1), true);
assertThat(isWeird(21), true);
assertThat(isWeird(22), true);
...
Ideally, you write such tests before you implement that method. And then you implement all the conditions, and any check that fails tells you that you got something wrong.
I feel, In the if (N % 2 != 0 || N % 2 == 0 && N >= 6 && N <= 20) condition, you are verifiying the odd and even values at same time using && and || operator. Can you modify the condition into like this if (N % 2 != 0 || (N % 2 == 0 && N >= 6 && N <= 20)) and check? If N is odd weird will be printed or if N is even and it falls under the 6 and 20 inclusive, weird will be printed.
You already have a good few answers here but if you think logically about what you actually need, you can break it down easier.
It looks like the only "Not Weird" print out is 2, 4 and even numbers > 20
So an example could be something like:
if (n % 2 == 0) {
if ((n >= 2 && n <= 5) || (n > 20)) {
return "Not Weird";
}
}
return "Weird";
You can try this
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int n = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
if (n % 2 == 1 || (n >= 6 && n <= 20)) {
System.out.println("Weird");
} else {
System.out.println("Not Weird");
}
scanner.close();
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Ok, so I was wondering how can one check whether two numbers have the same digits, e.g. 21 and 12 are ok, also 1233 and 2313, but 123 and 1233 are not, meaning that the digits are permutation of another number's digits.
I know how to do it with arrays or strings or maps, but the problem is, that I don't want to do it with either of those, if there exists another solution.
The solution with arrays / maps:
Map<int, int> counter = new HashMap<int, int>();
for (int i = 0; i < 10; i++)
counter.put(i, 0);
int x = 2421, y = 4223; // testcase
while (x > 0 || y > 0) {
if (x == 0 || y == 0) // if they are not the same length, one will be 0 and thus they are not permutations
return false;
counter.put(x%10, counter.get(x%10) + 1);
counter.put(y%10, counter.get(y%10) - 1);
x /= 10;
y /= 10;
}
// For each digit we added 1 to the counter if it was found in `x`
// and subtract 1 if it was found in `y`.
return counter.values() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
Now, the array approach is completely the same, since using a map for digits 0-9 is the same as using the key for map as the index in array. The solution without any data structure looks far from ideal to me:
private static boolean haveSameDigits(int x, int y) {
// Because we are not allowed to use maps, declare 10 vars...
int c0 = 0;
int c1 = 0;
int c2 = 0;
int c3 = 0;
int c4 = 0;
int c5 = 0;
int c6 = 0;
int c7 = 0;
int c8 = 0;
int c9 = 0;
while (x > 0 || y > 0) {
if (x == 0 || y == 0)
return false;
if ((x % 10) == 0)
c0++;
else if ((x % 10) == 1)
c1++;
else if ((x % 10) == 2)
c2++;
else if ((x % 10) == 3)
c3++;
else if ((x % 10) == 4)
c4++;
else if ((x % 10) == 5)
c5++;
else if ((x % 10) == 6)
c6++;
else if ((x % 10) == 7)
c7++;
else if ((x % 10) == 8)
c8++;
else if ((x % 10) == 9)
c9++;
if ((y % 10) == 0)
c0--;
else if ((y % 10) == 1)
c1--;
else if ((y % 10) == 2)
c2--;
else if ((y % 10) == 3)
c3--;
else if ((y % 10) == 4)
c4--;
else if ((y % 10) == 5)
c5--;
else if ((y % 10) == 6)
c6--;
else if ((y % 10) == 7)
c7--;
else if ((y % 10) == 8)
c8--;
else if ((y % 10) == 9)
c9--;
x /= 10;
y /= 10;
}
return c0 == 0 && c1 == 0 && c2 == 0 && c3 == 0 && c4 == 0 && c5 == 0 && c6 == 0 && c7 == 0 && c8 == 0 && c9 == 0
}
I have googled about it but no matter what I typed I ended up with a solution using strings or arrays.
I am not looking for a solution, I actually don't want it, I just need a hint to the approach.
Adding some more information: There is nothing prohibiting me from using any data structure I want, this is my program and nobody will be checking over what I do. I am just that kind of person that likes to learn new stuff, so I was wondering if there is a quick solution to it.
As stated in the comments, one can iterate over both numbers and check for each number in range (0,9) inclusive, how many times they appear in string but that obviously yields time complexity of O(n*n) which is not optimal.
You do not want to convert to string, or to use any helper data structures. How about this then: Create a hash from the numbers, in the form xor(2^d for every digit d in n)?
For example, hash(3112) will be (in binary) 1100.
Since you do not want a solution, here's some pseudocode (aka Python):
def hash(n):
r = 0
while n > 0:
d = n % 10 # last digit
n = n // 10 # remaining digits
r = r ^ 2**d # xor with 2^d
return r
def perm(n, m):
return hash(n) == hash(m)
Update: Turns out that the above does not work properly, as XOR can only keep track of whether a digit appears an even or odd number of times. Instead, you could create a hash using multiples of prime numbers. This way, hash(3112) becomes 7 * 3 * 3 * 5. While this uses a list to keep the first ten prime numbers, it does not create any new lists, arrays or maps while checking individual pairs of numbers. Also, keep in mind that the resulting hash might get very large -- larger than Java's int or long types. (You can probably take the modulo of another large prime number, but I'm not sure about that part.)
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
def hash(n):
r = 1
while n > 0:
d = n % 10 # last digit
n = n // 10 # remaining digits
r = r * primes[d]
return r
You can parse int's to strings and check with .contains
final List<Integer> intsForCheck = new ArrayList<>();
for (int i = 1; i < 180; i++)
intsForCheck.add(i);
final int num = 17;
intsForCheck.forEach(integer -> check(integer,num));
public static void check(int integer,int num)
{
final String _int = String.valueOf(integer);
final String _num = String.valueOf(num);
System.out.println(_int + (_int.contains(_num) ? " contains" : " not contains") + _num);
}
I'm new to programming
if( (N%2==0) && (6<=N<=20) )
Throws the error below
The operator <= is undefined for the argument type(s) boolean, int
Please help me fix it.
You can't compound the statement like that. You need to && it.
For example,
if ((N % 2 == 0) && (6 <= N && N <= 20)) {...}
The reason you get the error is the first condition of 6 <= N resolves to a boolean and you then attempt to check if a boolean is <= to an int. That does not compute.
You can't compare 2 conditions in one check, you need to split it to two checks
if (N % 2 == 0 && N >= 6 && N <= 20)
You should separate the conditions with logical operators (&& in this case):
if (N % 2 == 0 && N>=6 && N <= 20)
I have an algorithm to test for primality, which uses the naive implementation as listed here http://en.wikipedia.org/wiki/Primality_test#Naive_methods
static boolean check(int n)
{
if(n == 2 || n == 3)
{
return true;
}
if(n < 2 || n % 2 == 0 || n % 3 == 0)
{
return false;
}
for(int i = 6; i * i <= n; i += 6)
{
if(n % (i - 1) == 0 || n % (i + 1) == 0)
{
return false;
}
}
return true;
}
I got all the way to the 6k+1 section, but after that, I'm lost. How else can I further optimize this for speed?
If you want to stick with the naive method, then your next step is to use the next property listed in the wikipedia page you link to:
So all prime numbers are of the form 30k + i for i = 1, 7, 11, 13, 17,
19, 23, 29 (i.e. for i < 30 such that gcd(i,30) = 1).
Except you might pick slightly different / more primes than 2.3.5
You would replace the 6 stepping loop with a 30 stepping loop, (and check with all primes less than 30 by hand )
The code might look like this:
static boolean check(int n)
{
if(n<30)
{
return n==2 || n==3 || n==5 || n==7 || ...
}
for(int i = 30; i * i <= n; i += 30)
{
if (n % (i + 1))==0 return false;
if (n % (i + 7))==0 return false;
if (n % (i + 11))==0 return false;
if (n % (i + 13))==0 return false;
if (n % (i + 17))==0 return false;
if (n % (i + 19))==0 return false;
if (n % (i + 23))==0 return false;
if (n % (i + 29))==0 return false;
}
return true;
}
However you'll note that this scans 8/30 (=27%) numbers, while the 6 stepping loop scans 2/6
(=33%) So it scans about 20% less numbers, so you'd expect a speed up of at best 20%. As you add more primes to the list you get diminishing returns.
Really if you need fast prime checking then you need to move away from the naive methods. And there's been plenty of questions about those on stack overflow previously.