Algorithm to implement the BINGO game - java

For those who doesn't know a BINGO game, its played as follows
1)You get a BINGO card in which there is a NXN matrix of numbers randomly printed.Numbers are unique.The max number printed can be greater than N^2. e.g. if you have 5x5 matrix then the max number can be 75 as well.But the range of numbers is pre-decided say 1 to M.
2)A person speaks out numbers randomly in the range 1 to M.
3)If the number is on your card you cross the number.
4)The process of crossing numbers is repeated.When you have crossed a full row or a full column or the two diagonals,then you get your first bingo
The game is still continued as the total BINGOs possible are N+N+2 for N rows,N columns and 2 diagonals.
Now I want to create an algorithm for it.The user will input random numbers and the algorithm will hear them and cross its numbers in the matrix(already provided).As soon as it gets BINGO it declares it.What is the best possible approach
I tried it as maintaining a 2-D matrix for the card
When a number is announced, i search it in O(NxN) time.When I find it ,I make it as 0.
After making it as 0, I search whether it the corresponding row & column has now all zeroes.If it was on the diagonal , I also search for the diagonal.It takes O(3N) time.
Any better approach?

You can form a map for each number that would map to a pair (row, column).
if ( myMap[number] exists ) {
then increment rowCount[ myMap[number].row ];
then increment columnCount[ myMap[number].column ];
}
if ( rowCount[myMap[number].row] == N ) { bingo! }
if ( columnCount[myMap[number].column] == N ) { bingo! }
myMap.erase( number );
Similarly for diagonals.

Use an array to store the numbers on the card and keep it sorted. Upon number being called, search the number using Binary Search (O(logN) time). This should be a quick approach.

Create a class Coordinate that holds x and y position in bingo card.
NxN array of booleans initialized to false to keep track of what gets crossed off on bingo card.
N^2 time to iterate through bingo card and add each number to hash table using the number as the key and a new Coordinate as the value.
n time to iterate through all the numbers that will be called out, retrieve the Coordinate from the hash table, and update the status of the boolean array. In case of duplicate numbers called, you must retrieve and update boolean array until the hash table does not contain the key.
4N time to check each direction on boolean array for first bingo
N^2 + n*4N total runtime

Related

1d array of unique distances between points

I'm coding an N-body simulator with planets (points). I've got it working but there are still a lot of possible optimizations, one of them is to calculate distances between points once and store them in an array. I could use a 2d array (needed to be converted to 1d because the GPU doesn't support 2d arrays) but there are two problems:
The simulation would be limited to √2147483647 (max integer value) planets = 46340 planets since the size of the array would be n^2 (n is the number of planets)
A lot of the distances would be repeated (distance between 0 and 1 is the same as distance between 1 and 0)
To get the amount of unique connections the formula is: D = (n*(n-1))/2
But now I've got a problem: how to get an index in the distances array given two planet id-s (x,y). The distance index between planet 0 and 1 is 0, 0-2 -> 1, 1-2 -> 2...
To help visualize what this looks like, here is a table showing which index (in the 1D array) corresponds to each pair of planet ids. To use this table, given a pair of planet ids, find the row that corresponds to the larger of the two ids, and the column that corresponds to the smaller of the two ids, and that will give you the cell with the index of where that distance is stored in your 1D array.
So, now we need a formula that is given two planet ids and computes the 1D index number. For simplicity, we will assume that the larger planet id is given first. (If not, then we can simply swap the two planet ids.)
The first job is to take the larger planet id and determine the first index on its row. In other words, we need to convert 1 to 0, 2 to 1, 3 to 3, 4 to 6, 5 to 10, 6 to 15, etc. Luckily, the pattern 0,1,3,6,10,15 is well known - it is the triangular numbers. The usual formula for the Nth triangular number is (n*(n+1))/2 but in this case we actually want the N-1th triangular number, so the formula we want is (n*(n-1))/2.
Once we have the first index of the row, we can just add the smaller planet id to get the final index.
So, our final formula is:
given A (larger planet id) and B (smaller planet id):
the index of dist(A,B) in the 1D array is ((A * (A-1)) / 2) + B

Java permutations of offsets

Had a question regarding generating a list of 10-digit phone numbers on a PhonePad, given a set of possible moves and a starting number.
The PhonePad:
1 2 3
4 5 6
7 8 9
* 0 #
Possible moves:
The same number of moves a Queen in chess can make (so north, south, east, west, north-east, north-west, south-east, south-west... n-spaces per each orientation)
Starting number: 5
So far I have implemented the PhonePad as a 2-dimensional char array, implemented the possible moves a Queen can make in a HashMap (using offsets of x and y), and I can make the Queen move one square using one of the possible moves.
My next step is to figure out an algorithm that would give me all 10-digit permutations (phone numbers), using the possible moves in my HasMap. Repetition of a number is allowed. * and # are not allowed in the list of phone numbers returned.
I would imagine starting out with
- 5555555555, 5555555551, 5555555552... and so on up to 0,
- 5555555515, 5555555155, 5555551555.. 5155555555.. and with the numbers 2 upto 0
- 5555555151, 5555551515, 5555515155.. 5151555555.. and with numbers 2 upto 0
... and so on for a two digit combination
Any suggestions on a systematic approach generating 10-digit combinations? Even a pseudocode algorithm is appreciated! Let me know if further clarification is required.
Thanks in advance! :)
In more detail, the simplest approach would be a recursive method, roughly like:
It accepts a prefix string initially empty, a current digit (initially '5'), and a number of digits to generate (initially 10).
If the number of digits is 1, it will simply output the prefix concatenated with the current digit.
If the number of digits is greater than 1, then it will make a list of all possible next digits and call itself recursively with (prefix + (current digit), next digit, (number of digits)-1 ) as the arguments.
Other approaches, and refinements to this one, are possible of course. The "output" action could be writing to a file, adding to a field in the current class or object, or adding to a local variable collection (List or Set) that will be returned as a result. In that last case, the (ndigits>1) logic would have to combine results from multiple recursive calls to get a single return value.

Determine if there are conflicts in set

I have a Java HashMap containing 5 entries. Mapped to each entry is an object containing:
an x value
a y value
a length
an orientation (either "horizontal" or "vertical")
Think of the game battleship with a 10 x 10 board. The x / y coordinates in each entry corresponds to the top left corner of a ship on the board, and the length and orientation correspond, as one would expect, to the ships length and orientation from that point.
I'm trying to think of a way to rip through the 5 ships and check if there are any "overlapping ships", known as conflicts, on the board. I can't figure out how to do this. Any help would be much appreciated.
One way to do it is:
1) assign each cell in your board a number, 1-100 (or 0-99).
2) Add a method to the things in your hashmap that returns a List of the unique cell ids that are covered. So if x == 1, y==1, length == 3, orientation == horizontal, you would return the three 1-100 values that represent the cell over which your submarine resides.
You will be able to calculate the first unique id by doing something like rowNumber*10 + columnNumber. You might have to tweak it depending on if you are 0 or 1 based, and or if your range is likewise 0 or 1 based..From there, if horizontal you just add 1 for each unit of length. Or you add 10 for each unique id if your piece is vertical.
3) Now you can have a collision detector class with a static method, that takes two pieces. It can call the method you created in step 2, get the two lists, and if there are any overlaps, you would find the same number in both lists.
I don't know if this is the best way to do it, but it is one way.

JAVA How do I generate integers between 1 and 24 but I need a pair of each integer

I'm making the memory game concentration.
In this I have a specified obligation to generate random pairs of numbers.
These are to be assigned to a cell at its creation on a game board.
My problem lies not in how to generate a random number as I am able to do this with --
type = generator.nextInt(NUMBER_OF_ROWS*NUMBER_OF_COLUMNS);
However I must make sure that when I am populating my game board with Cell objects
board[row][column] = new Cell(this,type, row, column);
I have 2 cells of the same type, in order for the game to function.
Basically
I need 12 pairs of numbers that have been randomly generated.
Thanks
Varun
Invert the problem. Rather than think of generating 24 random numbers, what you really want is to distribute the numbers 1-12 randomly into a 24-cell array, with each number going into TWO randomly selected cells in the array. The simplest way to do this would be be to create a List<Cell>, populate it with 24 cells (two containing value 1, two containing value 2, etc), and then use Collections.shuffle(List<?>...)
The question is not clear. But I think you want to have two cells of same type i.e you have 24 cells and you want to make 12 pairs of them. If you want the cells to be random you can generate two random rows number and two random column number and pair them. You have to look that the pair is not repeated.
EDIT: No function can generate pair of numbers. What you can do is number the cells in 2-D array , like suppose the row count is 3 and columns is 2 then number it like 0,1,2,3,4,5. Now start generating random numbers and set the upper limit to 5. Suppose the first no. generated is 2 and second one is 5 then you can call it a pair. Then again generate the numbers. Next pair can 1 and 0 and so on.
It looks like you are not familiar with 2 Dimensional arrays or my understanding of the question is wrong. I think the game requires the player to remember a pair of cells. Totally there are 12 pairs so have a 2D array with one index varying from 0 to 11 which denotes pair number and another index which distinguishes the two cell numbers in a pair.
You need to store in an integer array called pairtype[12][2] two numbers which are paired. Say suppose cell no 1 is paired with 15 then there will be one value {1,15} in the array pairtype. So you can store 12 pairs of two integers in the array pairtype.
What mistake you are doing is using type which can range from 0 to 23 to assign to a cell type. Instead use the first index(index1) of pairtype[index1][index2] as cell type which will then vary from 0 to 11.
You also need to take care not to generate pairs like {1,15} and {1,12} in the array pairtype.

Looping through all combinations

I'm trying to program a multiple players game in Java.
I need to create a list of all combinations and to store these in an array.
If 2 players are logged in as the game start, the combinations are:
p1,p2 and p2, p1 (positions are important)
while if 3 players logged in to the game, the combinations are:
p1,p2,p3 ; p1,p3,p2 ; p2,p1,p3 ; p2,p3,p1 ; p3,p1,p2 and p3,p2,p1
In fact, I need a redundant array:
if 3 players are logged in, I need in advance the combinations of 3 AND the combinations of each possible pairs
p1,p2,p3 ; p1,p3,p2 ; p2,p1,p3 ; p2,p3,p1 ; p3,p1,p2 and p3,p2,p1
and
p1,p2 and p2, p1
and
p1,p3 and p3, p1
and
p2,p3 and p3, p2
)
Many players (EDITED: up to 8 players) may be logged in simultaneously to the same round of the game. (EDITED: there are up to 32 groups, but this is not important, because groups are independent)
Is there a quick, short and a simple way to create this combinations array for n players?
A recursive solution is foreseen and acceptable.
Many thanks
P.S.
My ongoing idea is to split the group into 2, a selected pair and the rest of the players.
The sekected pairs are selected using 2 FOR loops and the rest with a third.
If there are 2 players, no 'rest". If there are 3 players, the 2 FORs will select the positions of the pair and the rest will get the rest.
then, the rest are ordered using the same split procedure.
May this way get real? how? Will it be efficient?
Thanks again.
The number of permutations of size n is n!, which grows exponentially.
For example, the number of all permutations of 20 elements is 2432902008176640000(~2.43290201 × 10^18), quite big number.
Like you correctly guessed, there is a recursive algorithm for generating all permutations, but it is quite ineffecient in both time and space for reasons listed above.
However, if your task is generating a random permutation, an efficient algorithm does exist: Fisher–Yates shuffle. It requires O(n) time(assuming you can generate a random integer in O(1)), and O(1) of additional memory.
You know the number of entries in each array. For the array with all players, it's 256! That's possibilities for the first entry in the array, 255 for the next, and so forth. 256! is a larger enough number that my calculator can't handle it. Even for 170 players, the size of the array would be 1.3e241. Even on a 64 bit computer, you only have 1.8e19 addressable bytes. This basically means you need to rethink your approach.

Categories