I currently have following code:
int[][] legalForBlack = {{0,1},{1,0},{2,3},{3,2}};
for (int x=0;x<boardSize;x++) {
for (int y=0;y<boardSize;y++) {
if (x,y) in legalForBlack
methodA()
else
methodB()
}
}
Of course this code won't compile. I am looking for a fancy and compact way to check when (x,y) are in the given list.
I can do this with 4 if-statements or a loop, but this is not a proper way imo.
I am looking for something that does this in constant time.
EDIT:
I think I found a way. What do you think of this?
int[][] legalForBlack = {{0,1},{1,0},{2,3},{3,2}}; // keep in order!
int cur = 0;
for (int x=0;x<boardSize;x++) {
for (int y=0;y<boardSize;y++) {
int[] buffer = legalForBlack[cur];
if (x==buffer[0] && y==buffer[1]) {
cur++;
methodA();
} else {
methodB();
}
}
}
Heres pseudocode for arrays:
input data in array
find x with for to match first column (legalForBlack[i][0])
if x matches legalForBlack[i][0] check if legalForBlack[i][1] matches y
if yes, count it
But there is a better way, when you just want to check if they are in array. Create object Pair with variable x and y, create equals() and hashCode() functions to have unique for each pair (like get hashCode from string xy), place all inputs in Set and then check if given Pair(x,y) is in Set.
boolean isLegal = false;
for(int[] coord: legalForBlack)
if(Arrays.equals(coord, someXYArray)) {
isLegal = true;
break; //Credit to Adnan Isajbegovic
}
if(isLegal)
methodA();
else
methodB();
I have an alternative solution for your question. Judging from your code, I assume that you are writing something chess-related and your list of legalForBlack is a series of coordinates that the player is allowed to move to. Best way IMO would be to code each square on the board with an index (0 to maximum 63) and store all of these in a Map of type <Integer, Coordinate>, where Coordinate has int x and int y. If you don't have any particular use for the coordinates, you can also skip and convert your Map to a simple Array of allowed-squares. This would only require you to check whether a given value is in your allowed-square list. I hope this gives you a better approach to your problem. Good luck!
Related
I have the method below that gets a two-dimensional array and a value. The method check if the value be in the array or not.
I don't understand why do I need the line of code that I highlighted in bold (if (m[i][m[i].length-1] <= val).
It Looks that the code works without this line as well... Why do I still need this line, can someone explain me please? thanks
public static boolean findValWhat (int[][] m, int val)
{
for (int i = 0; i < m.length; i++) {
**if (m[i][m[i].length-1] <= val){**
if (binarySearch(m[i], val) == val){
return true;
}
}
}
return false;
}
The code will still work without it but is makeing it run faster.
Lets say you have this sorted 2d array:
[[1,2,3],[4,5,6],[7,8,9]]
Then you can see that if you are searching for 8 you don't need to do binary search for the first line because 3 is smaller then 8 and he is the biggest number in there.
You can even make this code batter by doing binary search instead of the loop.
Say, I'm making a simple badugi card game where the Hand is represented by 10 characters in a string. E.g:
2s3h5dQs - 2 of spades, 3 of hearts, 5 of diamonds, Queen of spades
Now, in this badugi card game I want to create two loops where the first loop checks if all the ranks are different(none of them can be the same) and the other loop checks if all the suits are different. If both of these conditions return as true where they all have different ranks and suits, the hand has drawn a badugi(please excuse my lack of terminology where necessary.)
Now, how can I create an efficient loop for such a situation? I was thinking that I could create several if statements as such:
if (hand.charAt(0) != hand.charAt(2) && hand.charAt(0) != hand.charAt(4) && hand.charAt(0) != hand.charAt(6))
if (hand.charAt(2) != hand.charAt(0) && hand.charAt(2) != hand.charAt(4) && hand.charAt(2) != hand.charAt(6))
... and so forth comparing every single index to one another. But this gets tedious and seems very unprofessional. So my question is, how do I write an efficient loop for this scenario? How can I compare/check if there are no matches at these specific index points to one another?
If I haven't explained properly then please let me know.
Please keep in mind, I am not allowed freedom of how to formulate a hand. It has to be in the format above
You are putting your energy into the wrong place.
You do not need to worry about efficiency at all.
Instead, you should worry about creating a clean design (based on reasonable abstractions) and then write code that is super-easy to read and understand.
And your current approach fails both of those ideas; unfortunately completely.
In other words: you do not represent hands and values as characters within a String.
You create a class that abstracts a Card (with its value and face).
And then a "hand" becomes a List / array of such Card objects. And then you can use concepts such as Comparator to compare card values, or you can make use of equals() ...
And even when you wish to keep your (actually over-complex) naive, simple approach of using chars within a string; then you should at least use some kind of looping so that you don't compare charAt(0) against charAt(2); but maybe charAt(i) against charAt(j).
And following your edit and the excellent comment by jsheeran: even when you are forced to deal with this kind of "string notation"; you could still write reasonable code ... that takes such string as input, but transforms them into something that makes more sense.
For example, the Card class constructor could take two chars for suite/value.
But to get you going with your actual question; you could something like:
public boolean isCardDistinctFromAllOtherCards(int indexToCheck) {
for (int i=0; i<cardString.length-1; i+=2) {
if (i == indexToCheck) {
continue;
}
if (cardString.charAt(indexToCheck) == cardString.charAt(i)) {
return false;
}
}
return true;
}
( the above is just an idea how to write down a method that checks that all chars at 0, 2, 4, ... are not matching some index x).
You should really think about your design, like creating Card class etc., but back to the question now, since it's not gonna solve it.
I suggest adding all 4 values to a Set and then checking if size of the Set is 4. You can even shortcut it and while adding this yourSet.add(element) return false then it means there is already that element in the set and they are not unique. That hardly matters here since you only need to add 4 elements, but it may be useful in the future if you work with more elements.
I would advice creating an array with these chars you are referencing just to clean up the fact you are using indices. i.e create a vals array and a suits array.
This would be my suggestion by using a return or break the loop will stop this means when a match is found it wont have to loop through the rest of the elements .. Hope this helps !
private static int check(char[] vals, char[] suits){
int flag;
for(int i=0; i<=vals.length-2;i++){
for(int k=vals.length-1; k<=0;k++){
if(vals[i]==vals[k]){
flag=-1;
return flag;
}
if(suits[i]==suits[k]){
flag=1;
return flag;
}
}
}
return 0;
}
Why not simply iterate over your string and check for same ranks or suits:
public class NewClass {
public static void main(String[] args) {
System.out.println(checkRanks("2s3h5dQs"));
System.out.println(checkSuits("2s3h5dQs"));
}
public static boolean checkRanks(String hand){
List<Character> list = new ArrayList<>();
for (int i = 0; i< hand.length(); i+=2){
if (!list.contains(hand.charAt(i))){
list.add(hand.charAt(i));
}
else{
return false;
}
}
return true;
}
public static boolean checkSuits(String hand){
List<Character> list = new ArrayList<>();
for (int i = 1; i< hand.length(); i+=2){
if (!list.contains(hand.charAt(i))){
list.add(hand.charAt(i));
}
else{
return false;
}
}
return true;
}
}
I have created a gameboard (5x5) and I now want to decide when a move is legal as fast as possible. For example a piece at (0,0) wants to go to (1,1), is that legal? First I tried to find this out with computations but that seemed bothersome. I would like to hard-code the possible moves based on a position on the board and then iterate through all the possible moves to see if they match the destinations of the piece. I have problems getting this on paper. This is what I would like:
//game piece is at 0,0 now, decide if 1,1 is legal
Point destination = new Point(1,1);
destination.findIn(legalMoves[0][0]);
The first problem I face is that I don't know how to put a list of possible moves in an array at for example index [0][0]. This must be fairly obvious but I am stuck at this for some time. I would like to create an array in which there is a list of Point objects. So in semi-code: legalMoves[0][0] = {Point(1,1),Point(0,1),Point(1,0)}
I am not sure if this is efficient but it makes logically move sense than maybe [[1,1],[0,1],[1,0]] but I am not sold on this.
The second problem I have is that instead of creating the object at every start of the game with an instance variable legalMoves, I would rather have it read from disk. I think that it should be quicker this way? Is the serializable class the way to go?
My 3rd small problem is that for the 25 positions the legal moves are unbalanced. Some have 8 possible legal moves, others have 3. Maybe this is not a problem at all.
You are looking for a structure that will give you the candidate for a given point, i.e. Point -> List<Point>.
Typically, I would go for a Map<Point, List<Point>>.
You can initialise this structure statically at program start or dynamically when needing. For instance, here I use 2 helpers arrays that contains the possible translations from a point, and these will yield the neighbours of the point.
// (-1 1) (0 1) (1 1)
// (-1 0) (----) (1 0)
// (-1 -1) (0 -1) (1 -1)
// from (1 0) anti-clockwise:
static int[] xOffset = {1,1,0,-1,-1,-1,0,1};
static int[] yOffset = {0,1,1,1,0,-1,-1,-1};
The following Map contains the actual neighbours for a Point with a function that compute, store and return these neighbours. You can choose to initialise all neighbours in one pass, but given the small numbers, I would not think this a problem performance wise.
static Map<Point, List<Point>> neighbours = new HashMap<>();
static List<Point> getNeighbours(Point a) {
List<Point> nb = neighbours.get(a);
if (nb == null) {
nb = new ArrayList<>(xOffset.length); // size the list
for (int i=0; i < xOffset.length; i++) {
int x = a.getX() + xOffset[i];
int y = a.getY() + yOffset[i];
if (x>=0 && y>=0 && x < 5 && y < 5) {
nb.add(new Point(x, y));
}
}
neighbours.put(a, nb);
}
return nb;
}
Now checking a legal move is a matter of finding the point in the neighbours:
static boolean isLegalMove(Point from, Point to) {
boolean legal = false;
for (Point p : getNeighbours(from)) {
if (p.equals(to)) {
legal = true;
break;
}
}
return legal;
}
Note: the class Point must define equals() and hashCode() for the map to behave as expected.
The first problem I face is that I don't know how to put a list of possible moves in an array at for example index [0][0]
Since the board is 2D, and the number of legal moves could generally be more than one, you would end up with a 3D data structure:
Point legalMoves[][][] = new legalMoves[5][5][];
legalMoves[0][0] = new Point[] {Point(1,1),Point(0,1),Point(1,0)};
instead of creating the object at every start of the game with an instance variable legalMoves, I would rather have it read from disk. I think that it should be quicker this way? Is the serializable class the way to go?
This cannot be answered without profiling. I cannot imagine that computing legal moves of any kind for a 5x5 board could be so intense computationally as to justify any kind of additional I/O operation.
for the 25 positions the legal moves are unbalanced. Some have 8 possible legal moves, others have 3. Maybe this is not a problem at all.
This can be handled nicely with a 3D "jagged array" described above, so it is not a problem at all.
Basically this is what I have:
if(field1.getText().equals("")){
label2.setForeground(Color.red);
label2.setText("Please enter a pet type");
}
else if(field1.getText().equals(petList.get(z)){
label2.setForeground(Color.red);
label2.setText("The pet type already exists");
}
else{
label2.setForeground(Color.red);
label2.setText("Pet Type Added");
String input = field1.getText();
petList.add(j,input);
j++;
}
What I need to do is check field1 to see if it equals any of the elements in the vector petList. How can I accomplish this? I have already tried using a for loop on the outside of the if loop like this :for(int z = 0; z < petList.size(); z++){ but it returned an array index out of range error. Any help would be awesome! I would prefer to do it using the same basic structure that I have now, but if it can't be done that's ok. This code is inside of a buttonlistener class, if that helps.
Did you look at the contains method in Vector. petList.contains(field1.getText())
Without revealing the solution (and thereby not giving you the chance to develop your skills) here is a tip!
You could use a for-each loop.
http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html
And for every iteration check if the element at the current location in the array equals the users input.
Good luck!
Replace this
if(field1.getText().equals(""))
with
if (contains(vect, field1.getText()))
and put the following method:
private static boolean contains(Vector v, String s) {
for (int i = 0; i < v.size(); ++i) {
if (s.equals((String) v.elementAt(i))) {
return true;
}
}
return false;
}
If my guess is correct, you are getting array index out of range error in line petList.add(j,input); Instead of specifying the index, why dont you add this input after the for loop using petList.add(input);
I have a function that is recursively calling itself, and i want to detect and terminate if goes into an infinite loop, i.e - getting called for the same problem again. What is the easiest way to do that?
EDIT: This is the function, and it will get called recursively with different values of x and y. i want to terminate if in a recursive call, the value of the pair (x,y) is repeated.
int fromPos(int [] arr, int x, int y)
One way is to pass a depth variable from one call to the next, incrementing it each time your function calls itself. Check that depth doesn't grow larger than some particular threshold. Example:
int fromPos(int [] arr, int x, int y)
{
return fromPos(arr, x, y, 0);
}
int fromPos(int [] arr, int x, int y, int depth)
{
assert(depth < 10000);
// Do stuff
if (condition)
return fromPos(arr, x+1, y+1, depth + 1);
else
return 0;
}
If the function is purely functional, i.e. it has no state or side effects, then you could keep a Set of the arguments (edit: seeing your edit, you would keep a Set of pairs of (x,y) ) that it has been called with, and every time just check if the current argument is in the set. That way, you can detect a cycle if you run into it pretty quickly. But if the argument space is big and it takes a long time to get to a repeat, you may run out of your memory before you detect a cycle. In general, of course, you can't do it because this is the halting problem.
You will need to find a work-around, because as you've asked it, there is no general solution. See the Halting problem for more info.
An easy way would be to implement one of the following:
Pass the previous value and the new value to the recursive call and make your first step a check to see if they're the same - this is possibly your recursive case.
Pass a variable to indicate the number of times the function has been called, and arbitrarily limit the number of times it can be called.
You can only detect the most trivial ones using program analysis. The best you can do is to add guards in your particular circumstance and pass a depth level context. It is nearly impossible to detect the general case and differentiate legitimate use of recursive algorithms.
You can either use overloading for a consistent signature (this is the better method), or you can use a static variable:
int someFunc(int foo)
{
static recursionDepth = 0;
recursionDepth++;
if (recursionDepth > 10000)
{
recurisonDepth = 0;
return -1;
}
if (foo < 1000)
someFunc(foo + 3);
recursionDepth = 0;
return foo;
}
John Kugelman's answer with overloading is better beacuse it's thread safe, while static variables are not.
Billy3
Looks like you might be working on a 2D array. If you've got an extra bit to spare in the values of the array, you can use it as a flag. Check it, and terminate the recursion if the flag has been set. Then set it before continuing on.
If you don't have a bit to spare in the values, you can always make it an array of objects instead.
If you want to keep your method signature, you could keep a couple of sets to record old values of x and y.
static Set<Integer> xs;
static Set<Integer> ys;//Initialize this!
static int n=0;//keeps the count function calls.
int fromPos(int [] arr, int x, int y){
int newX= getX(x);
int newY= getY(y);
n++;
if ((!xs.add(Integer.valueOf(newX)) && !ys.add(Integer.valueOf(newY))){
assert(n<threshold); //threshold defined elsewhere.
fromPos(arr,newx,newy);
}
}
IMHO Only loops can go into an infinite loop.
If your method has too many level of recursion the JVM will throw a StackOverflowError. You can trap this error with a try/catch block and do whatever you plan to do when this condition occurs.
A recursive function terminates in case a condition is fulfilled.
Examples:
The result of a function is 0 or is 1
The maximum number of calls is reached
The result is lower/greater than the input value
In your case the condition is ([x0,y0] == [xN,yN]) OR ([x1,y1] == [xN,yN]) OR ([xN-1,yN-1] == [xN,yN])
0, 1, ...N are the indexes of the pairs
Thus you need a container(vector, list, map) to store all previous pairs and compare them to the current pair.
First use mvn findbugs:gui to open a gui which point to the line where this error is present.
I also faced the same problem and I solved it by adding a boolean variable in the loop verification.
Code before ->
for (local = 0; local < heightOfDiv; local = local + 200) { // Line under Error
tileInfo = appender.append(tileInfo).append(local).toString();
while (true) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
}
}
To Solve this problem, I just added a boolean variable and set it to false in the catch block. Check it down
for (local = 0; local < heightOfDiv; local = local + 200) {
tileInfo = appender.append(tileInfo).append(local).toString();
boolean terminationStatus = true;
while (terminationStatus) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
terminationStatus = false;
}
}
This is how i Solved this problem.
Hope this will help. :)