Rolling m die with n sides x times - java

Okay so I changed my code around and deleted a lot of the unnecessary garbage in it. It works for some numbers but not for others, for example, when I put in 100 rolls/8 sides/3 die it gives me an out of bounds error despite the limits I've set for it. Obviously I've looked over some detail, I'm just not sure what detail it is.
public class Ass11f {
public static void main(String[] args) {
EasyReader console = new EasyReader();
System.out.print("Enter how many times you want to roll the die: ");
int numRolls = console.readInt();
System.out.print("Enter the amount of sides: ");
int numSides = console.readInt();
System.out.print("Enter the amount of die: ");
int numDie = console.readInt();
int[] rollSum = new int[numDie*numSides];
for (int i = 0; i<numRolls; ++i)
{
int rollCounter=0;
for (int l = 0; l<numDie; ++l){
rollCounter += ((int)(Math.random()*numSides)+1);
}
rollSum[rollCounter]++;
}
for (int m = 2;m<=rollSum.length;++m) System.out.println(m+"'s: "+rollSum[m]+" times, "+((((double)rollSum[m])/numRolls)*100)+"%");
}
}

There are two base problems:
When adding roll totals, you're trying to add the maximum roll in an index one past the end of the array. The easy fix is to simply add 1 to the length of your array.
When printing, you cannot access an array using an index equal to the array's length, which is what m<=rollSum.length will eventually do. Replace that with m < rollSum.length so it stops before the final value.
Also, here's some ways to make your array creation a bit clearer:
// The minimum value is always numDie.
// The maximum is always numDie * numSides
// There are maximum - minimum + 1 possible values (ie 6 on a d6)
int maximum = numDie * numSides;
int minimum = numDie;
// Remember, index zero is now the minimum roll.
// The final index is the maximum roll. So the count at an index is really
// the count for any roll with value index + minimum
int[] rollSum = new int[maximum - minimum + 1];
I also recommend splitting up that print statement. It's a bit easier to read and debug. Also, you can start at numDie instead of 2 to account for when you have more or less die than 3:
for (int i = numDie; i < rollSum.length; ++i) {
// Print the first bit, ie "2's: ".
System.out.print(i + "'s: ");
// How many times was that value rolled?
System.out.print(rollSum[i] + " times, ");
// What percentage is that?
double percentage = ((double)rollSum[i]) / numRolls * 100;
System.out.println(percentage + "%");
}

Related

Finding Max value in for Loop

I'm a beginner at java and was just wondering how to find the max and minimum value from integers declared in a for loop (using a scanner to obtain user input) this program creates an object from a class Car and obtains information on the name, registration, colour and number of trips.
The number of trips prompts the for loop to print out odometer readings from 0 (odometer's initial reading) to whatever the variable carSample.numberOfTrips specifies.
I've tried declaring a new variable; int maximum = carSample.odometerReading.MAX_VALUE; (Then printing it)
aswell with minimum, however to no success; I receive the following error:
TestCar.java:25: error: int cannot be dereferenced
int maximum = carSample.odometerReading.MAX_VALUE;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
car carSample = new car(); // Creates object of class Car
carSample.name = input.nextLine();
carSample.registration = input.nextLine();
carSample.colour = input.nextLine();
carSample.numberOfTrips = input.nextInt();
for (int i = 0; i < carSample.numberOfTrips; i++) {
System.out.print("Odometer reading " + (i) + ": ");
int odometerReading = input.nextInt();
}
Any help or insight into how this can be peformed is really appreciated, thank you for your time!
int maximum = Integer.MIN_VALUE;
for (int i = 0; i < carSample.numberOfTrips; i++) {
System.out.print("Odometer reading " + (i) + ": ");
int odometerReading = input.nextInt();
if (odometerReading > maximum) {
maximum = odometerReading;
}
}
System.out.println(maximum); // Maximum value
If readings are for example 20 10 22 41 11
Do the first reading. 20
And use that value as your maximum and also minimum. So maximum = 20 and minimum = 20.
Then for the other readings, compare the reading to the current maximum and minimum and update the maximum and minimum accordingly.
E.g: second reading: 10. 10 is less than current maximum of 20, so no change in maximum. 10 is less than current minimum of 20, so update minimum to 10....and repeat for the remainder of the loop.

Array keeps counting 0 as a number when I didn'

I'm trying to make a game show program where I enter the number of contestants, how fast they hit the buzzer, the fastest and slowest times for hitting the buzzer, and the number of people that hit the buzzer faster than average.
Everything goes well with my program when I have 5 contestants. But if I enter 4 contestants or anything else less than 5, it messes up some things. When I have 4 contestants, my fastest time is 0, even when I'm not putting in a 0 as a time, and the number of contestants that hit the buzzer faster than average is also messed up, having one extra than it should, because it's putting in a 0.
How do I stop this program from adding in a 0 when I don't have 5 contestants?
import java.util.Scanner;
public class FastestFingers {
public static void main(String[] args) {
//declare varialbes
int contestants;
int [] milisecs = new int [6];
int fastest, slowest, i;
int faster = 0;
double average;
Scanner scanInt = new Scanner (System.in);
//make user enter number of contestants
System.out.println ("Enter # of contestants: ");
contestants = scanInt.nextInt();
//make user enter times
for(i=1;i<=contestants;i++)
{
System.out.println ("Time (ms): ");
milisecs[i] = scanInt.nextInt();
}
//calculate fastest time
fastest = milisecs[1];
for(i=1;i<milisecs.length;i++)
{
if(milisecs[i] < fastest)
{
fastest = milisecs[i];
}
}
System.out.println ("Fastest: " + fastest);
//calculate slowest time
slowest = milisecs[1];
for(i=1;i<milisecs.length;i++)
{
if(milisecs[i] > slowest)
{
slowest = milisecs[i];
}
}
System.out.println ("Slowest: " + slowest);
//tell program how to find average
int total = 0;
for(i=1;i<milisecs.length;i++)
{
total = total + milisecs[i];
}
average = total/contestants;
//find numbers faster than the average
int count = 0;
for(i=1;i<milisecs.length;i++)
{
if(milisecs[i]<average)
{
count++;
}
}
System.out.println ("Faster than average: " + count);
}
}
You create an int[] of fixed size 6. Then you compare the last 5 values to find the lowest. All int values are default 0. If you only set 4 values to anything larger than 0 the fifth value will always be 0 and therefore your lowest value.
You can fix this problem by setting the size of your array to the number of contestants.
Also remember that arrays start counting at 0 not at 1. Your loops should therefore be:
for(i=0;i<milisecs.length;i++), etc.
The problem is that you initialize the array to have six elements.
int [] milisecs = new int [6];
By default all of these values will be zero. Then in your loop you only initialize four of them, meaning that two will still be zero. Change your code to:
System.out.println ("Enter # of contestants: ");
contestants = scanInt.nextInt();
int [] milisecs = new int [contestants];
This will ensure that you will only have as many time slots as you have contestants.
Also array indexes start at zero, so you should change
fastest = milisecs[1];
to
fastest = milisecs[0];
And in your loops, start your variable at 0 instead of 1.
Array Index should start with 0. Please be careful with this. You code reads input and assigns to the milisecs starting from index 1.

Processing numbers program

Firstly, I'm taking AP Computer Science this year, and this question is related to an exercise we were assigned in class. I have written the code, and verified that it meets the requirements to my knowledge, so this is not a topic searching for homework answers.
What I'm looking for is to see if there's a much simpler way to do this, or if there's anything I could improve on in writing my code. Any tips would be greatly appreciated, specific questions asked below the code.
The exercise is as follows: Write a program called ProcessingNumbers that does:
Accepts a user input as a string of numbers
Prints the smallest and largest of all the numbers supplied by the user
Print the sum of all the even numbers the user typed, along with the largest even number typed.
Here is the code:
import java.util.*;
public class ProcessingNumbers {
public static void main(String[] args) {
// Initialize variables and objects
Scanner sc = new Scanner(System.in);
ArrayList<Integer> al = new ArrayList();
int sumOfEven = 0;
// Initial input
System.out.print("Please input 10 integers, separated by spaces.");
// Stores 10 values from the scanner in the ArrayList
for(int i = 0; i < 10; i++) {
al.add(sc.nextInt());
}
// Sorts in ascending order
Collections.sort(al);
// Smallest and largest values section
int smallest = al.get(0);
int largest = al.get(al.size() - 1);
System.out.println("Your smallest value is " + smallest + " and your largest value is " + largest);
// Sum of Even numbers
int arrayLength = al.size();
for (int i = 0; i < al.size(); i++) {
if (al.get(i) % 2 == 0) {
sumOfEven += al.get(i);
}
}
System.out.println("The sum of all even numbers is " + sumOfEven);
// Last section, greatest even number
if (al.get(arrayLength - 1) % 2 == 0) {
System.out.println("The greatest even number typed is " + al.get(arrayLength - 1));
} else {
System.out.println("The greatest even number typed is " + al.get(arrayLength - 2));
}
sc.close();
}
}
Here are specific questions I'd like answered, if possible:
Did I overthink this? Was there a much simpler, more streamlined way to solve the problem?
Was the use of an ArrayList mostly necessary? We haven't learned about them yet, I did get approval from my teacher to use them though.
How could I possibly code it so that there is no 10 integer limit?
This is my first time on Stackoverflow in quite some time, so let me know if anything's out of order.
Any advice is appreciated. Thanks!
Usage of the ArrayList wasn't necessary, however it does make it much simpler due to Collections.sort().
To remove the 10 integer limit you can ask the user how many numbers they want to enter:
int numbersToEnter = sc.nextInt();
for(int i = 0; i < numbersToEnter; i++) {
al.add(sc.nextInt());
}
Another note is that your last if-else to get the highest even integer doesn't work, you want to use a for loop, something like this:
for (int i = al.size() - 1; i >= 0; i--) {
if (al.get(i) % 2 == 0) {
System.out.println("The greatest even number typed is " + al.get(i));
break;
}
I wouldn't say so. Your code is pretty straightforward and simple. You could break it up into separate methods to make it cleaner and more organized, though that isn't necessary unless you have sections of code that have to be run repeatedly or if you have long sections of code cluttering up your main method. You also could have just used al.size() instead of creating arrayLength.
It wasn't entirely necessary, though it is convenient. Now, regarding your next question, you definitely do want to use an ArrayList rather than a regular array if you want it to have a variable size, since arrays are created with a fixed size which can't be changed.
Here's an example:
int number;
System.out.print("Please input some integers, separated by spaces, followed by -1.");
number = sc.nextInt();
while (number != -1) {
al.add(number);
number = sc.nextInt();
}
Here is a solution that:
Doesn't use Scanner (it's a heavyweight when all you need is a line of text)
Doesn't have a strict limit to the number of numbers
Doesn't need to ask how many numbers
Doesn't waste space/time on a List
Handles the case when no numbers are entered
Handles the case when no even numbers are entered
Fails with NumberFormatException if non-integer is entered
Moved actual logic to separate method, so it can be mass tested
public static void main(String[] args) throws Exception {
System.out.println("Enter numbers, separated by spaces:");
processNumbers(new BufferedReader(new InputStreamReader(System.in)).readLine());
}
public static void processNumbers(String numbers) {
int min = 0, max = 0, sumOfEven = 0, maxEven = 1, count = 0;
if (! numbers.trim().isEmpty())
for (String value : numbers.trim().split("\\s+")) {
int number = Integer.parseInt(value);
if (count++ == 0)
min = max = number;
else if (number < min)
min = number;
else if (number > max)
max = number;
if ((number & 1) == 0) {
sumOfEven += number;
if (maxEven == 1 || number > maxEven)
maxEven = number;
}
}
if (count == 0)
System.out.println("No numbers entered");
else {
System.out.println("Smallest number: " + min);
System.out.println("Largest number: " + max);
if (maxEven == 1)
System.out.println("No even numbers entered");
else {
System.out.println("Sum of even numbers: " + sumOfEven);
System.out.println("Largest even number: " + maxEven);
}
}
}
Tests
Enter numbers, separated by spaces:
1 2 3 4 5 6 7 8 9 9
Smallest number: 1
Largest number: 9
Sum of even numbers: 20
Largest even number: 8
Enter numbers, separated by spaces:
1 3 5 7 9
Smallest number: 1
Largest number: 9
No even numbers entered
Enter numbers, separated by spaces:
-9 -8 -7 -6 -5 -4
Smallest number: -9
Largest number: -4
Sum of even numbers: -18
Largest even number: -4
Enter numbers, separated by spaces:
No numbers entered

Find the Max/Min of values within a for loop

I've searched for answers to this specific question, but haven't been able to find anything. I need to find the maximum and minimum of the input numbers but the values I need are inside the for loop and I can't figure out how to use them outside of it.
System.out.print("How many numbers do you want to input?");
int totalNumbers = console.nextInt();
int minMax = 0;
for(int i = 1; i <= totalNumbers; i++){
System.out.print("Number " + i + ": ");
int inputNumbers = console.nextInt();
}
System.out.println();
int smallest = Math.min(minMax);
System.out.println("Smallest = " + smallest);
int largest = Math.max(minMax);
System.out.println("Largest = " + largest);
I don't need changed code just something that will get me on the right track.Thank you!
Can you notice the problem with the following loop?
for(int i = 1; i <= totalNumbers; i++){
System.out.print("Number " + i + ": ");
int inputNumbers = console.nextInt();
}
You are running the loop totalNumbers times and every time you create a new int with name inputNumbers and store the value received from console. Also where are you changing the value of minMax? Also Math.min(or max) does not take single paramtere and wont even compile.
Now you have few options:
Either store all the numbers in an array and then traverse that for min and max elements using some utility method.
Set some min and max value and run a loop to get all items and also keep track of min and max in loop.
I am not writing any solution as I want you to try it yourself.
The Math.min() and Math.max() methods, according to the oracle documentation, can only compare two values. Importing the values into an array, and then performing operations on the array, should allow you to find minimums and maximums, as well as any other data operation quite easily.
int[] numbers = new int[totalNumbers];
for (int i = 0; i < totalNumbers; i++) {
numbers[i] = console.nextInt();
}
//Other Operations
Unless I'm misreading what you want, can't you just maintain a variable on the outside of the for loop and check them?
int minMax = 0;
int smallest = 0;
int largest = 0;
for(int i = 1; i <= totalNumbers; i++){
System.out.print("Number " + i + ": ");
int inputNumbers = console.nextInt();
if(inputNumbers > largest){
largest = inputNumbers;
} else if (inputNumbers < smallest){
smallest = inputNumbers;
}
}
System.out.println();
System.out.println("Smallest = " + smallest);
System.out.println("Largest = " + largest);
This is the most direct and logical way of checking the input values and deciding whether they're the smallest or largest currently known (Edit: Unless you require the use of Math.minMax)
Pseudocode:
smallest := +∞
largest := -∞
for each number read, n:
if n > largest:
largest := n
if n < smallest:
smallest := n
print the results
Hint:
Java ints can't represent ±∞. Use Integer.MIN_VALUE and Integer.MAX_VALUE instead.
You can do it by just put if else condition inside for loop... like
take 2 variable at outside loop one for max value and other for min value store.
inside loop assign input number to min and max first time.
after that comare next number with this and reassign values.
at end of loop you will find both min and max.

Java While loop skipping lines, doing them every 2 cycles instead

I'm writing a program for homework that is supposed to read in an unspecified number of 0-100 scores (maximum of 100 scores) and stop after -1 or any negative number is entered.
I've put this into a Do While loop that is set to terminate when -1 is pulled in through Scanner. The loop has a counter that keeps track of how many times the loop has been gone through, an adder that adds all the input lines together to later compute an average, and a means to send the input value to an array after it has checked to see if the number is -1.
Instead of doing this, the loop only increments the counter every 2 loops and -1 will only terminate the loop on an even cycle number, other wise it will wait until the next cycle to terminate. This completely baffles me, I have no idea why it's doing this. Could someone point out the error? Thanks in advance! This is all I have so far.
import java.util.Scanner;
public class main {
//Assignment 2, Problem 2
//Reads in an unspecified number of scores, stopping at -1. Calculates the average and
//prints out number of scores below the average.
public static void main(String[] args) {
//Declaration
int Counter = 0; //Counts how many scores are
int Total = 0; //Adds all the input together
int[] Scores = new int[100]; //Scores go here after being checked
int CurrentInput = 0; //Scanner goes here, checked for negative, then added to Scores
Scanner In = new Scanner(System.in);
do {
System.out.println("Please input test scores: ");
System.out.println("Counter = " + Counter);
CurrentInput = In.nextInt();
Scores[Counter] = CurrentInput;
Total += In.nextInt();
Counter++;
} while ( CurrentInput > 0);
for(int i = 0; i < Counter; i++) {
System.out.println(Scores[i]);
}
System.out.println("Total = " + Total);
In.close();
}
}
CurrentInput = In.nextInt();
Scores[Counter] = CurrentInput;
Total += In.nextInt();
You are calling twice In.nextInt(), i.e., you are reading two lines in each loop iteration.
CurrentInput = In.nextInt();
Scores[Counter] = CurrentInput;
Total += CurrentInput;
Use this instead.

Categories