how to prevent a number from repeating - java

Ok so i have looked about for an answer. I am using a random generator to generate numbers based on the user input. This will then select a random number from that and assign them a special position in the game. However the problem is i keep getting repeated values which isn't what i want. So could anyone help?
in
(blueprint class)
int getRoll()
{
roll=rand.nextInt(totalNum);
return roll;
}
(main class)
for(numberOfWerewolves=0;numberOfWerewolves!=wolves.werewolfNum;numberOfWerewolves++)
{
playerNumber++;
wolves.getRoll();
System.out.println(wolves.roll);
}
anyone can help me would be great thanks

It sounds like you want several random numbers within the same range, but you don't want any repeats. If so, what you want is called a "shuffle." Fill an array with the numbers from 1 to N (or 0 to N-1, or whatever), shuffle the array, and then start using the numbers from the beginning of the array.
A good description and implementation of shuffling is given here:
https://stackoverflow.com/a/1520212/1441122

Create a list to keep track of previous random numbers, and loop to keep recalculating the random number until it doesn't match any of them in the list:
public static boolean checkIfExists(ArrayList<Double> list, double x) {
for (double d : list) {
if (d == x) {
return false;
}
}
return true;
}
ArrayList<Double> list = new ArrayList<Double>();
int getRoll()
{
while (true) {
roll = rand.nextInt(totalNum);
if (checkIfExists(list, roll)) {
list.add(roll);
return roll;
}
}
return -100; // -100 means it couldn't generate a number
}
You should not keep the while condition to be true; you should modify it so that it only loops for until you're sure that a unique number can't be generated.

Related

How to generate random unique numbers on java

I'm new to Java and im trying to randomize non-repeating numbers for a game. My code generates unique random numbers from 1 to 75 only if i do not add a break statement, (which i have to do to only get one number at the time). What do I do? edit -(i was wondering if the reason it kept resetting is because i called on the method multiple times? im not too sure how to fix that)
public static void genNumber() {
Random random = new Random();
int num;
String u;
String letter = "";
HashSet<Integer> used = new HashSet<>(75);
for (int i = 1; i <= 75; i++){
ball.add(i);
}
while(used.size() > 0) {
num = 1 + random.nextInt(75);
if (used.contains(num)){
used.remove(new Integer(num));
u = Integer.toString(num);
System.out.print(u + "\n");
break;
}
if (!used.contains(num)){
continue;
}
}
The numbers are unique and random but i only want one number at the time (without repeating) not all 75 at once.
Perhaps shuffle the list each time you want a new random sequence, like a deck of cards. Each element is guaranteed to be unique.
List<Integer> balls = new ArrayList<>();
for (int i = 1; i <= 75; ++i) {
balls.add(i);
}
for (;;) {
// Shuffle the list every 75 draws:
Collections.shuffle(balls);
System.out.println(Arrays.toString(balls.toArray()));
// Consume the sequence
for (Integer ball : balls) {
take(ball);
}
}
I would make a 75 element array of boolean values and set all the values to true. Make a method that generates one random number and update your boolean array at that value to false. Each time you generate a number check your array to see if that value is set to true. Then you can keep generating numbers one at a time and not have to worry about getting repeats. You can have a while loop that asks the user to input yes or no and if they answer no it won't call your method and set your while loop condition to false. and if they answer yes it does call the method and keeps looping.

The correct Recursive backtracking algorithm?

My assignment is to find a way to display all possible ways of giving back change for a predetermined value, the values being scanned in from a txt file. This must be accomplished by Recursive Backtracking otherwise my solution will not be given credit. I will be honest in saying I am completely lost on how to code in the appropriate algorithm. All I know is that the algorithm works something like this:
start with empty sets.
add a dime to one set.
subtract '10' from my amount.
This is a negative number, so I discard that set: it is invalid.
add a nickel to another (empty) set.
subtract '5' from my amount.
This equals 2; so I'll have to keep working on this set.
Now I'm working with sets that already include one nickel.
add a dime to one set.
subtract '10' from my amount.
This is a negative number, so I discard that set: it is invalid.
repeat this with a nickel; I discard this possibility because (2 - 5) is also negative.
repeat this with a penny; this is valid but I still have 1 left.
repeat this whole process again with a starting set of one nickel and one penny,
again discarding a dime and nickel,
and finally adding a penny to reach an amount of 0: this is a valid set.
Now I go back to empty sets and repeat starting with a nickel, then pennies.
The issue is I haven't the slightest clue on how or where to begin, only that that has to be accomplished, or if any other solutions are apparent.
This is my code thus far:
UPDATED
import java.io.*;
import java.util.*;
import java.lang.*;
public class homework5 {
public static int penny = 1;
public static int nickle = 5;
public static int dime = 10;
public static int quarter = 25;
public static int halfDollar = 50;
public static int dollar = 100;
public static int change;
public static void main(String[] args) throws FileNotFoundException {
ArrayList<Integer> coinTypes = new ArrayList<Integer>();
Integer i;
File f = new File (args[0]);
Scanner input = new Scanner(f);
input.nextLine();
while(input.hasNextInt()) {
i = input.nextInt();
coinTypes.add(i);
}
change = coinTypes.get(coinTypes.size()-1);
coinTypes.remove(coinTypes.size()-1);
System.out.println("Found change"); //used for debugging
System.out.println("Change: " + change);
System.out.println(coinTypes);
}
boolean findChange(int change, List<Integer> coinTypes,
List<Integer> answerCoins) {
if(change == 0) {
return true;
}
if(change < 0) {
return false;
} else {
for(Integer coin : coinTypes) {
if(findChange(change - coin, coinTypes, answerCoins)){
answerCoins.add(coin);
return true;
}
}
List<Integer> answer = new ArrayList<Integer>();
boolean canFindChange = findChange(change, coinTypes, answer);
if(canFindChange) {
System.out.println(answer);
} else { System.out.println("No change found");
}
return false;
}
}
Here is the input file that I scan in
java homework5 hwk5sample1.txt
// Coins available in the USA, given in cents. Change for $1.43?
1 5 10 25 50 100
143
OUTPUT
Found change
Change: 143
[1, 5, 10, 25, 50, 100]
So using the numbers in my coinTypes ArrayList, I need a generic code algorithm to show all possible ways of receiving, for example, 143 ($1.43) back in change using the coins in the file with all pennies being the last way to show it.
Please do not think I want you to write me the algorithm, I am simply wanting help writing one otherwise I will learn nothing. Thank you all for any answers or help you can give it means a lot to me! Please let me know if i missed anything or you need more info
The example that you walk through seems to be mostly correct. The only error is this: again discarding a dime and nickel, which should be again discarding a *penny* and nickel (but I think that's just a typo.)
To write a recursive backtracking algorithm, it is useful to think of the recursive call as solving a subproblem of the original problem. In one possible implementation of the solution, the pseudocode looks like this:
/**
* findChange returns true if it is possible to make *change* cents of change
* using the coins in coinTypes. It adds the solution to answerCoins.
* If it's impossible to make this amount of change, then it returns false.
*/
boolean findChange(int change, List<Integer> coinTypes, List<Integer> answerCoins) {
if change is exactly 0: then we're done making change for 0 cents! return true
if change is negative: we cannot make change for negative cents; return false
otherwise, for each coin in coinTypes {
// we solve the subproblem of finding change for (change - coin) cents
// using the recursive call.
if we can findChange(change - coin, coinTypes, answerCoins) {
// then we have a solution to the subproblem of
// making (change - coins) cents of change, so:
- we add coin to answerCoins, the list of coins that we have used
- we return true // because this is a solution for the original problem
}
}
//if we get to the next line, then we can't find change for any of our subproblems
return false
}
We would call this method with:
List<Integer> answer = new ArrayList<Integer>();
boolean canFindChange = findChange(change, coinTypes, answer);
if(canFindChange) {
System.out.println(answer); // your desired output.
}
else {
System.out.println("Can't find change!");
}

How to get unique random int?

static int n = -1;
private static int repeatBuffer[] = new int[10];
static {
repeatBuffer[0] = 0;
//and more
repeatBuffer[9] = 9;
}
static public void randomize() {
do {
Random r = new Random();
randomNumber = r.nextInt(20);
} while (!uniqueInt(randomNumber));
Log.e(TAG, "" + randomNumber); //here I need have a unique int
}
private static Boolean uniqueInt(int random) {
for (int i = 0; i < 9; i++) {
if (random == repeatBuffer[i]) {
return false;
}
}
if (++n > 9)
n = 0;
repeatBuffer[n] = random;
return true;
}
Sometimes I'm getting same int twice, I'm wondering where is the problem? And is it even work? I spend quite a lot of time on this, and I give up. I think I need some minor tweaks in code :)
An easier way to get a random int is to create a List of integers List<Integer>, adding it with numbers that you would like to have. Then shuffling the List using Collections.shuffle(list);. Now start reading from the beginning of the list and you will get a unique random int each time.
Just make sure that each time you "read" a number from the list, either remove it from the list or increase the index for where you read.
That's the normal behavior of a random number generator, it's correct to generate repeated numbers as long as the number distribution remains uniform.
If you need a set of unique random numbers, you can generate them inside a loop and ask at every iteration if the newly generated number is present in the set of generated numbers. If not, add it, if yes, keep iterating - until the set has the desired size.
Er, a unique random between 1 and 20? What happens when it runs the 21st time?
Try making a List of the Integers between 1 and 20. Use Collections.shuffle() to shuffle the list. Then pop the first item off the front of the list and use that.

recursion using a hashmap

I have an array that has the following numbers
int[] arr = {2,4,3,1,5,6,0,7,8,9,10,11,12,13,14,15};
Or any other order for that matter.
I need to make all the possible combinations for the numbers using a recursion but satisfying a condition that the next number clubbed with the present one can only be from specific numbers given by a hashmap:
ex When the recursion takes 1 the next number can be from {0,4,5,2,6} (from the HaspMap),and then if i make 10,the next number can be from {1,4,5} and so on
static HashMap<Integer,Integer[]> possibleSeq = new HashMap<Integer,Integer[] >();
private static void initialize(HashMap<Integer,Integer[]> possibleSeq) {
possibleSeq.put(0,new Integer[]{1,4,5});
possibleSeq.put(1,new Integer[]{0,4,5,2,6});
possibleSeq.put(2,new Integer[]{1,3,5,6,7});
possibleSeq.put(3,new Integer[]{2,6,7});
possibleSeq.put(4,new Integer[]{0,1,5,8,9});
possibleSeq.put(5,new Integer[]{0,1,2,4,6,8,9,10});
possibleSeq.put(6,new Integer[]{1,2,3,5,7,9,10,11});
possibleSeq.put(7,new Integer[]{2,3,6,10,11});
possibleSeq.put(8,new Integer[]{9,4,5,12,13});
possibleSeq.put(9,new Integer[]{10,4,5,8,6,12,13,14});
possibleSeq.put(10,new Integer[]{7,6,5,9,11,15,13,14});
possibleSeq.put(11,new Integer[]{6,7,10,14,15});
possibleSeq.put(12,new Integer[]{8,9,13});
possibleSeq.put(13,new Integer[]{8,9,10,12,14});
possibleSeq.put(14,new Integer[]{9,10,11,13,15});
possibleSeq.put(15,new Integer[]{10,11,14});
}
Note: I am required to make all the possible numbers beginning from digit length 1 to 10.
Help!
Try with something like this, for starters:
void findPath(Set paths, Stack path, int[] nextSteps, Set numbersLeft) {
if (numbersLeft.isEmpty()) {
//Done
paths.add(new ArrayList(path));
return;
}
for (int step:nextSteps) {
if (numbersLeft.contains(step)) {
// We can move on
path.push(step);
numbersLeft.remove(step);
findPath(paths, path, possiblePaths.get(step), numbersLeft);
numbersLeft.add(path.pop());
}
}
}
Starting values should be an empty Set, and empty Stack, a nextSteps identical to you initial array, and a set created from your initial array. When this returns, the paths Set should be filled with the possible paths.
I haven't tested this, and there are bugs as well as more elegant solutions.

Extend java.util.Random to control generation of numbers

Hello I have the following tasks:
First, I am given this code that uses a method to generate random numbers 100 times:
public class Q3 {
public static void printDiceRolls(Random randGenerator) {
for (int i = 0; i < 100; i++) {
System.out.println(randGenerator.nextInt(6) + 1);
}
}
public static void main(String[] args) {
Random man = new Random();
printDiceRolls(man);
}
}
Second, I am asked to make a class LoadedDice that extends the Random class:
public class LoadedDice extends Random {
// instance variables - replace the example below with your own
public int nextInt(int num) {
// code right here
return 3;
}
}
Then I am asked to override the public int nextInt ( int num ) and do the following
Override the public int nextInt(int num) method such that with a 50%
chance, the new method always returns the largest number possible
(i.e., num-1), and with a 50% chance, it returns what the Random's
nextInt method would return
I do not quite understand what my overridden method should do in this case.
Suggestions?
Use another Random instance to give you a 50% chance (e.g. nextInt(100) >= 50) then based on that return a constant or a real random.
I guess one way to do this is to use (another?) random number generator with a uniform distribution and set it to return 0 or 1. The 0/1 would be the 50% for you to make your decision upon.... either returning super.nextInt or the max number.
To me, it looks like the nextInt(int) function comes up with a number between 1 and the input. In the root Random class, this function finds a random number within that range. What they want you to do is change that so that half the time it will return a random number in the range, but the other half the time it will give the maximum number.
In the example they gave, you're rolling a dice, so the range is 1-6. Normally, nextInt will find a random number between 1 and 6. But your new function will only do that half the time. The other half the time, it will return 6.
I have an idea on how you can implement that, but it seems like it would be cheating to go that far. ^^;
if(super.nextBoolean())
return num-1;
return super.nextInt(num);
if num<Integer.MAX/2, we can
int x = super.nextInt(num*2);
return Math.min(x, num-1);

Categories