I have a quick question on an assignment I'm trying to finish up. I'm writing a boolean method that takes three digit parameters (0-9) and returns true if they can be re arranged to make up a sequence. The hard part, for me at least, is that 0 can make a sequence with 8, 9, or 1,2. The three numbers are assumed to all be different. To be clear, the number 5,7,6 would be true because it can be rearranged to be 5, 6, 7, a sequence. Also 8,0,9 would return true, but 2,4,7 would not. I'm hoping someone can point me in the right direction with this, any help at all would be much appreciated!
You only need to check the validity of two tests:
Are all numbers different?
Is the absolute difference between the extremes 2?
This would give you the following method:
public static boolean isSequence(int a, int b, int c) {
if(a == 0) a = 10;
if(b == 0) b = 10;
if(c == 0) c = 10;
//Add the commented-out lines to make it safe to use with non-different numbers.
//boolean allDifferent = !(a == b) && !(b == c) && !(a == c);
boolean extremesIsTwo = Math.abs(Math.max(Math.max(a, b), c)
- Math.min(Math.min(a, b), c)) == 2;
//return allDifferent && extremesIsTwo;
return extremesIsTwo;
}
When you look at it, it's only a matter of simple logic, and finding the shortest path to the answer. There might be more optimized ways to do this, but this is clear, readable and works just fine.
Now, if you really want to get grinding on a problem of the like, you could either try to optimize this algorithm, or find another way to check that the three numbers are a sequence.
EDIT This version is scalable. And even though your requirements are for three arguments, I would still consider this solution, because it uses OOP to avoid repetition of code. As requested, it also doesn't check for duplicates.
public static boolean isSequenceScalable(List<Integer> list) {
list = list.stream().map(i -> i = (i == 0) ? 10 : i).collect(Collectors.toList());
list.sort(Integer::compareTo);
if (Math.abs(list.get(0) - list.get(list.size() - 1)) == 2) return true;
return false;
}
Related
I am given with three integers A, B and C. I need to implement a program to perform the operation A^B modulus C.
I without thinking much, wrote the following code:-
public int Mod(int A, int B, int C)
{
return (int)Math.pow(A,B) % C;
}
testcase : A = -1, B = 1, C = 20, the expected o/p was 19 whereas my code gave -1 as output.
I found out that this approach is incorrect when there is a negative number, in this example, when A < 0.
I referred to explanations in few websites, but was unable to understand this behavior.
Please help me on this one. Thank you.
% Operator in Java
In java, when calculating
A % B
the answer is produced according to following conditions:
When the dividend is negative, the answer produced will also be negative and when the dividend is positive, the answer produced will also be positive.
Do note that this behavior is language specific. In python, the above program will produce 19 as output.
Flaw in the code
If one only wants A % B to produce positive results, then simply using A % B will produce wrong output because of reasons mentioned above.
Also, calculating A^B % C where B can take large values directly is not the right approach. I suggest you use fast exponentiation to do so. It is a famous algorithm and you can easily find it online.
Solution
If you want only positive result, use this:
r = a % b > 0 ? a % b : Math.abs(b) + a % b;
Here r is remainder, a is dividend and b is divisor.
I hope I have helped you. If you want to understand why this happens, do comment and I will be happy to edit my answer to help you.
There is no 'modulus' operator in Java; there is a remainder operator.
Negative one to the power one is negative one.
The remainder of dividing negative one by 20 is negative one.
The JLS (link above) specifically says that the sign of the result is the same as the sign of the left-hand side. Thus -1 and not +19.
The definition of % is
The remainder operation for operands that are integers after binary
numeric promotion (ยง5.6.2) produces a result value such that
(a/b)*b+(a%b) is equal to a.
function pow(A,B,C)
{
if(A == 0) {
return 0;
}
else if(B == 0) {
return 1;
}
else if(B%2 == 0) {
let half = this.power(A,Math.floor(B/2),C);
return (half * half)%C;
}
else {
return ((this.power(A,B-1,C)) * A%C)%C;
}
}
import java.util.*;
public class BugFixes
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
altCaps("Computer Science");
}
static void altCaps(String hi)
{
String hi2 = hi;
int locate = 0;
for(int i = 0; i < hi2.length();i++)
{
if((Character.isLetter(hi2.charAt(locate))))
{
if(hi2.charAt(locate) % 2 == 0)
{
System.out.print(hi2.toLowerCase().charAt(locate));
locate++;
}
else if(hi2.charAt(locate) % 2 == 1)
{
System.out.print(hi2.toUpperCase().charAt(locate));
locate++;
}
}
else if(hi2.charAt(locate) == ' ')
{
System.out.print(" ");
locate++;
}
}
}
}
This is one of the problems that I have on my current lab. I was able to fix a few other mistakes but I can't seem to find this one.
My question is why it is outputting "COMpUtER SCIEnCE"? I don't understand what is happening here and I've been looking through it for an hour now. My goal is to output "CoMpUtEr ScIeNcE"
I thought the (hi2.charAt(locate) % 2 == 0) and vice versa would alternate between the even and odd locations in the string, but I believe I have made a mistake somewhere. I just can't find it.
Using BlueJ V3.1.7
1 year high school Computer Science Experience and currently enrolled in AP Computer Science
Any Tips?
not really. So hi2.charAt(locate) % 2 == 0 is actually checking if the integer value of the character is odd or even, but you want to actually check if the index is odd or even if I get you right. In other words:
hi2.charAt(2) % 2 == 0
Is check if m is odd or even. However, I think you want to check if 2 (the index) is odd or even. I guess from here it's easy to assume that you need to change:
if(hi2.charAt(locate) % 2 == 0)
//...
else if(hi2.charAt(locate) % 2 == 1)
//...
to
if(locate % 2 == 0)
//...
else if(locate % 2 == 1)
//...
This won't give you exactly the output you want, but it's just a matter of inverting the if conditions or the body as you wish. Also, there's no other cases for the operation % 2, meaning you'd only get either an odd or even index, so you could simplify the code by just doing:
if(locate % 2 == 0)
//...
else
//...
Which reads better. Hope this helps!
I would strongly advise refactoring your code to reduce repetative calls, and make inspection of values possible (rather than comparison of function evaluation).
For example:
char currentCharacter = hi2.charAt(locate);
would replace four instances of the function call, and allow you to inspect what the actual value is (rather than what you expect the value to be). This would likely make your error more evident.
Assuming the following values:
hi2 = "Computer Science";
locate = 0;
then it may be worth stepping through the evaluation.
0. hi2.charAt(locate) % 2 == 0
1. "Computer Science".charAt(0) % 2 == 0
2. 'C' % 2 == 0
3. 67 % 2 == 0
4. 1 == 0
5. false
The fundamental problem is that by never assigning your value to a variable, you never take the time to understand what is in it. By assigning it to the variable, you are able to inspect the value using a debugger.
By inspecting the values, we can see that you probably want the mod of 0, not 'C', therefore you probably wanted
0. locate % 2 == 0
1. 0 % 2 == 0
2. 0 == 0
3. true
Bonus
Refactoring your code to reduce repetition, would also highlight other errors. For example, try the following:
assert "CoMpUtEr sCiEnCe".equals(BugFixes.altcaps("Computer Science"));
assert "CoMpUtEr-sCiEnCe 201".equals(BugFixes.altcaps("Computer-Science 201"));
KISS: removal of needless logic would reduce the chance of things going wrong.
For starters, you don't need to reassign the string, or the locate variable, or check if a character is already a character. Just use the iteration integer, if you need it, and the parameter.
Secondly, you're modding the character, not the position.
Anyways, a simple boolean toggle would be easier to understand than modding.
void altCaps(String hi) {
boolean caps = true;
for (char ch : hi.toCharArray()) {
if (ch == ' ') {
System.out.print(ch);
}
else if (Character.isLetter(ch)) {
if (caps) System.out.print(Character.toUpperCase(ch));
else System.out.print(Character.toLowerCase(ch));
caps = !caps; // switch between upper and lower every character
}
Is there a way of using OR in java without repeating the variable in the condition:
For example
if(x != 5 || x != 10 || x != 15)
instead use something like
if x not in [5,10,15]
You can take advantage of short-circuit terminal operations in Java8 streams (See the Stream Operations section in the Stream Package Description for details.) For example:
int x = 2;
// OR operator
boolean bool1 = Stream.of(5, 10, 15).anyMatch(i -> i == x);
System.out.println("Bool1: " +bool1);
// AND operator
boolean bool2 = Stream.of(5, 10, 15).allMatch(i -> i != x);
System.out.println("Bool2: " +bool2);
It produces the following output:
Bool1: false
Bool2: true
Your second example is just storing elements in an array and checking for existence, no need for OR in that case.
If you want to go that route, store your elements in a List<Integer> and use contains(Object o)
if(!myList.contains(x))
if you want to exclude all multiply of 5, you can try this
if(x % 5 != 0)
Here a solution that comes with much less performance overhead than the ones using Streams or a HashMap:
Store the values you want to check against in an array and write a small function to check whether x is among these values
private static boolean isNotIn(int x, int[] values) {
for (int i : values) {
if (i == x) {
return false;
}
}
return true;
}
if (isNotIn(x, new int[] {5, 10, 15})) {
...
}
The overhead is minimal compared to the original code and becomes negligible if you can pull out the array as a constant.
I also find that it is nicer to read than the other solutions but that is a very subjective opinion ;-)
In a particular if-else, I have to identify if a given value falls within a range. The condition part looks like this:
else if (a==2 && b.equalsIgnoreCase("line")
&& <<Here I need to search if c falls within a range>> && d)
where a is int, b is string, c is int and d is a boolean. Now if c falls within 1 to 8, the condition is true, else it is false. How can I do that?
I think you need you this condition for c
(c > 1 && c < 8) // 1 and 8 are exclusive
(c => 1 && c <= 8) // 1 and 8 are inclusive
Full sample
else if (a==2 && b.equalsIgnoreCase("line")
&& (c > 1 && c < 8) && d)
If you need to check if the values belongs to a set of values, you need to use a Set and then check if the c belongs to that or not. In your original question, it was mentioned as a range and thus the answer. Anyways, this is how you can check a value in a set.
Integer[] arr = {1,4,9,11,13};
Set<Integer> set = new HashSet<>(Arrays.asList(arr));
...
else if (a==2 && b.equalsIgnoreCase("line")
&& (set.contains(c)) && d)
Surprise surprise, it is c >= low && c <= high
To answer to the update, you'll need to employ a set
Set<Integer> validValues = new HashSet<Integer>();
validValues.add(1);
validValues.add(4);
validValues.add(9);
validValues.add(10);
validValues.add(19);
if (validValues.contains(currentVal)) {
// do stuff
}
To curb java's verbosity you may use Guava's immutable set:
Set<Integer> validValues = ImmutableSet.of(1, 4, 9, 10, 19);
Try like this, range1 and range2 are ranges from which you need to check b.
(c < range1 && c > range2) ? d=true : d=false;
You simply need to add:
c > 1 && c < 8
If you ever feel that your conditionals are getting too complicated I'd suggest creating Boolean methods that simplify them down a little. This is a very moderate case, but for example this range problem could be represented by:
public boolean inRange(int num)
{
return (num > 1 && num < 8);
}
Unfortunately, the only way to do it would be using if else statements (as far as I know). A switch statement does not accept conditional operators, and so would not work for that. As suggested by some others, you could use seperate methods, as the methods, would allow you to check if other values were in range as well. Instead of just for this value, however, you could go for something like
public Boolean inRange(int num, int lowBound, int topBound)
{
return (num > lowBound && num < topBound);
}
and just use it in your code like this
else if (a==2 && b.equalsIgnoreCase("line")
&& inBound(c, 1, 8) && d)
It does not look too messy, and will work (you'll need to decide whether it is inclusive or exclusive bounds though).
The reason for the changed method is that it could be used in other places as well, making it useful for range checking.
im studying for my final exam from the text book. I need an answer for this question since i couldn't solve it.
1)Write a recursive definition of the function multiply(int a, int b) that takes two integers and return the result of their multiplication.
I answered:
Multiply(a, b) :
0 - if a or b is equal to zero. (I got -1 here. Reason written: only 1)
a * b - (I didn't know what to write here)
2)
Write a recursive method that takes a linked list of integers and returns the sum of it's elements.
My solution was:
int sumList(Node<Integer> list) {
int temp = list.getInfo();
if(temp == null) {
return 0;
} else {
return temp + sumList(temp.getNext);
}
}
I fixed it, i think:
public int sumList(Node<Integer> list) {
Node<Integer> temp = list;
if(temp == null) {
return 0;
} else {
return temp.getInfo() + sumList(temp.getNext());
}
}
Is the solution for question 2 right?
Since this is for exam preparation, I don't want to give you the code for doing this. Instead I will give you some ideas.
For the question no 1. Since multiplication is repeated summation, you can use that as the base for recursion here.
If you want to find 3 * 4, use recursion to calculate and return 4 + 4 + 4.
In other words, you can see a pattern emerge below.
4 * 3 = 4 + (4 * 2)
4 * 3 = 4 + 4 + (4 * 1)
To get a working recursive solution you need a base case, for example a == 0, and then work yourself down towards the base case by recursively calling yourself.
The solution for question 1 could be something along the lines of this, that decreases the a argument until it reaches 0:
int multiply(int a, int b) {
if (a == 0 || b == 0) {
return 0;
}
return b + multiply(a - 1, b);
}
For example, multiply(2, 5) would become 5 + multiply(1, 5) -> 5 + 5 + multiply(0, 5) -> 5 + 5 + 0.
Note that this particular solution doesn't work for negative numbers, but you get the idea. You should be able to easily add support for that yourself.
A) well, you really need to reread that chapter on recursion.
The mathematical principle is this:
http://en.wikipedia.org/wiki/Mathematical_induction
and the Wikipedia article will step you through a much more complicated task.
B) No, it won't compile at all. There are multiple syntax errors.
Try using a Java compiler for excersising your programming skills.