Randomly pick elements from an array - java

This is a part of creating a matching game with graphical components. I need to code a class method named randomOrder. I should be able to randomly choose which pictures to be used and I need to place them randomly on the board (for now the board is a 4x4).
I want a method that randomly moves around the elements in an array. For this I wrote
public class Tools {
public static void randomOrder(Object[] f){
Object[] a = new Object[8];
}
}
The only thing I got from the hint is the following:
"Use a temporary array inside the method and take one element at a time from the original array and place it in the temporary array. If the array-position is taken, then you need to randomize a new position. When all the elements are placed, you can copy the temporary array to the original."
I don't understand how to use the hint. I feel this is so complicated that I can't even formulate a proper question.
Can someone translate the hint to me in a more understandable
question?
Is my start okay?
I'm sorry if the question is bad, I don't know how to make it better. Any suggestions are welcome.

Let me try:
Use a temporary array inside the method
You already did that, although the array a should have the same length as f
take one element at a time from the original array and place it in the temporary array
You iterate over a and for each index you do the following:
Create a random integer between 0 and the size of the array, e.g. for a 4x4 grid your array would have length 16 so the index would be between 0 and 15 (both inclusive).
Get the element at that index from f and place it at the current position in a. Then set that index in f to null.
Example:
//iterate
for( int i = 0; i < a.length; i++ ) {
int random = ...; //create the random number here
Object o = f[random];
while( o == null ) {
//see below
}
a[i] = o;
}
If the array-position is taken, then you need to randomize a new position.
If the element in f already is null then either create a new random number (that's what the text hints at) or increment that index until you hit the end or find a non-null element (probably better from a performance point of view, when you hit the end go back to index 0 for f).
When all the elements are placed, you can copy the temporary array to the original.
When you are done filling a you iterate once again and set the elements in f according to their index in a, i.e.
for( int i = 0; i < a.length; i++ ) {
f[i] = a[i];
}

Related

How to set value of cell in List<int[][]>?

I have a list List<int[][]> orgnisms = new ArrayList<>();, which I have populated a few empty (only 0 values) tables and I want to set the value of certain cells now. For example, I want the first table from list and cell [1][1] to have a value of 1. How do I accomplish that?
EDIT:
I have a problem because orgnisms.get(0)[1][1] = 1; adds the value 1 to each table in list, not only table which has index 0...
Here is my code to generate a new empty multi-dimensional array which then gets added to the orgnisms list:
private void newEmptyArrays(){
int[][] emptyTable = new int[n][n];
for( int[] ii : emptyTable)
for (int i : ii)
i = 0;
for(int i=0;i<mi;i++)
orgnisms.add(emptyTable);
}
The same 'table' is being added multiple times to the list, but it is just the only one 'table' that was created in following code part (original problem, not the solution):
int[][] emptyTable = new int[n][n];
for(int i=0;i<mi;i++)
orgnisms.add(emptyTable);
since there is only one instance multiple times, there is no difference by which index of the list the table is being changed. orgnism.get(0) is the same (instance) as orgnism.get(1) and so on...
Solution: create a new 'table' for each entry in the list:
for(int i=0;i<mi;i++) {
int[][] emptyTable = new int[n][n];
orgnisms.add(emptyTable);
}
and just a note, the assignment in following code part is not changing the value inside the array - it wouldn't work to clear an array:
for (int i : ii)
i = 0; // this only changes the value of the variable,
// not of the array entry (not written back)
List<int[][]> orgnisms = new ArrayList<>();
each element within the list is a multi-dimensional array, hence if you want to access any of them you'll first need to retrieve it through the List#get method then perform some operations on it i.e
orgnisms.get(0)[1][1] = 1;
orgnisms.get(0) will retrieve the reference to the multi-dimensional array, then [1][1] will index into row 1 and column 1 of the retrieved multi-dimensional array and assign a value 1 to it.
Update
I have a problem because orgnisms.get(0)[1][1] = 1; adds the value 1
to each table in list, not only table which has index 0...
Look carefully at your last loop, you're storing multiple references to the same multi-dimensional array within the orgnisms list thus it makes sense for such behavior to happen.
Also, as per your update, the code is not doing what you think it's. In fact, the nested for loops are not doing anything to the emptyTable multi-dimensional array. However, by default, all the arrays inside emptyTable have a value of 0 set to each element anyway, meaning attempting to set them to 0 again is redundant.
That said, you can change your method accordingly:
private void newEmptyArrays(){
for(int i = 0; i < mi ; i++){
int[][] emptyTable = new int[n][n];
orgnisms.add(emptyTable);
}
}

2 dimensional array & method calls - beginner

I'm currently working on a homework assignment for a beginner-level class and I need help building a program that tests if a sodoku solution presented as an int[][] is valid. I do this by creating helper methods that check both rows, columns and grids.
To check the column I call a method called getColumn that returns a column[]. When I test it out it works fine. I then pass it out on a method called uniqueEntries that makes sure that there are no duplicates.
Problem is, when I call my getColumn method, it returns an array consisting of only one number (for example 11111111, 22222222, 33333333). I have no idea why it does that. Here is my code:
int[][] sodokuColumns = new int[length][length];
for(int k = 0 ; k < sodokuPuzzle.length ; k++) {
sodokuColumns[k] = getColumn(sodokuPuzzle, k);
}
for (int l = 0; l < sodokuPuzzle.length; l++) {
if(uniqueEntries(sodokuColumns[l]) == false) {
columnStatus = false;
}
}
my helper is as follows
public static int[] getColumn(int[][] intArray, int index) {
int[] column = new int[intArray.length];
for(int i = 0 ; i < intArray.length ; i++) {
column[i] = intArray[i][index];
}
return column;
}
Thanks !
You said:
when I call my getColumn method, it returns an array consisting of only one number (for example 11111111, 22222222, 33333333).
I don't see any issue with your getColumn method other than the fact it's not even needed because getColumn(sodokuPuzzle, k) is the same as sodokuPuzzle[k]. If you're going to conceptualize your 2D array in such a way that your first index is the column then for your purpose of checking uniqueness you only need to write a method to get rows.
The issue you're having would seem to be with another part of your code that you did not share. I suspect there's a bug in the logic that accepts user input and that it's populating the puzzle incorrectly.
Lastly a tip for checking uniqueness (if you're allowed to use it) would be to create a Set of some kind (e.g. HashSet) and add all of your items (in your case integers) to that set. If the set has the same size as your original array of items then the items are all unique, if the size differs there are duplicates.

Best way to put 20 elements in a coordinate system with neighbouring elements unique

This question is regarding libGDX, but I think it's in fact more Java/algorithm related.
Part of my game includes placing 20 elements out of predefined 30 elements list on a screen (so effectively a coordinate system) in 20 partially-predefined places.
By partially predefined I mean that they are predefined for each screen, but there can be dozens of screens, so they can be as well treated as random.
The elements will be selected randomly, but the elements close to each other must be unique. By close I mean in range of some arbitrary defined distance X. Effectively each place will have around 3 'close neightbours'.
The best way I can think of so far is as follows:
Calculate the distance between all places. If a given distance between A and B is lower than X put two entries in a map - one (A,B) and one (B,A)
Now start filling the places with elements
For each place create a list with all neightbours using the map from point 1 (let's call it N-list)
For each place create a temporary list with all possible (30) elements (let's call it E-list)
Get a random element from E-list
Iterate through N-list. For each place from the list get an element currently there (if there's any). For this a (place, element) map is needed, so it will be filled as the algorithm progresses.
If the found element is equal to the current random element remove this element from E-list and this place from N-list and come back to point 5
Proceed until all places are filled
Step 1 is in fact a separate algorithm, that probably can be tweaked, ex. if we calculated the A->B distance we don't need to calculate B->A, but that needs an additional map to store calculation info, etc.
I would like to know what you think of this way and if you have any ideas for a better one.
Thanks in advance for your answers.
P.S. Perhaps the terms I used could be better chosen, but I'm not a native speaker and I don't know English math terms :-)
Ok, I think I understood your solution and this is what I thought of initially. But I think it can be slightly optimized by eliminating extra pairs and maps (or maybe not :)
First, create a map of locations where key is location position (or the location itself) and value is a list of location's parents who fall within the close range. Yes it will have multiple parents, not children, it is actually the same but parents are more fitting here as we'll see.
ArrayList<Place> place_list; // your list of places here
ArrayList<Element> element_list; // your list of elements here
HashMap<Place,ArrayList<Place>> parent_map = new HashMap<Place,ArrayList<Place>>;
ArrayList<Place> a;
for (int i = 0; i < place_list.size() - 1; i++) {
Place place1 = place_list.get(i);
for (int j = i + 1; j < place_list.size(); j++) {
Place place2 = place_list.get(j);
int dist = getDistance(place1, place2);
if (dist > DISTANCE_THRESHOLD) continue;
// if this place is within range,
// add parent place to its list and put/update it to the map
a = parent_map.get(place2);
if (a == null) a = new ArrayList<Place>();
a.add(place1);
parent_map.put(place2, a);
}
}
Now we have a map of all places that have parents. Next we do the following: if place does not have parents, it can choose any random element freely. If it does have parents, it checks what elements parents own and reduces the available set of elements. After the set was reduced, any random element can be chosen from it.
HashMap<Place,Element> used_place_map = new HashMap<Place,Element>(); // key is place, value is assigned element
ArrayList<Element> tmp_element_list;
for (i = 0; i < place_list.size(); i++) {
Place place = place_list.get(i);
a = parent_map.get(place);
if (a == null) { // this place has no parents, use elements freely
tmp_element_list = element_list;
} else { // if it has parents, they have already registered their elements in used_place_map
tmp_element_list = new ArrayList<Element>();
// create list of available elements, lame
for (j = 0; j < element_list.size(); j++) tmp_element_list.add(element_list.get(j));
// now reduce it, very lame, sorry
for (Place pl : a) {
Element used_element = used_place_map.get(pl);
for (j = 0; j < tmp_element_list.size(); j++) {
if (used_element.equals(tmp_element_list.get(j)) {
tmp_element_list.remove(j);
break;
}
}
}
}
// finally, get the random index on (probably reduced) array
int element_id = Random.nextInt(tmp_element_list.size());
Element element = element_list.get(element_id);
// store our choice as future parent
used_place_map.put(place, element);
}

Java - Trouble reading data from a list of 2D arrays

I have created a list of 2D arrays containing randomly generated number values for different locations.
public static int Prices[][] = new int[Cities.length][ItemNames.length];
public static List<int[][]> CityPrices = new ArrayList<int[][]>();
public static void NewDay()
{
for(int i = 0; i<Cities.length; ++i)
{
Prices[i] = PriceGenerator.ReturnPricesForCity(i);
//This method returns an array of random integers
}
CityPrices.add(Prices);
}
But then later when I want to retrieve the price history for a specific item for the amount of days passed, it returns the same value for each day
int Prices[] = new int[GlobalVariables.CityPrices.size()];
String sTest = "";
for(int i = 0; i < Prices.length; ++i)
{
Prices[i] = GlobalVariables.CityPrices.get(i)[spinCity.getSelectedItemPosition()][spinItem.getSelectedItemPosition()];
sTest = sTest + Prices[i] + ",";
}
In this case, the values returned by sTest was : 6055,6055,6055,6055,6055, for five consecutive days.
If I would for instance add a day, the values would change to a range of a new number, which in this case was : 7294,7294,7294,7294,7294,7294,
Please show me what I am doing wrong, as I have been trying to figure this one out the past 4 days with no luck.
Every element in your CityPrices list is the same: in each case, you are adding the Prices two-dimensional array. Your loop modifies Prices[i], but it doesn't change Prices, which is still a reference to the same two-dimensional array right the way through.
I think you're imagining it will pass the contents of the array in its current state, but it doesn't: it passes a reference to the array to the .add() method, so any subsequent changes to the array will be reflected in the contents of CityPrices.
If at the end of your loop you try
CityPrices.get(0) == CityPrices.get(1)
you'll see it returns true.
In the assignment: Prices[i] = GlobalVariables.CityPrices.get(i)[spinCity.getSelectedItemPosition()][spinItem.getSelectedItemPosition()]; you are basically referencing an int[][] at the same index for both dimensions.
On top of that, the spinCity.getSelectedItemPosition() invocation might be returning the same index at every iteration of your loop, hence your identical values.
It's hard to assume anything further as you haven't posted the code for spinCity.

How to check a matrix postion value in java?

Given a matrix filled in with all its values, there's the need of pulling out data randomly in order to create a random matrix (intialized with null values each position). The issue lies while checking if a position (within the randomMatrix) is different from null, as shown below:
public void randomLogic(String[][] givenMatrix){
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
int positioni = this.randInt(0, 1);
int positionj = this.randInt(0, 1);
int x = this.randInt(0, 3);
int y = this.randInt(0, 2);
/*In here lies the reported issue while checking if empty. */
while (!this.randomMatrix[x][y].isEmpty()) {
x = this.randInt(0, 3);
y = this.randInt(0, 2);
this.randomMatrix[x][y] = givenMatrix[positioni][positionj];
}
}
}
}
I've also tried with the following: while(this.randomMatrix[x][y] != null) and the code breaks down right away. All the solving-logic work out as expected (because if I ommit that part it works with flaws but works) the only problem is that validation. Regardless of what position is being evaluated it always stops working.
Is there any other way of checking a matrix position value?
are you trying to pull random values (and consequently, some will be repeated) from a givenMatrix OR do you want to specifically randomize the givenMatrix?
If it's the latter, I would approach it differently.
First of all, gather all values of the givenMatrix in one linear-array or list.
Then, you can randomize this array, and you'll be left with a big array of rows*columns items, with all the values from the original matrix already randomized.
Then, you can systematically fill the new randomized matrix, taking each element of the array in order, till you complete each row and column of the new matrix.
I would choose this approach, because it's easier, and it will finish in a fixed number of steps; rather than filling random positions, because maybe you land 2 times in the same place to fill, and you'll have to randomize until you hit all the spots.
(Also, if you don't care of repeating the values for the new matrix, then instead of taking each element of the randomized array, you can simply pick a random position of this array each time)
Have you declared String[][] randomMatrix as a class level member variable? If you have declared the randomMatrix correctly then the isEmpty() and != null checks should work.

Categories