I want to generate random coordinates from 0-5 (Row,Col) without any duplicates using for loops. Basically if the numbers (3,2), (3,4), (1,4), (3,4) are generated then (3,4) will not be utilized and a new random set will be looked for.
These are the methods that generate two random numbers and loads them into the array shootP[ ]
int[] shootP = new int[2];
public static int shootRowP(int[] shootP)
{
Random rn = new Random();
shootP[0] = rn.nextInt(5)+1;//loads into ROW
System.out.print("Row:"+(shootP[0]));
return shootP[0]--;
}
public static int shootColP(int[] shootP,int[][]boardP)
{
Random rn = new Random();
shootP[1] = rn.nextInt(5)+1;//loads into Col
System.out.print(" Column:"+(shootP[1])+"/n");
return shootP[1]--;
}
I then want to have another method read in the values of shootP[0] and shootP[1] and check to see if those values were already used. Any suggestions?
Since the number of possible coordinates (X,Y) is not too large, first build a list of all possible coordinates. Then, at each random pick, choose a random element in this list (i.e. rn.nextInt(current_list_length)), remove the element from the list and return it.
Notes:
You must do something (exception?) when the list is empty
You can also shuffle your list at initialization and at each draw, you pick and delete the first (or last) element. See here how to shuffle an array, for example.
Instead of a list, a stack (an array + an element counter) can do the trick.
Related
Let's say I have the following dictionary:
the_dictionary_list = {'Color': ['Amarillo.png', 'Blanco.png', 'Rojirosado.png', 'Turquesa.png', 'Verde_oscuro.png', 'Zapote.png'],
'Cuerpo': ['Cuerpo_cangrejo.png'],
'Fondo': ['Oceano.png'],
'Ojos': ['Antenas.png', 'Pico.png', 'Verticales.png'],
'Pinzas': ['None', 'Pinzitas.png', 'Pinzotas.png', 'Pinzota_pinzita.png'],
'Puas': ['None', 'Arena.png', 'Marron.png', 'Purpura.png', 'Verde.png']}
A way of printing each possible combination is by using itertools, here:
import itertools as it
AllKeysNames = the_dictionary_list.keys()
Combinations = list(it.product(*(the_dictionary_list[Name] for Name in AllKeysNames)))
print(f'{Combinations}')
This will print a list which has 360 elements in total.
However, let's say that the order matters in the previous case (i.e. permutations are needed), this order would be the following:
'Fondo'>'Cuerpo'>'Ojos'>'Color'>'Pinzas'>'Puas'
How could I make a program that always start with the value of 'Fondo' key, then adds the value of 'Cuerpo' key, then adds the first value of 'Color' key, then adds the first value of 'Pinzas' key, then adds the first value of 'Puas' key and so on...?
In the end the total amount of elements in the new list would still be 360, but this time these elements would have been created following an specific order.
Any ideas?
I finally figured it out, I even decided to let the user be the one who decides the order in which the permutations will be made.
# creating an empty list
Keys_input = []
# number of elements
n = len(the_dictionary_list)
i = 0
while True:
AllKeysNames = the_dictionary_list.keys()
print('\033[46m'+str(AllKeysNames)+'\033[0m')
ele = input("\033[0;37;40mTell me which valid key you want me to set now:\033[0m ")
if ele in the_dictionary_list and ele not in Keys_input:
Keys_input.append(ele) # adding the element
i += 1
print(f'\033[0;37;42mThe array has been updated, its current storage is the following {Keys_input}\033[0m')
if i == n:
print("\u001b[45mThe array is now full, let's continue with the next step\033[0m")
break
else:
if ele not in the_dictionary_list:
print('\u001b[43mPlease, type only valid key names\033[0m')
if ele in Keys_input:
print('\u001b[43mStop, that key IS ALREADY SAVED in the array, try with a different valid one\033[0m')
print(f'\u001b[45mCurrent storage of the array is the following {Keys_input}\033[0m')
AllKeysNames2 = Keys_input
Combinations = list(it.product(*(the_dictionary_list[Name] for Name in AllKeysNames2)))
print(f'{Combinations}')
Suppose I have the following numpy array of strings:
a = numpy.array(['apples', 'foobar', ‘bananas’, 'cowboy'])
I would like to generate len(a)/2 random pairs of strings from that matrix in another numpy matrix without repeating elements in each pair, with unique pairs and also with unique values for each pair (each value is unique for each pair). I also need to fix the random number generator so the pairs are always the same no matter how many times the algorithm is run. Is it possible to do that?
numpy.random.choice
The random.choice method is probably going to achieve what you're after.
import numpy as np
n_samples = 2
# Set the random state to the same value each time,
# this ensures the pseudorandom array that's generated is the same each time.
random_state = 42
np.random.seed(random_state)
a = np.array(['apples', 'foobar', ‘bananas’, 'cowboy'])
new_a = np.random.choice(a, (2, n_samples), replace=False)
The replace=False ensures that an element is only used once, which would produce the following output.
array([['foobar', 'cowboy'],
['bananas', 'apples']], dtype='<U7')
There are 20 red balls sitting in 20 positions on 4 shelves. I'd like to move each ball to a new position on its own shelf by generating a new array that contains the new positions for all 20 balls. I am using a function (below) that allows me to do this. However, I find that this function keeps crashing; when I print out values it is generating, it seems to hang at the last coordinate of available position but then doesn't exit the "while" loop.
func generateNewLocationArray(previous: [String: CGPoint]) -> [String : CGPoint] {
var refreshedLocations = [String : CGPoint]()
for (location, _) in previous {
let node = fgNode.childNode(withName: location) as? LocationNode
var newLocation = generateRandomLocation(check: refreshedLocations)
let previousLocation = previous[(node?.name!)!]
while (newLocation == previousLocation) || (newLocation.y != previousLocation?.y) {
newLocation = generateRandomLocation(check: refreshedLocations)
}
node?.position = newLocation
refreshedLocations[location] = newLocation
}
return refreshedLocations
}
What I'm trying to achieve:
The function takes in an array of CGPoints, this is the "previous"
array, of positions where all the balls were.
It then creates a brand-new array, called "refreshedLocations".
It loads an existing node, which is located at a position contained in the previous array.
It then generates a new position for that node. This position is obtained from a pre-set array of 20 positions. This new location cannot be the same position the node is currently in; nor can it have a different y-coordinate (so the balls stay on the shelf).
Until this criteria is met, it keeps generating a new position.
It then loads this position into the refreshedLocations array, and the next node is also checked against this array to ensure there are no repeated positions.
The problem again: this code works with 10, or 15 balls. But when the number is pushed to 20, it seems more likely to hang. It will identify how to move all the balls around to new positions, but it gets stuck in the "while" loop more often than not. What's going wrong here?
EDIT: This is the function which returns a random location, but first checks whether the array that is being generated already contains the point being added.
func generateRandomLocation(check: [String : CGPoint]) -> CGPoint {
let randomIndex = GKRandomDistribution(lowestValue: 0, highestValue: allPositions.count - 1)
var position = allPositions[randomIndex.nextInt()]
while check.values.contains(position) {
position = allPositions[randomIndex.nextInt()]
}
return position
}
As far as I can see,
while (newLocation == previousLocation) || (newLocation.y != previousLocation?.y)
is always going to be true if you get to the last ball on a row and the only position left is the one it is already in. You can fix it by detecting how many positions on the shelf have been filled and if it is n - 1 out of n and the only position left is the one the ball is in, just swap it with a randomly selected other ball on the same shelf.
However, there must be a better way of doing this. I'd try a modified Fisher Yates shuffle.
Firstly, organise the balls by shelf and position. Then, for each shelf of n balls (numbered 0 to n - 1)
select a random ball from the first n - 2 balls and swap it with ball n - 1
select a random ball from the first n - 3 balls and swap it with ball n - 2
select a random ball from the first n - 4 balls and swap it with ball n - 3
and so on. Stop when the random selection would be from 0 balls. At the end of this process, all the balls will have changed position.
Repeat for each shelf.
I'm creating a 4x4 sudoku game in a multidimensional array filled by random generated numbers (from 1 to 4). Now I have to search duplicates and replace them with other random numbers until there are unique numbers on the single row, single column and on the four 2x2 sub-matrix.
How can I do that?
There's my code for generating the grid:
func fill (N:Int) {
for row in 0..<N {
//Append an empty row
matrix.append([Int]())
for _ in 0..<N {
//Populate the row
matrix[row].append(Int(arc4random_uniform(4)+1))
}
}
}
fill(N: 4)
You can change the array into a set(removes duplicates) and then back into an array. But your order might change.
matrix = Array(Set(matrix))
My image array: C_filled = 256x256x3270
What I would like to do is calculate the centroids of each image, and store each centroid corresponding to each 'slice'/image into an array. However, when I try to update the array, like a regular array, I get this error:
"Undefined operator '+' for input arguments of type 'struct'."
I have the following code:
for i=1:3270;
cen(i) = regionprops(C_filled(:,:,i),'centroid');
centroids = cat(1, cen.Centroid);% convert the cen struct into a regular array.
cen(i+1) = cen(i) + 1; <- this is the problem line
end
How can I update the array to store each new centroid?
Thanks in advance.
That's because the output of regionprops (i.e. cen(i)) is a structure, to which you try to add the value 1. But since you try to add the value to the structure and not one of its field, it fails.
Assuming that each image can contain multiple objects (and therefore centroids), it would be best (I think) to store their coordinates into a cell array in which each cell can be of a different size, contrary to a numeric array. If you have the exact same number of objects in each image, then you could use a numeric array.
If we look at the "cell array" option with code:
%// Initialize cell array to store centroid coordinates (1st row) and their number (2nd row)
centroids_cell = cell(2,3270);
for i=1:3270;
%// No need to index cen...saves memory
cen = regionprops(C_filled(:,:,i),'centroid');
centroids_cell{1,i} = cat(1,cen.Centroid);
centroids_cell{2,i} = numel(cen.Centroid);
end
and that's it. You can access the centroid coordinates of any image using this notation:centroids_cell{some index}.