I am working on a basic program (console).
The program should allow the user to enter in various marks, until the mark entered exceeds 100. At this point the program should display a histogram. Each star represents a student who achieved a module mark in the range shown.
This is an example of the output.
0 - 29 xxx
30 - 39 xxxxx
40 - 69 xxxxxxx
70 - 100 xxxx
20 students in total.
As the user enters each mark, there ought to be a counter that increases in value and print the total number of marks entered.
I want to make sure that the program is as efficient as possible but also understandable
Code
Working with #Dici on collabedit I have an amazing answer to my question:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] ranges = { 0,29,39,69,100 };
int[] inRange = new int[ranges.length - 1];
int mark;
do {
System.out.println("Enter Mark:");
mark = sc.nextInt();
for (int j=1 ; j<ranges.length ; j++)
if (ranges[j-1] <= mark && mark <= ranges[j]) {
inRange[j-1]++;
break;
}
} while (mark <= 100);
System.out.println(Arrays.toString(inRange));
String s = "The number of students that have scored between %d and %d is: ";
int k = 0;
for (int i=0 ; i<ranges.length - 1 ; i++) {
System.out.print(String.format(s,ranges[i] + k,ranges[i + 1]));
for (int r = 0; r<inRange[i] ; r++)
System.out.print("*");
System.out.println();
k = 1;
}
sc.close();
Thank you again for your amazing help!
As we did it together on Collabedit, here is a working code for your question :
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] ranges = { 0,29,39,69,100 };
int[] inRange = new int[ranges.length - 1];
int mark;
do {
System.out.println("Enter Mark:");
mark = sc.nextInt();
for (int j=1 ; j<ranges.length ; j++)
if (ranges[j-1] <= mark && mark <= ranges[j]) {
inRange[j-1]++;
break;
}
} while (mark <= 100);
System.out.println(Arrays.toString(inRange));
String s = "The number of students that have scored between %d and %d is : ";
int k = 0;
for (int i=0 ; i<ranges.length - 1 ; i++) {
System.out.print(String.format(s,ranges[i] + k,ranges[i + 1]));
for (int r = 0; r<inRange[i] ; r++)
System.out.print("*");
System.out.println();
k = 1;
}
sc.close();
}
}
Okay. Now that makes sense. If you have a number
int mark = 3;
You can use an if statement
if(mark <= 10){
//do this
}else if(mark <= 20){
//do this
}
You can also use a switch statement, however personal preference leads me to almost always use if statements.
If you want "buckets" you could use
ArrayList<String> marksForStudent = new ArrayList<>();
the documentation for that is here.
https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
Or, alternatively and probably what you want is a hashmap. With the student's name or other unique identifier as the key and then a collection to contain their marks.
HashMap<String, ArrayList<String>> gradesForStudents = new HashMap<>();
gradesForStudents.put("Marc",Arrays.asList("99","98","100"));
Something like that.
Quick suggestion: do not alter marksInsp inside the loop if that's your loop index.
Paulinho made the excellent suggestion of using the modulo operator. I'll extend that here to a map, since you didn't specify the upper mark limit:
public static void main(String[] args) {
int currentMark, currentBucket;
final int BUCKET_WIDTH = 30;
Map<Integer, Integer> markRanges = new HashMap<Integer, Integer>();
for(int i = 0; i < 101; i++) {
Scanner input = new Scanner(System.in);
System.out.print("Enter Marks: ");
currentMark = input.nextInt();
currentBucket = currentMark % BUCKET_WIDTH;
if(markRanges.containsKey(currentBucket)) {
// There's already an entry for this bucket
markRanges.put(currentBucket, markRanges.get(currentBucket) + 1);
} else {
// If there isn't, make a new entry
markRanges.put(currentBucket, 1);
}
// Print out grade buckets
for(Integer j : markRanges.keySet) {
System.out.println(String.format("There are %d students with scores between %d and %d", markRanges.get(j), j, j.intValue() + BUCKET_WIDTH - 1));
}
}
}
Related
As the problem states, i must use monte carlo(randomness) to solve the question given. I am running the simulation 1,000,000 times.
import java.util.*;
public class MonteCarlo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter size of the class: ");
int classSize = sc.nextInt();
System.out.println("Please enter the amount of people who share the same birthday: ");
int birthPpl = sc.nextInt();
System.out.println("calculate the probability that "+birthPpl+" people share the same Birthday in a class size of "+classSize);
sc.close();
int birthdays [] = new int[classSize];
int simulations = 0;
int success=0;
for(int i=0; i<1000000; i++){
simulations++;
if(Collision(birthdays)>=birthPpl){
success++;
}
}
System.out.println(success+" "+simulations);
System.out.println("Answer: "+ (success*100)/simulations + "%");
}
public static int Collision(int birthday[]){
Random rand = new Random();
for(int i=1; i<birthday.length; i++){
birthday[i]= rand.nextInt(365);
}
int count = 0;
for(int i=0; i<birthday.length; i++){
for(int j= i+1; j<birthday.length; j++){
if(birthday[i]==birthday[j]){
count++;
}
}
}
return count;
}
}
As per a couple of psuedo code solutions i have seen online i have tried looping through the size of the class x and inserting in a random birthday. then comparing birthdays , reducing the birthdays i look through by 1 each time. I then check the number of collisions against the amount sof ppl who should a birthday , if it is greater or equal to it than i increase the count. i have been given sample imput 20 and 2 which should give 41 % but my program gives eithe 7 or 8 %
What's the problem, and how can it be fixed?
You could also make use the Random and HashMap classes. Map.merge will take the key, a birthday in this case, then a default value of 1, and continues to add 1 to the existing value which is returned and compared to x. Then success is appropriately updated. The Random class provides a variety of methods to return random numbers and is usually preferred over Math.random.
double success = 0;
int tests = 1_000_000;
// instantiate a Random class for selecting the next birthday
Random r = new Random();
// a map to hold the frequency count of same birthdays
Map<Integer,Integer> birthdays = new HashMap<>();
int n = 23;
int x = 2;
for(int i=0; i< tests; i++) {
for (int j = 0; j < n; j++) {
if (birthdays.merge(r.nextInt(365), 1, Integer::sum) >= x) {
success++;
break;
}
}
// clear the map for the next run
birthdays.clear();
}
Using System.out.printf facilitates formatting the output.
System.out.printf("probability = %4.1f%%%n", (success/tests) * 100);
prints something like the following:
probability = 50.7%
import java.util.Scanner;
public class Birthday {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // class size
int x = sc.nextInt(); // people who share the same birthday
double tests = 1_000_000;
double success = 0;
// fills array of birthdays and breaks out when x amount of people share
// a birthday. then we find the % of successes.
for (int i = 0; i < tests; i++) {
int[] year = new int[365];
for (int j = 0; j < n; j++) {
int birthday = (int) (Math.random() * 365);
year[birthday]++;
if (year[birthday] >= x) {
success++;
break;
}
}
}
System.out.println(Math.round(success * 100 / tests));
}
}
I seriously need help please
1=1, 1+2=3, 1+2+3=6, 1+2+3+4=10
I don't know how to code the equation part
import java.util.Scanner;
public class Equations {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println ("Enter a number between 1 to 15: ");
int num = scan.nextInt();
int total = 0;
int save;
for(int i=1;i<=num;i++)
{
for(int j=1;j<=num;j++)
{
save = total+i;
i++;
}
System.out.print (save+"="+total);
System.out.println ();
}
}
This is all I have, and it doesn't work.
There are quite a few things off. You're not resetting total or save after each equation. save is an int, so it can't hold the equation string. j needs to increment to i, not num. total is never incremented. i++ doesn't belong in the inner loop.
Here's a simple, correct version:
for (int i = 1; i <= num; i++) {
int sum = 0;
String equation = "";
for (int j = 1; j <= i; j++) {
sum += j;
equation += "+" + j;
}
System.out.println(equation.substring(1) + "=" + sum);
}
The purpose of my code is to display the student number and their respective grade as follows:
Student Grade
1 53
2 45
So on...
I used a 5x2 array, in which the user can input the values for the grade...
However I run in to a problem, when inputting the grades, for some reason I have to input 3 values, out of all the 3 inputted values only the 3rd is considered.
My problems:
(1) Why is it that I am even able to enter 3 values per student (Should only be able to input 1 value per student).
(2) Why is it the 3rd value that is being considered?
Here is my code:
import java.util.*;
public class practice {
public static void main(String[] args) {
int[][] studentGrade = new int[5][2];
for(int i = 0; i<5; i++) {
studentGrade[i][0] = i+1;
}
for(int j = 0; j<5; j++) {
System.out.printf("Student %s: ", j+1);
Scanner input = new Scanner(System.in);
if(input.nextInt()>=0 && input.nextInt()<=100) {
studentGrade[j][1] = input.nextInt();
}
else {
studentGrade[j][1] = 0;
System.out.printf("Student %s's mark has been defaulted", j);
}
}
System.out.print("\nStudent \t Grade");
for(int s=0; s<5; s++) {
System.out.print("\n" + studentGrade[s][0] +"\t" + "\t " + studentGrade[s][1]);
}
}
}
input.nextInt() consumes the next integer in the stream.
You need to do this:
Scanner input = new Scanner (System.in);
for (int j = 0; j < 5; j++) {
System.out.printf("Student %s: ", j+1);
int num = input.nextInt();
if (num >= 0 && num <= 100)
studentGrade[j][1] = num;
else {
studentGrade[j][1] = 0;
System.out.printf("Student %s's mark has been defaulted", j+1);
}
}
This will make it so that you read the number being input only once, and then you use that number when checking boundaries and then setting the grade.
Ok, so this is for a Java class, but I'm not looking for someone to write the code, just help me debug this one. I want to enter 10 integers and have the inputs sorted in ascending order as they are entered then displayed, without any zeros (0) that may exist in the array.
Example of what the assignment should look like:
Enter 10 integers - one at a time...
Enter integer #1: 21
Sorted numbers: 21
Enter integer #2: 48
Sorted numbers: 21 48
Enter integer #3: 37
Sorted numbers: 21 37 48
etc....
I have tried a Selection Sort, Insertion and Bubble Sort, but the array will not hold or display more than 5 numbers.
Help.
Here is my Main:
import java.util.*;
public class Main {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner (System.in);
int j = 1;
int[] list = new int[10];
System.out.println("Enter 10 integers - one at a time...");
for (int i = 0; i < list.length; i++){
System.out.print("Enter integer #" + j + ": ");
list[i] = input.nextInt();
j++;
//SortMethod.sort(list, list.length);
SelectionSort.sort(list);
//BubbleSort.sort(list);
System.out.print("Sorted numbers: ");
for(int p= 0; p<list.length; p++){
if (list[p] !=0)
System.out.print(list[p] + " ");
}
System.out.print("\n");
}
System.out.println("Done!");
}
}
Here is my Selection Sort:
public class SelectionSort {
public static void sort (int[] list){
for(int i=0; i<list.length; i++)
{
for(int j=i+1; j<list.length; j++)
{
if(list[i] > list[j] )
{
int temp = list[j];
list[j] = list[i];
list[i] = temp;
}
}
}
}
}
Thanks in advance!
Why don't you use List insteed of array and ready-to-go sorting implementations from jdk -> Collections.sort() ?
Anyway the problem is that you are inserting new integers into already sorted array and that causes disfunction of your code. So as you inserting new elements on indexes 0,1,2,3,4 - sorting algorithm moves them to positions 5,6,7,8,9. From this point your inputs starts overriding sorted values with new ones from input - (Main loop i>=5).All in all, it accepted 10 integers, but 5 of them where kindly overriten.
Here is little modified version of your work whitch works like you want. Analyze it!
import java.util.*;
public class test {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int j = 1;
int[] list = new int[11];
System.out.println("Enter 10 integers - one at a time...");
for (int i = 0; i < list.length - 1; i++) {
System.out.print("Enter integer #" + j + ": ");
list[0] = input.nextInt();
j++;
//SortMethod.sort(list, list.length);
SelectionSort.sort(list);
//BubbleSort.sort(list);
System.out.print("Sorted numbers: ");
for (int p = 1; p < list.length; p++) {
if (list[p] != 0)
System.out.print(list[p] + " ");
}
System.out.print("\n");
}
System.out.println("Done!");
}
}
class SelectionSort {
public static void sort(int[] list) {
for (int i = 0; i < list.length; i++) {
for (int j = i + 1; j < list.length; j++) {
if (list[i] > list[j]) {
int temp = list[j];
list[j] = list[i];
list[i] = temp;
i--;
break;
}
}
}
}
}
You are replacing sorted value with list[i] = input.nextInt(); with every input. So, 5 values always 0 in list. Use List<Integer> instead of int[] and add new value to List<Integer>. Try following code:
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner (System.in);
int j = 1;
List<Integer> list = new ArrayList<>();
System.out.println("Enter 10 integers - one at a time...");
for (int i = 0; i < 10; i++){
System.out.print("Enter integer #" + j + ": ");
list.add(input.nextInt());
j++;
//SortMethod.sort(list, list.length);
// SelectionSort.sort(list);
Collections.sort(list);
//BubbleSort.sort(list);
System.out.print("Sorted numbers: ");
for(int p= 0; p<list.size(); p++){
if (list.get(p) !=0)
System.out.print(list.get(p) + " ");
}
System.out.print("\n");
}
System.out.println("Done!");
}
I just modified the lines below the comments I put (temp declaration and for loop).
This changes makes program support negative numbers too, read the comments below:
import java.util.*;
public class test {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int j = 1;
int[] list = new int[11];
System.out.println("Enter 10 integers - one at a time...");
for (int i = 0; i < list.length - 1; i++) {
System.out.print("Enter integer #" + j + ": ");
// Add temporal variable to store input
int temp = input.nextInt();
// Check for empty place in list (as far as it seems you don't care about zeros)
for (int p = 0; p < list.length; p++) {
if (list[p] == 0) {
list[p] = temp;
break;
}
}
j++;
//SortMethod.sort(list, list.length);
SelectionSort.sort(list);
//BubbleSort.sort(list);
System.out.print("Sorted numbers: ");
for (int p = 1; p < list.length; p++) {
if (list[p] != 0)
System.out.print(list[p] + " ");
}
System.out.print("\n");
}
System.out.println("Done!");
}
}
A link to the assignment:
http://i.imgur.com/fc86hG9.png
I'm having a bit of trouble discerning how to take a series of numbers and apply them to an array without a loop. Not only that, but I'm having a bit of trouble comparing them. What I have written so far is:
import java.util.Scanner;
public class Lottery {
public static void main(String[] args) {
int userInputs[] = new int[5];
int lotteryNumbers [] = new int[5];
int matchedNumbers =0;
char repeatLottery = '\0';
Scanner in = new Scanner (System.in);
do{
System.out.println("Enter your 5 single-digit lottery numbers.\n (Use the spacebar to separate digits): ");
for(int i = 0; i <5; i++ )
userInputs[i] = in.nextInt();
System.out.println("Your inputs: ");
printArray(userInputs);
System.out.println("\nLottery Numbers: ");
readIn(lotteryNumbers);
for(int i=0; i<5; i++) {
System.out.print(lotteryNumbers[i] + " ");
}
matchedNumbers = compareArr(userInputs, lotteryNumbers);
System.out.println("\n\nYou matched " + matchedNumbers + " numbers");
System.out.println("\nDo you wish to play again?(Enter Y or N): ");
repeatLottery = in.next().charAt(0);
}
while (repeatLottery == 'Y' || repeatLottery == 'y');
}
public static void printArray(int arr[]){
int n = arr.length;
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
}
public static void readIn(int[] List) {
for(int j=0; j<List.length; j++) {
List[j] = (int) (Math.random()*10);
}
}
public static int compareArr (int[] list1, int[] list2) {
int same = 0;
for (int i = 0; i <= list1.length-1; i++) {
for(int j = 0; j <= list2.length-1; j++) {
if (list1[i] == list2[j]) {
same++;
}
}
}
return same;
}
}
As you'll notice, I commented out the input line because I'm not quite sure how to handle it. If I have them in an array, I should be able to compare them fairly easily I think. This is our first assignment handling arrays, and I think it seems a bit in-depth for only having one class-period on it; So, please forgive my ignorance. :P
Edit:
I added a new method at the end to compare the digits, but the problem is it compares them in-general and not from position to position. That seems to be the major issue now.
your question isn't 100% clear but i will try my best.
1- i don't see any problems with reading input from user
int[] userInput = new int[5]; // maybe here you had a mistake
int[] lotterryArray = new int[5]; // and here you were declaring your arrays in a wrong way
Scanner scanner = new Scanner(system.in);
for ( int i = 0 ; i < 5 ; i++)
{
userInput[i] = scanner.nextInt();
} // this will populate your array try to print it to make sure
Edit : important in the link you shared about the assignment the compare need to check the value and location so if there are two 5 one in input one in loterry array they need to be in the same location check the assignment again
// to compare
int result = 0 ; // this will be the number of matched digits
for ( int i = 0 ; i < 5 ; i++)
{
if ( userInput[i] == loterryArray[i] )
result++
}
// in this comparsion if the digits are equale in value and location result will be incremented