I made a quick program recently to have the computer guess a number you input. I was just using it to show a friend an example of a While loop. I decided I wish to make it more complicated but I'm not sure how to do it.
I wish to add each random guess to an array so that it doesn't guess the same number more than once.
Scanner scan = new Scanner (System.in); // Number to guess //
Random rand = new Random(); // Generates the guess //
int GuessNum = 0, RandGuess = 0;
System.out.println("Enter a number 1 - 100 for me to guess: ");
int input = scan.nextInt();
if (input >= 1 && input <= 100)
{
int MyGuess = rand.nextInt (100) + 1;
while ( MyGuess != input)
{
MyGuess = rand.nextInt (100) + 1;
GuessNum++;
}
System.out.println ("I guessed the number after " + GuessNum + " tries.");
}
You might want to use an ArrayList(A dynamically increasing array)
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(num);
If you want to see if that number is already added into the arraylist
if(list.contains(num))
{
System.out.println("You already tried " + num);
}
A Set is also considerably better option. It is the same as a ArrayList but doesn't allow duplicates.
HashSet<Integer> set = new HashSet<Integer>();
set.add(num);//returns true if the num was not inserted before else return false
if(!set.add(num))//set also has a contains method
{
System.out.println("You already entered " + num);
}
A Set is an appropriate container for that functionality. You would define it like this :
Set<Integer> previous = new HashSet<>();
And to get a random number that you haven't previously tried
while (previous.contains(MyGuess))
MyGuess = rand.nextInt(100) + 1;
previous.add(MyGuess);
This will get new random numbers from rand object until one is found that isn't in previous. Then that is added to previous for the next iteration.
Arrays in Java are of fixed size. Once you have allocated an array, adding elements is allowed only up to the number of elements that you have allocated upfront. This wouldn't be a big issue in your situation, because the values are limited to 100, but you have better alternatives:
Java library offers collections that grow dynamically. In your case a HashSet<Integer> would be a good choice:
HashSet can grow to an arbitrary size as you go
Checking HashSet for a number is a quick operation
Another solution would be to make an array of 101 booleans:
boolean[] seen = new boolean[101];
Now you can check if the number has been seen before by testing seen[myGuess] to be false, and set seen[myGuess] = true when you see a new number. This approach is also very fast. However, you need to keep track of how many available numbers you have, because the range from 1 to 100 will get exhausted after 100 guesses, so trying to generate an additional number would become an infinite loop.
Use a HashSet<Integer> to do this. The values in a Set are unique so this is an easy way to store the already guessed values.
The contains(...) method is how you find out if you've guessed this number before
A very simple example would be:
public static int[] randomArray(){
int number = Integer.parseInt(JOptionPane.showInputDialog("How many numbers would you like to save?: ")); //Get Number of numbers from user
int[] array = new int[number]; //Create the array with number of numbers (by User)
for(int counter = 0; counter < number; counter++){ //For loop to get a new input and output every time
int arrayString = (int) (Math.random() * 10);
array[counter] = arrayString;
System.out.println("Number " + (counter + 1) + " is: " + array[counter]); //Print out the number
}
return array;
}
This example adds numbers every time the loop repeats, just replace the random with the number you want.
The easiest way would be to add an ArrayList and just to check if the list contains the random value:
Ar first you make and new ArrayList:
ArrayList<Integer> myGuesses = new ArrayList();
The second step is to add the random value to the list:
ArrayList<Integer> myGuesses = new ArrayList();
Now you only have to check if if the List cotains the value bevore generating a new one and counting your trys:
if(myGuesses.contains(MyGuess))
{
//your code
}
I applied this to your code:
Scanner scan = new Scanner(System.in); // Number to guess //
Random rand = new Random(); // Generates the guess //
int GuessNum = 0, RandGuess = 0;
ArrayList<Integer> myGuesses = new ArrayList();
System.out.println("Enter a number 1 - 100 for me to guess: ");
int input = scan.nextInt();
if (input >= 1 && input <= 100) {
int MyGuess = rand.nextInt(100) + 1;
while (MyGuess != input) {
if(myGuesses.contains(MyGuess))
{
MyGuess = rand.nextInt(100) + 1;
GuessNum++;
myGuesses.add(MyGuess);
}
}
System.out.println("I guessed the number after " + GuessNum + " tries.");
}
I hope that helps!
Related
I need to create a program that asks the customer how many packages they have (after the input it creates an array of that size) which then ask the customer to enter the weights of them. It then has to sort the packages into small, medium, or large and then prints how many of each size package there is.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int small = 0;
int medium = 0;
int large = 0;
int size = 0;
int[] intArray = {size};
System.out.printf("Please enter the number of weights to enter: ");
size = scan.nextInt();
for (double i = 0; i < intArray.length; i++){
if (i < size)
System.out.print("Please Enter weight1: ");
double weights = scan.nextInt();
System.out.println("\nPackage Weights");
System.out.print(weights);
if (weights <= 5)
small = 1 + small;
if (weights <= 10 && weights >= 6)
medium = 1 + medium;
if (weights >= 11)
large = 1 + large;
System.out.println("\n\nSmall: " + small);
System.out.println("Medium: " + medium);
System.out.println("Large:" + large);
}
}
}
I got the sorting to work, but I can only get it to ask for one package, which means my array and loop aren't working. Just now learning arrays / loops so i'm kinda stuck on this.
It only asks for one package because you initialize intArray as an array containing exactly one element. Instead of pointlessly initializing it in its declaration, before you even know how large it needs to be, create and assign the needed array after you input its length. At your option, you can move the whole declaration there:
// ...
size = scan.nextInt();
int[] intArray = new int[size];
Inasmuch as that's the case, I'm inclined to doubt your claim that you had the sorting part working -- you don't have a suitable place to store the weights that are entered. Perhaps you cut that part out of the code you presented. Indeed, if your program ever had any semblance of sorting then you must have performed quite a hack job on it.
The problem is the time at which your intArray is initialised.
It gets initialised just after size is initialized with the value of 0.
Therefore you end up with a single Element in your array.
All you have to do is move the initialisation of your intArray after the user input:
int[] intArray;
System.out.printf("Please enter the number of weights to enter: ");
size = scan.nextInt();
intArray = new int[size]; //<-- initialization of the array after the user input
for (double i = 0; i < intArray.length; i++){
I am writing code to Generate an Array of 100 random numbers between 1 and 100 .
I then want to ask the user for a number and then search for that number in the array. If the number is present i want to remove it from the array and ask the user for another number. I want to repeat this until the user guesses
incorrectly. If the user guesses incorrectly, I want to output the remaining Array contents in reverse order.
I think I have everything written correctly, but here is my Question; I can't get my head around how to have the program keep asking if the guesses are correct.
Here is my code, I know it's just a well placed for loop that is needed,I just can't see where. I would really appreciate some help on this. Thank you! I'm not looking for someone to give me the code needed just a steer.
int[] randomArray = new int[10];
// For loop to fill the array with random elements from 1 to 100
for (int i = 0; i < randomArray.length; i++) {
randomArray[i] = (int) (Math.random() * 100);
// Print the array
System.out.print(randomArray[i] + ", ");
}
// Print a blank line
System.out.println();
Scanner input = new Scanner(System.in);
// Declare an int variable to hold the number
int searchNumber;
// Ask the user to enter a number
System.out.println("Please enter a number to search for between 1 and
100: ");
// Initialise the int variable with the number entered
searchNumber = input.nextInt();
// initialise boolean as false
boolean found = false;
// for loop to search the array for the value entered by the user
for (int i = 0; i < randomArray.length; i++) {
if (searchNumber == randomArray[i]) {
// If found then set boolean to true
found = true;
// If found print out the index where it was found and inform
the user that it
// will be removed from the array
System.out.println("Your number was found at index " + i + "
and will be deleted from the array:");
// create a new array which is one element shorter than the
original
int[] result = new int[randomArray.length - 1];
// Copy the the new array from the original array
System.arraycopy(randomArray, 0, result, 0, i); // i is the
element to be removed
System.arraycopy(randomArray, i + 1, result, i, result.length -
i);
// Print the new array without the element i
System.out.println(Arrays.toString(result));
}
}
// code to inform the user if their value was not found and print the
array in
// reverse
if (!found) {
// Print text telling the user that the number was found and the
array will be
// printed in reverse
System.out.println("Your number was not found, here is the array in
reverse");
// For loop to print the array in reverse
for (int k = randomArray.length - 1; k >= 0; k--)
System.out.print(randomArray[k] + ", ");
}
}
Question; I can't get my head around how to have the program keep asking if the guesses are correct.?
Then you should build your logic around some do while loop.
//Initialize random values here.
do{
//Get input & process.
//Do all Logics.
}while( exit condition based on your logic else process input again )
This should do it. I hope.
Im looking to fill an array with doubles from the user using Scanner. However, I am having difficulties because of Java's inability to alter array size. I need to get around this somehow. My idea for getting around this was to first have the user enter how many doubles he will be putting into the array.
System.out.print("How many numbers would you like to put in the array?: ");
int num = in.nextInt();
while(num >= 0) {
double[] array[] = new double[num][];
System.out.println("Enter the " + num + " numbers now.");
}
This is what I have so far but it is clear that it will not function as intended.
You need to:
Decrement num or option (3)
Initialize your array outside the loop
Start saving numbers from array position 0
Here is how that would be done:
System.out.print("How many numbers would you like to put in the array?: ");
int num = in.nextInt();
int position = 0;
double[] array = new double[num];
while(position < num) {
System.out.println("Enter the " + num + " numbers now.");
array[position++] = in.nextDouble();
}
As you already know how many numbers the user will provide, Consider Using an ArrayList
ArrayList<Double> list = new ArrayList<Double>();
for(int i = 0;i< num;i++){
//Ask for a value
//add that value to the list
}
Using a simple for loop, you can ask each value, an add it to the list.
This question already has answers here:
Random Number Generator: mainly how to stop repetition of numbers. Java
(6 answers)
Closed 9 years ago.
Ok so the objective is to generate 6 random numbers per line/row. With x number of rows (set by the user via UserInput). Each row MUST have unique numbers (non-duplicated numbers). I'm pretty sure the numbers are unique, however I can't seem to get it to have multiple rows, and I cannot figure out for the life of me what part is preventing multiple rows.
package rtg;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class Array {
public static void main(String[] args) {
String name;
int noTickets;
int[] numbers = new int[6];
Set<Integer> randomNumbers = new HashSet<>();
Random rand = new Random();
int ticketCount = 1;
System.out.println("Please input your name");
name = UserInput.readString();
System.out.println("Please input the number of tickets you want");
noTickets = UserInput.readInt();
System.out.println("___________________________________________\n___________________________________________");
System.out.println("___________________________________________\n___________________________________________");
System.out.println("Name: " +name+ "\nNumber of Tickets: " +noTickets+ "\nNumbers: ");
for (ticketCount = 1; ticketCount <= noTickets; ++ticketCount){
while (randomNumbers.size() < 6) {
randomNumbers.add(rand.nextInt(50) + 1);
}
int i = 0;
for (Integer n : randomNumbers) {
numbers[i++] = n;
}
System.out.print( Arrays.toString(numbers) + "\n");
}
}
}
EDIT Thanks a lot everyone, I finally got there, turns out I put the array in the wrong place (it was outside the for loop so only made 1 set of random numbers) Fixed it now. Next challange; having a comparison program to scan 90+ sets of 6 unique numbers, and comparing if any of them match a different set (per row/set >.<)
You can stuff random integers into a Set<Integer> until it has six elements:
Set<Integer> randomNumbers = new HashSet<>();
Random rand = new Random();
while (randomNumbers.size() < 6) {
randomNumbers.add(rand.nextInt(50) + 1);
}
Alternatively, you can generate the numbers 1-50, shuffle them, and pick any six elements:
List<Integer> numbers = new ArrayList<>(50); // known capacity
for (int i = 1; i <= 50; ++i) { numbers.add(i); }
Collections.shuffle(numbers);
List<Integer> sixRandomNumbers = numbers.subList(0, 6);
The first solution does extra work whenever there is a collision; this extra work goes up the greater the ratio is of desired to total numbers. The second does extra work by having to deal with all 50 numbers; the extra work goes down the greater the ratio is of desired to total numbers. It's an interesting question where the cross-over point is.
EDIT (Responding to the edit to the original question) After you use one of the above methods to generate six distinct, random numbers, you need to put them into the variables you are going to use. One way (say, using the first method) is as follows:
int[] numbers = new int[6];
Set<Integer> randomNumbers = new HashSet<>();
Random rand = new Random();
while (randomNumbers.size() < 6) {
randomNumbers.add(rand.nextInt(50) + 1);
}
System.out.println("Six random numbers: " + randomNumbers.toString());
// if you need them as an `int` array:
int i = 0;
for (Integer n : randomNumbers) {
numbers[i++] = n;
}
The numbers array replaces your variables number1, ..., number6.
Use a data type which allows you to check if the int has already been created. For example, adding them to an ArrayList<Integer>.
ArrayList<Integer> numbers = new ArrayList<Integer>();
while(numbers.size() < 6) {
int num = rand.nextInt(50) + 1;
if(!numbers.contains(num)) {
numbers.add(num);
}
}
Of course, as #sanbhat says in the comments, you can use a Set<Integer> and avoid the if() conditional entirely in the loop. However I thought this would be more intuitive for a beginner who doesn't know that the Set API will not add a duplicate element.
Save a sorted list or more efficiently a set of the previously chosen values and check your current selection against the previous ones, if it was previously chosen try again.
If you know the valid range of your random numbers and if the size of that range is not prohibitive, one simple algorithm would be as follows:
Create an array with a size equal to your number range
Consecutively fill your array with the numbers in your number range
Iterate through the list an arbitrarily large number of times; generate two pseudorandom numbers that are within your array indices, and swap the two elements at those indices
After the iteration is complete, you will have an array of uniquely represented numbers that are all within your number range that appear in a random order. This nearly exactly simulates what happens when one shuffles a deck of cards.
You can then write a simple method to consecutively pop numbers out of your array each time it is called.
An advantage of this algorithm is that it can be implemented as an array of primitives, eg. int[], without any need for the Java Collections API.
I'm trying to get random numbers 0 - 499 in sets of 2 based on what the user inputs. For example 234 and 58, and thats one set, but the user may prompt that they wan 8 sets. Im trying to make sure that a redundant number doesnt show up, like 234 & 58, 12 & 444, 198 & 58. (58 showed up twice.)
The way im trying to prevent this is by putting the found numbers into an array and when i go around the next match im checking in the array to make sure they havent been used yet. Was just wondering what the best way of this would be. Like obviously on the first go around no numbers have been chosen yet so i dont need to check. but then the next go around what if i get a redundant? i will get numbers and then check the array, and if it is already in the array how do i go back and get new numbers? a do while loop maybe?
here is what im doing:
//now add the specified number of random connections
System.out.println();
System.out.println("new connection(s): ");
//array for keeping track of the new connections to prevent redundant add's
int redundant [] = new int[con*2];
for( int i = 1; i <= con; i++ ){
Random ran = new Random();
if( i == 1){
int ran1 = ran.nextInt(sWorld.length-1) + 1;
int ran2 = ran.nextInt(sWorld.length-1) + 1;
redundant[i - 1] = ran1;
redundant[i] = ran2;
System.out.println(" " + ran1 + " - " + ran2);
}
else{
int ran1 = ran.nextInt(sWorld.length-1) + 1;
int ran2 = ran.nextInt(sWorld.length-1) + 1;
//need help
}
thanks in advance!
EDIT. Going with a maethod below (using collections)
List<Integer> nums = new LinkedList<Integer>();
for( int i = 0; i <= 499; i++ ){
nums.add(i);
}
//shuffle the collection for more randomness
System.out.println();
System.out.println("new connection(s): ");
for (int x = 1; x <= con; x++){
Collections.shuffle(nums);
Random ran = new Random();
int r1 = nums.remove(ran.nextInt(nums));
int r2 = nums.remove(ran.nextInt(nums));
but having trouble getting the random numbers, any help?
Just fill a collection with all indices in the desired range (i.e. 0 to 499), and then use Collections.shuffle().
One way is to create a list of number from 0-499
List<Integer> nums = new LinkedList<Integer>();
for(int i=0; i<=499; i++) nums.add(i);
Then shuffle the the list
Collections.shuffle(nums);
Then each time you need a non-recurring random number between 0-499, just remove an element from the list
int x = nums.remove()
Use a while cycle and use an array. While your index is not out of scope generate two numbers. Add them to the array if they are not redundant and increase your index accordingly. If they are redundant, do nothing, the next iteration of the while cycle will generate two new numbers anyway.