Searching a matrix for a chain of sums - java

I'm still trying to improve on my coding skills, and this question has got me spinning in my tracks a little bit, so any help is greatly appreciated. I know how to create the random array very easily, no problem with that. However, the logic of finding the chain is proving very difficult for me. I believe the proper approach is some sort of depth first searching algorithm, but I'm not entirely sure of how to implement that in this scenario, or whether that is even correct.
My basic question is, should I be using depth first search, and if so, should I be doing it recursively? Any tips or hints on implementation are also welcome!
Make a program that creates a 3x3 grid of random
positive numbers where 0 <= n <= 9. The program should
find all possible combinations of numbers that add up to the area of
the grid, or 9, using these rules (similar to Boggle):
a. The numbers must be "chained" in sequentially adjacent cells, where
"adjacent" cells are those horizontally, vertically, and diagonally
neighboring
b. The chain does not have to be in a line. For example, it could go
horizontally once, then vertically once, and finally diagonally once
c. At least the “grid width - 1” cells must be used in the chain (a
3x3 grid means that at least two cells must be used)
d. A chain cannot repeat a grid cell that it has already used
e. Chains that use the exact same cells as a previous chain are
considered repeats and should not be counted
I know that for each element, when you are searching through each adjacent element, you must check and keep track of whether it's been visited before, so you don't repeat numbers.
public class GridSolver {
int[][] workingGrid;
public GridSolver(int[][] workingGrid){
this.workingGrid = workingGrid;
}
public String solve(){
int length = this.workingGrid.length;
boolean[][] visited = new boolean[length][length];
for(int rows=0; rows<length; rows++){
for(int columns=0; columns<length; columns++){
if(visited[rows][columns] == false){
dfs(workingGrid[rows][columns]);
}
}
}
return null;
}
public HashSet<ArrayList<Integer>> dfs(int element){
HashSet<ArrayList<Integer>> chains = new HashSet<>();
checkLeft();
checkTopLeft();
checkTopMiddle();
checkTopRight();
checkRight();
checkBottomRight();
checkBottomMiddle();
checkBottomLeft();
return null;
}}
This is what I have so far and I realize that it is pretty sloppy and not the best thought out scheme, but that's why I'm here I guess :P.
Also just to explain some of my thinking in the code, the dfs()method has a return type of HashSet because I know that you can't have duplicate chains, and it is a set of a list of the chains. Also the "check" methods are not implemented, I just wrote them down because I know that you will need to process each of these adjacent blocks for each number.
Once again, any help is greatly appreciated, and thank you for humoring me as a beginner here!

Related

How to increase total positions considered for a chess engine

I'm writing a chess engine in Java and using bitboards to represent the board (12 64-bit numbers). The size of an instance of this class(its retained size) is 152Bytes according to IntelliJ debugger.
When trying to see a few moves a head, for each move I consider I create a new instance to represent the new Board state. Below is what the Board class looks like approximately.
public long WP=0L, WN=0L, WB=0L, WR=0L, WQ=0L, WK=0L, BP=0L, BN=0L, BB=0L, BR=0L, BQ=0L, BK=0L;
long NOT_WHITE_PIECES;
long WHITE_PIECES;
long BLACK_PIECES;
long OCCUPIED;
long EMPTY;
public void updateBitboards() {}
public void updateMailbox() {}
public void movePiece(Move move) {}
public void drawBitboard() {}
Other fields and methods are static so I don't think they affect the size of an instance.
The problem is, even if I want to consider only the first 4 moves in chess, there's ~8,000,000 possible combination of moves. So I'm going to end up storing a total of 8,000,000*152B = 1,216,000,000B... which is 1.2GB.
I feel like I'm missing something here. How can I increase the number of positions I consider at a time?
First, you don't want to create a new instance of the board state each move. If you are using e.g. Minimax then you make the move, make recursive call, then unmake the move. This way you always just have one board state which it considers.
Then to minimize the number of moves you need to consider you want to make enhancements to the algorithm. The most common to start with is alpha-beta pruning which you can read more about here: https://www.chessprogramming.org/Alpha-Beta. Alpha beta pruning will always yield the same result as a minimax, but you consider less positions since you don't search the hopeless ones.
Then there are tons of other pruning techniques that you can do to reduce the search tree. Most of these will not yield the same result since you "manually" choose to cut off certain positions that you "think" is going to be bad. This could be things like the assumption that there is always better to do something than nothing (null move pruning).
Other easy things you can do to speed up algorithm is to look at move ordering. To make Minimax most efficient you always want to look at the best move first in each position. That way you will get more cutoffs and not search as many moves. Everything you need to know about chess programming you can find at https://www.chessprogramming.org/.

Efficient way for checking if a string is present in an array of strings [duplicate]

This question already has answers here:
How do I determine whether an array contains a particular value in Java?
(30 answers)
Closed 2 years ago.
I'm working on a little project in java, and I want to make my algorithm more efficient.
What I'm trying to do is check if a given string is present in an array of strings.
The thing is, I know a few ways to check if a string is present in an array of strings, but the array I am working with is pretty big (around 90,000 strings) and I am looking for a way to make the search more efficient, and the only ways I know are linear search based, which is not good for an array of this magnitude.
Edit: So I tried implementing the advices that were given to me, but the code i wrote accordingly is not working properly, would love to hear your thoughts.`
public static int binaryStringSearch(String[] strArr, String str) {
int low = 0;
int high = strArr.length -1;
int result = -1;
while (low <= high) {
int mid = (low + high) / 2;
if (strArr[mid].equals(str)) {
result = mid;
return result;
}else if (strArr[mid].compareTo(str) < 0) {
low = mid + 1;
}else {
high = mid - 1;
}
}
return result;
}
Basically what it's supposed to do is return the index at which the string is present in the array, and if it is not in the array then return -1.
So you have a more or less fixed array of strings and then you throw a string at the code and it should tell you if the string you gave it is in the array, do I get that right?
So if your array pretty much never changes, it should be possible to just sort them by alphabet and then use binary search. Tom Scott did a good video on that (if you don't want to read a long, messy text written by someone who isn't a native english speaker, just watch this, that's all you need). You just look right in the middle and then check - is the string you have before or after the string in the middle you just read? If it is already precisely the right one, you can just stop. But in case it isn't, you can eliminate every string after that string in case it's after the string you want to find, otherwise every string that's before the just checked string. Of course, you also eliminate the string itself if it's not equal because - logic. And then you just do it all over again, check the string in the middle of the ones which are left (btw you don't have to actually delete the array items, it's enough just to set a variable for the lower and upper boundary because you don't randomly delete elements in the middle) and eliminate based on the result. And you do that until you don't have a single string in the list left. Then you can be sure that your input isn't in the array. So this basically means that by checking and comparing one string, you can't just eliminate 1 item like you could with checking one after the other, you can remove more then half of the array, so with a list of 256, it should only take 8 compares (or 9, not quite sure but I think it takes one more if you don't want to find the item but know if it exists) and for 65k (which almost matches your number) it takes 16. That's a lot more optimised.
If it's not already sorted and you can't because that would take way too long or for some reason I don't get, then I don't quite know and I think there would be no way to make it faster if it's not ordered, then you have to check them one by one.
Hope that helped!
Edit: If you don't want to really sort all the items and just want to make it a bit (26 times (if language would be random)) faster, just make 26 arrays for all letters (in case you only use normal letters, otherwise make more and the speed boost will increase too) and then loop through all strings and put them into the right array matching their first letter. That way it is much faster then sorting them normally, but it's a trade-off, since it's not so neat then binary search. You pretty much still use linear search (= looping through all of them and checking if they match) but you already kinda ordered the items. You can imagine that like two ways you can sort a buncha cards on a table if you want to find them quicker, the lazy one and the not so lazy one. One way would be to sort all the cards by number, let's just say the cards are from 1-100, but not continuously, there are missing cards. But nicely sorting them so you can find any card really quickly takes some time, so what you can do instead is making 10 rows of cards. In each one you just put your cards in some random order, so when someone wants card 38, you just go to the third row and then linearly search through all of them, that way it is much faster to find items then just having them randomly on your table because you only have to search through a tenth of the cards, but you can't take shortcuts once you're in that row of cards.
Depending on the requirements, there can be so many ways to deal with it. It's better to use a collection class for the rich API available OOTB.
Are the strings supposed to be unique i.e. the duplicate strings need to be discarded automatically and the insertion order does not matter: Use Set<String> set = new HashSet<>() and then you can use Set#contains to check the presence of a particular string.
Are the strings supposed to be unique i.e. the duplicate strings need to be discarded automatically and also the insertion order needs to be preserved: Use Set<String> set = new LinkedHashSet<>() and then you can use Set#contains to check the presence of a particular string.
Can the list contain duplicate strings. If yes, you can use a List<String> list = new ArrayList<>() to benefit from its rich API as well as get rid of the limitation of fixed size (Note: the maximum number of elements can be Integer.MAX_VALUE) beforehand. However, a List is navigated always in a sequential way. Despite this limitation (or feature), the can gain some efficiency by sorting the list (again, it's subject to your requirement). Check Why is processing a sorted array faster than processing an unsorted array? to learn more about it.
You could use a HashMap which stores all the strings if
Contains query is very frequent and lookup strings do not change frequently.
Memory is not a problem (:D) .

Permutations of ArrayList<Integer>

im working on a problem where i have to obtain all permutations of an arraylist of numbers. The only restriction is that any number cant start with 0, so if we have [0,1,2] we would obtain
[1,2,0]
[1,0,2]
[2,0,1]
[2,1,0]
i know how to do this with 3 loops but the thing is that i have to repeat this to different sets of numbers with differentes sizes, so i need one method that i can apply to different sets of numbers but i have no clue on how to do this. I imagine i have to used some kind of recursive function but i dont know how to implement it so the numbers cant start with a 0. Any ideas? please dont just post the code i want to understand the problem, thank you in advantage!!
Curious question! Interesting code kata.
I naively think I would have a recursive method that takes:
a list of the items currently chosen by the caller
a set of the items available for the callee
The method would iterate over the set to chose 1 more item and call itself with the list extended by this item, and the set reduced by this item. Upon return, remove from list, add back to set and go on with next item (take a defensive copy of the set of course).
If the current list is empty, the selected first item cannot be 0, as per your rules. If you must collect the permutations somewhere (not just print), a 3rd argument would be required for a collection or an observer.
The recursion obvioulsy stops when the available set is empty, at which point the permutation is sent to the collection or observer.
If items can repeat, you may have benefit from sorting them first in order to skip electing the same item again at a given position.
Beware this quires a recursion depth of N, for N items. But the danger is minimal because even with N=10000, it may not stackoverflow, but the CPU time to complete would be order(N!) (probably end of universe...)
You could solve this recursively as described here: Permutation of an ArrayList of numbers using recursion.
The only thing that is missing there is your restriction with the zeros, which could be solved somehow like this (the loop is taken from the example above):
for (List<Integer> al : myLists) {
// The part you need to add:
if (al.get(0) == 0) {
continue;
}
String appender = "";
for (Integer i : al) {
System.out.print(appender + i);
appender = " ";
}
System.out.println();
}
You basically check the first element of each permutation and skip the ones with a leading zero. The continue jumps to the next iteration of the loop and therefore to the next permutation.

I need to implement an array hashtable that works without initializing the array to null at the start. Any clue how to do that?

So, here is the actual question (it's for a homework):
A hashtable is data structure that allows access and manipulation of the date at constant time (O(1)). The hashtable array must be initialized to null during the creation of the hashtable in order to identify the empty cells. In most cases, the time penalty is enormous especially considering that most cells will never be read. We ask of you that you implement a hashtable that bypasses this problem at the price of a heavier insertion, but still at constant time. For the purpose of this homework and to simplify your work, we suppose that you can't delete elements in this hashtable.
In the archive of this homework you will find the interface of an hashtable that you need to fill. You can use the function hashcode() from java as a hash function. You will have to use the Vector data structure from Java in order to bypass the initialization and you have to find by yourself how to do so. You can only insert elements at the end of the vector so that the complexity is still O(1).
Here are some facts to consider:
In a hashtable containing integers, the table contains numeric values (but they don't make any sense).
In a stack, you cannot access elements over the highest element, but you know for sure that all the values are valid. Furthermore, you know the index of the highest element.
Use those facts to bypass the initialization of the hashtable. The table must use linear probing to resolve collisions.
Also, here is the interface that I need to implement for this homework:
public interface NoInitHashTable<E>
{
public void insert(E e);
public boolean contains(E e);
public void rehash();
public int nextPrime(int n);
public boolean isPrime(int n);
}
I have already implemented nextPrime and isPrime (I don't think they are different from a normal hashtable). The three other I need to figure out.
I thought a lot about it and discussed it with my teammate but I really can't find anything. I only need to know the basic principle of how to implement it, I can handle the coding.
tl;dr I need to implement an array hashtable that works without initializing the array to null at the start. The insertion must be done in constant time. I only need to know the basic principle of how to do that.
I think I have seen this in a book as exercise with answer at the back, but I can't remember which book or where. It is generally relevant to the question of why we usually concentrate on the time a program takes rather than the space - a program that runs efficiently in time shouldn't need huge amounts of space.
Here is some pseudo-code that checks if a cell in the hash table is valid. I will leave the job of altering the data structures it defines to make another cell in the hash table valid as a remaining exercise for the reader.
// each cell here is for a cell at the same offset in the
// hash table
int numValidWhenFirstSetValid[SIZE];
int numValidSoFar = 0; // initialise only this
// Only cells 0..numValidSoFar-1 here are valid.
int validOffsetsInOrderSeen[SIZE];
boolean isValid(int offsetInArray)
{
int supposedWhenFirstValid =
numValidWhenFirstSetValid[offsetInArray]
if supposedWhenFirstValid >= numValidSoFar)
{
return false;
}
if supposedWhenFirstValid < 0)
{
return false;
}
if (validOffsetsInOrderSeen[supposedWhenFirstValid] !=
offsetInArray)
{
return false;
}
return true;
}
Edit - this is exercise 24 in section 2.2.6 of Knuth Vol 1. The provided answer references exercise 2.12 of "The Design And Analysis of Computer Programs" by Aho, Hopcraft, and Ullman. You can avoid any accusation of plaigarism in your answer by referencing the source of the question you were asked :-)
Mark each element in hashtable with some color (1, 2, ...)
F.e.
Current color:
int curColor = 0;
When you put element to hash table, associate with it current color (curColor)
If you need to search, filter elements that haven't the same color (element.color == curColor)
If you need to clear hashTable, just increment current color (curColor++)

How to Generate a Map in Java?

I trying to complete a RPG game for a project, but have no idea on how to make the game map.
It doesn't need to be graphical, but the code for the whole map and each tile must be correct.
So far, I thought about making a non-matricial map (as request by the professor) by using an ArrayList which contain all the linked tiles.
public abstract class Casella {
/**
* #uml.property name="tabellone"
* #uml.associationEnd multiplicity="(1 1)" inverse="casella:Tabellone"
* #uml.association name="contains"
*/
private int id;
private boolean free = true;
private List adjacent;
private List items;
private Tabellone tabellone = null;
public void in(){
free = false;
}
public void out(){
free = true;
}
}
This was the code for a single tile (which has 3 classes that extends it). I still have no idea on how to put together and generate a map.
Thank you for your time.
Don't start with the implementation, start with how you would like to use the map. That will give you some constraints how to implement it. For example:
When drawing the map, how do you access it? By coordinate? Or by "go west from tile X"?
[EDIT] I suggest to start with the main loop of the RPG game. You'll need to place the character/token somewhere (i.e. it needs some kind of relation to a tile).
Then you need to move the character. A character must be able to examine the current tile (opponents, items, type). It needs a way to know how it can move (i.e. is there a wall to the right?)
This gives you an interface for your map: Services which it renders for other objects in the game. When you have an idea of what the interface needs to provide, that should give you an idea how to implement the map (the data structure).
As for generating a map, use a random number generator plus some "common sense". Have a look at the adjacent tiles: When they are all city, this tile is probably city, too. Same for plains. Hills are singular items, and they are least frequent.
Run this code, print the map as ASCII ("C"ity, "P"lain, "H"ill) to see if it works.
To generate a map like this without using a matrix, I recommend starting with a center tile and then populating the map outwards by using a modified breadth first search algorithm. First of all, we'll need something a little better than a list of adjacent tiles. You could simply have four variables, one for each direction that stores the next tile, as such:
private Tabellone up = null;
private Tabellone down = null;
private Tabellone left = null;
private Tabellone right = null;
Say we start with the center-most tile. All you have to do now is figure out how many of the directions are null, and create a new Tablellone object for each direction, making sure to set each of the variables in this current object and to set the appropriate opposite variable in the object created.
Tabellone adj = new Tabellone();
up = adj;
adj.setDown(this);
Once you've filled out all of the directions on this tile, you then choose one of the other tiles you've created and perform the same operation. This is where the breadth-first search algorithm comes in. You can use a queue to go through each tile you've created and fill out the directions. To make the algorithm stop, simply set a limit on the number of tiles you want to create and use a counter to keep track of how many have been created.
int count = 0;
ArrayList<Tabellone> queue = new ArrayList<Tabellone>()
queue.add(/*center tile*/);
while (count < 100) { //if we want 100 tiles
//take out the center tile from the beginning of the array list, create a tile for each direction and add those tiles to the array list, then increment count by 1.
}
Note: This algorithm as it stands will create a diamond shaped map, if you want a square, you'd need to have a variable for each diagonal direction as well.
Of course, if this seems a little more complicated than you'd like, I'd recommend a coordinate system.
The walls, baggs and areas are special containers, which will hold all the walls, baggs and areas of the game.
private String level =
" ######\n"
+ " ## #\n"
+ " ##$ #\n"
+ " #### $##\n"
+ " ## $ $ #\n"
+ "#### # ## # ######\n"
+ "## # ## ##### ..#\n"
+ "## $ $ ..#\n"
+ "###### ### #### ..#\n"
+ " ## #########\n"
+ " ########\n";
This is the level of the game. Except for the space, there are five characters. The hash (#) stands for a wall. The dollar ($) represents the box to move. The dot (.) character represents the place where we must move the box. The at character (#) is the sokoban. And finally the new line character (\n) starts a new row of the world.
Is speed or memory a huge concern for this project? If not, why don't you use a 2d array?
Something like
Casella map [][] = new Casella[xSize][ySize];
From here it is easy to conceptualize, just picture it as an excel spreadsheet where each cell is a tile on the map.
The way you are going is fine though, just a little hard to conceptualize sometimes. You have a List of adjacent tiles. So, when creating your map you start somewhere, possibly top left, and go from there.
You could use nested for loops in order to set up the map, and to help determine the edge items.
for(int i = 0; i < XSIZE ; ++i)
for(int j = 0; j < YSIZE ; ++j)
if(j==0) //found left edge (i.e. no adjacent ones to the left)
if(j==(YSIZE)) //found right edge (you get the picture)
The point of using the loops, and checking the edges, is that you are going to need to link backwards and forward, up and down for each tile except at the edges, where you will have either 2 or 3 links instead of 4.
The code needs to be correct really isn't a functional requirement, so its hard to say exactly what is correct without knowing more about your game/map.
Assuming you have a map that has X tiles and no ordered adjacency a non-matricial solution is best, a common solution is to just model it like a graph using either adjacency list for non-symmetric adjacency or incidence list for symmetric adjacency. If youre using an incidence list you need an edge object that contain the vertices the edge is connecting, if youre using adjacency list a multimap might be cool to use.
If you want a non-matricial solution with ordered adjacency AlbertoPL has the solution for that.
Assuming you have a map thats X tiles wide and Y tiles tall and the tiles that are next to each other are adjacent, so that each tile has at max 4 and min 2 adjacent tiles you could use a matrix to access the tiles and also represent adjacency by matricial adjacency. The idea is that map[Y][X] is adjacent to map[Y+1][X] and map[Y][X+1] and reversely.
This solution could also fit max 6 and min 3 tile adjacency if tile [Y+1][X+1] is adjacent to tile [Y][X].
Upside to this is that you can easily parse the map, and since it has 2 dimensions its natural to model it like this.
Downside is that once a tile is set, you cant change its adjacency without changing the matrix. As this isnt what you professor suggested you might not want to do it, but if you have (static) ordered adjacency this might be easiest way to do it.
I managed this by using adjacency lists.
Each cell will have an ArrayList containing the indexes of the adjacent cells. Those indexes are the ones that the said cell have in the map ArrayList of cells.
http://en.wikipedia.org/wiki/Adjacency_list
If it's a tile-based map, then each room has a fixed relationship with its adjacent rooms. You may not need to worry about co-ordinates (although it might be simpler if the tiles are square), but you will need to worry about directions.
If the tiles are square, cardinal directions (n, s, e, w) may be all you need care about. If they're hex tiles, you can number your exits 1-6 (perhaps with static final constants). Then each adjacent tile may be linked to this one along with its exit.
As said by Aaron, you need to decide first how the maping coordinates will be.
But you are not constrained by an X-Y-Z coordinate system. For instance, each tile could be linked to any other tile on your map. It all depends on how you want to build it.
You say that you're building an RPG game, then you need to have a good view of the terrain surround your character. Is it multi-level? How does the character move from one tile to another? Is the movement one way?
There are, literally, dozens of question to be asked when designing a map for a game.
You need to plan it very well first, before starting coding.

Categories