I am new to Java, and am writing a program to print 6 random numbers for a lottery ticket. I am receiving an error,
-Exception in thread "main" java.lang.RuntimeException: Uncompilable source -code - cannot find symbol
- symbol: variable numbers
- location: class lotto.Lottery
- at lotto.Lottery.printNumbers(Lottery.java:52)
- at lotto.Lottery.main(Lottery.java:34)
-Java Result: 1
import java.util.Random;
import java.util.ArrayList;
public class Lottery {
static ArrayList<Integer> lottoNumbers = new ArrayList<Integer>();
static int MAX_NUMBERS = 6;
public static void main(String[] args)
{
generateNumbers();
printNumbers();
}
private static void generateNumbers()
{
int ticketNumber;
Random generateRandomNumber = new Random();
for (int count = 0; count < MAX_NUMBERS; count++)
{
ticketNumber = 1 + generateRandomNumber.nextInt(59);
lottoNumbers.add(new Integer(ticketNumber));
}
}
private static void printNumbers()
{
int count = 0;
for( Integer number : numbers )
{
if (count < 5)
if (count == 4)
System.out.print(number);
else
System.out.print(number + ", ");
else
{
System.out.println("\nPower Ball: " + number);
count++;
}
}
}
}
Your code has a compilation error, hence the program fails to run: the variable numbers is not defined anywhere. If you want to loop over the generated numbers, use lottoNumbers which was filled by the generateNumbers method. You should also increment count++ after each element is printed (I would strongly encourage you to always use curly braces after if statements to avoid bugs):
int count = 0;
for (Integer number : lottoNumbers) {
if (count < 5) {
if (count == 4) {
System.out.print(number);
} else {
System.out.print(number + ", ");
}
} else {
System.out.println("\nPower Ball: " + number);
}
count++;
}
Related
I have been programming a lottery simulation, with some help from questions I've been looking at on this site. I can't seem to get the program to display the correct number of results that I am requiring, and the two sets are not comparing correctly to say how many numbers have matched.
import java.util.Set;
import java.util.HashSet;
import java.util.Random;
import java.util.Scanner;
public class Lotto {
private static final int INPUT_SIZE = 6;
private static final int MIN_NUMBER_POSSIBLE = 1;
private static final int MAX_NUMBER_POSSIBLE = 10;
private Set<Integer> userNumbers = new HashSet<Integer>();
private Set<Integer> randomNumbers = new HashSet<Integer>();
public static void main(String[] args) {
Lotto c = new Lotto();
c.generateRandomNumbers();
System.out.println("Please choose " + INPUT_SIZE + " numbers from " + MIN_NUMBER_POSSIBLE + " to " + MAX_NUMBER_POSSIBLE + ", hit enter after each number.");
c.readUserNumbers();
if (c.doUserNumbersMatchRandomNumbers()) {
System.out.println("Congratulations, you have won!");
} else {
System.out.println("Not a winner, better luck next time.");
c.showRandomNumbersToUser();
}
}
private void generateRandomNumbers() {
Random random = new Random();
for (int i = 0; i < INPUT_SIZE; i++) {
randomNumbers.add(random.nextInt(MAX_NUMBER_POSSIBLE));
}
}
private void showRandomNumbersToUser() {
System.out.println("\nLotto numbers were : ");
for (Integer randomNumber : randomNumbers) {
System.out.println(randomNumber + "\t");
}
}
private void readUserNumbers() {
Scanner input = new Scanner(System.in);
int inputSize = 1;
while (input.hasNextInt() && inputSize < INPUT_SIZE) {
int numberChosen = input.nextInt();
if (numberChosen < MIN_NUMBER_POSSIBLE || numberChosen > MAX_NUMBER_POSSIBLE) {
System.out.println("Your number must be in " + MIN_NUMBER_POSSIBLE + " - " + MAX_NUMBER_POSSIBLE + " range.");
} else {
userNumbers.add(numberChosen);
inputSize++;
}
}
}
private boolean doUserNumbersMatchRandomNumbers() {
for (Integer userNumber : userNumbers) {
for (Integer randomNumber : randomNumbers) {
if (!randomNumbers.contains(userNumber)) {
return false;
}
}
printMatchingNumber(userNumber);
}
return true;
}
private void printMatchingNumber(int num) {
System.out.println("Your number, " + num + ", has been drawn.");
}
}
There 2 problems in your code:
1) In generateRandomNumbers you should take into account that the same random number could occur multiple times. So make sure that randomNumbers is really of INPUT_SIZE size in the end.
2) In doUserNumbersMatchRandomNumbers you iterate over randomNumbers but never use randomNumber.
You store your random numbers in a (Hash-)Set, One feature of Set as described in the API is that they do not contain duplicate values (by comparing them with their equals() method). Since the Random class may output the the same value multiple times you have less values in your Set.
The better approach for generating the random numbers would be to go with a while loop:
while (random.size() < INPUT_SIZE)
{
randomNumbers.add(random.nextInt(MAX_NUMBER_POSSIBLE));
}
keep in mind that this could result in an endless loop. Although it is very unlikely though. At least this loop does have varying execution times.
assignment:
Write a program that reads in integers between 1 and 100 from the user and counts the
occurrences of each number. The user input ends when they enter a 0.
You must use an enhanced for-loop to solve this problem.
If a number occurs more than 1 time use the plural word “times” instead of “time”. Do not display numbers that were not entered.
I know and understand why my code's current output below appears with duplicates. The print logic is inside the for-each loop code block. If I close the code block I am no longer able to use the variables I initialized inside the loop. I have tried everything I can think of. Any suggestions would be appreciated
current output:
- 1 occurs 1 time,
- 1 occurs 2 times
- 2 occurs 1 time
- 2 occurs 2 times
- 3 occurs 1 time
- 3 occurs 2 times
needed output:
- 1 occurs 2 times
- 2 occurs 2 times
- 3 occurs 2 times
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] numbers = new int[10];
System.out.print("Enter Integers:");
for (int i = 0; i < numbers.length; i++) {
numbers[i] = in.nextInt();
if (numbers[i] == 0) {
break;
}
}
enhancedLoop(numbers);
}
private static void enhancedLoop(int[] numbers) {
int[] counts = new int[101];
for (int value : numbers) {
counts[value]++;
if (value > 0)
if (counts[value]> 1)
System.out.println(value + " occurs " + counts[value]+ " times");
else
System.out.println(value + " occurs " + counts[value] + " time");
}
}
Variables are only available in the block in which they are declared. Move the output after the for loop and iterate over counts to display the values:
for (int i = 0, c = counts.length; i < c; ++i) {
if (counts[i] > 0) {
if (counts[i] > 1) {
System.out.println(value + " occurs " + counts[i]+ " times");
} else {
System.out.println(value + " occurs " + counts[i]+ " time");
}
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] numbers = new int[10];
System.out.print("Enter Integers:");
for (int i = 0; i < numbers.length; i++) {
numbers[i] = in.nextInt();
if (numbers[i] == 0) {
break;
}
}
enhancedLoop(numbers);
}
private static void enhancedLoop(int[] numbers) {
int[] counts = new int[101];
for (int value : numbers) {
counts[value]++;
if (value > 0)
if (counts[value]> 1)
System.out.println(value + " occurs " + counts[value]+ " times");
else
System.out.println(value + " occurs " + counts[value] + " time");
}
}
You can do this effectively using the below steps:
(1) Identify the unique numbers first
(2) Find the number of times each unique number occurs
So, you need to change your enhancedLoop(int[] numbers) method as shown below to achieve the result:
private static void enhancedLoop(int[] numbers) {
//convert the array to a list to make computations easier by using streams
List<Integer> numbersList = Arrays.stream(numbers).boxed().collect(Collectors.toList());
//Get the unique numbers in the list
List<Integer> uniqueNumbers = numbersList.stream().distinct().collect(Collectors.toList());
//Now find out number of times each each unique number occured
for(int number : uniqueNumbers) {
long times = numbersList.stream().filter(num -> num == number).count();
System.out.println(number+" occurs "+times);
}
}
lets try to do this without lamdas, using simply a hashmap instead of arrays
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
HashMap<Integer, Integer> numbers = new HashMap<Integer, Integer>();
int tmp=0;
System.out.print("Enter Integers:");
//read a maximum of 10 int
for (int i = 0; i < 10; i++) {
tmp = in.nextInt();
//if we read a 0 we quit
if (tmp == 0) {
break;
}
//if we already saw the number we up the counter
if(numbers.containsKey(tmp)){
numbers.put(tmp, numbers.get(tmp)+1);
}else{
//otherwise we just add the new int
numbers.put(tmp, 1);
}
}
//call the print loop
enhancedLoop(numbers);
}
private static void enhancedLoop(HashMap<Integer, Integer> numbers) {
//you print what you counted
for(Map.Entry<Integer, Integer> entry : numbers.entrySet()) {
System.out.print(entry.getKey() + " occurs " + entry.getValue() + " time");
if (entry.getValue()>1)
System.out.print("s");
System.out.println("");
}
}
My program reads in values from a file and uses a recursive method to print patterns of asterisks based on those values. I'm just having a problem getting everything to line up properly.
The output is supposed to look like this:
*
* *
* * *
* *
*
Regarding the format of the output, the directions are:
"Note that the pattern is aligned symmetrically (vertically) about the center line. The pattern should be aligned symmetrically on each line (horizontally) as well- hint: use the line value to help space."
But my output looks like this:
*
* *
* * *
* *
*
The code I'm using to get this pattern:
public static void makePattern(int thisRow, int num) {
if(thisRow >= num) {
for(int i = 0; i < num; i++) {
System.out.print(" " + "*" + " ");
}
System.out.println();
}
else {
for(int i = 0; i < thisRow; i++) {
System.out.print(" " + "*" + " ");
}
System.out.println();
makePattern(thisRow + 1, num);
for(int i = 0; i < thisRow; i++) {
System.out.print(" " + "*" + " ");
}
System.out.println();
}
}
Also my main method:
import java.util.Scanner;
import java.io.*;
public class Program3 {
public static void main(String[] args) throws Exception {
int num = 0;
int thisRow = 1;
java.io.File file = new java.io.File("../instr/prog3.dat");
Scanner fin = new Scanner(file);
while(fin.hasNext()) {
num = fin.nextInt();
if(num >=0 && num <= 25)
makePattern(thisRow, num);
System.out.println();
}
fin.close();
}
Any suggestions on how to edit my code to make my output appear like the example pattern I included?
Let's analyse the output first!!
First step is to analyse the output
Conclusions:
The total number of characters on every line is always n (=3)
Number of Spaces has the following pattern:
1st line 3 - 1 spaces
2nd line 3 - 2 spaces
3rd line 3 - 3 spaces
4th line 4 - 3 spaces
5th line 5 - 3 spaces
So
if(num < thisRow) {
numberOfSpaces = thisRow - num;
} else {
numberOfSpaces = num - thisRow;
}
Number of Stars is always [n - the number of spaces]
So
int numberOfStars = num - numberOfSpaces;
And the recursion should end on the 6th line, i.e. when current line number is n*2
So the return condition in your recursive method should be
if(thisRow == num * 2)
return;
Final Code : Putting the peices together
When we put the peices together, we get:
public static void makePattern(int thisRow, int num) {
//the termination condition
if(thisRow == num * 2)
return;
//the number of spaces
int numberOfSpaces = 0;
if(num < thisRow) {
numberOfSpaces = thisRow - num;
} else {
numberOfSpaces = num - thisRow;
}
//the number of stars
int numberOfStars = num - numberOfSpaces;
//compose the string before printing it
StringBuffer outputBuffer = new StringBuffer(num);
for (int i = 0; i < numberOfSpaces; i++){
outputBuffer.append(" ");
}
for (int i = 0; i < numberOfStars; i++){
outputBuffer.append("* ");
}
//print the string
System.out.println(outputBuffer.toString());
//recursion
makePattern(thisRow + 1, num);
}
This is code for printing diamond shaped pattern using recursion technique.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class patternRecursion {
static int n,k;
public static void main(String[] args) throws IOException{
try(Scanner s = new Scanner(System.in)){
n=Integer.parseInt(reader.readLine());
k=n-1;
printPattern(n);
}
}
public static void printChar(int m,char c){
if(m==0) return;
try{
printChar(m-1,c);
System.out.print(c);
}catch(StackOverflowError s){return;}
}
public static void printPattern(int m){
if(m==0){
return ;
}else{
printChar(m-1,' ');
printChar(n-m,'#');
printChar(n-m+1,'#');
System.out.println();
printPattern(m-1);
printChar(m,' ');
printChar(k-m,'#');
printChar(k-m+1,'#');
System.out.println();
}
}
}
Note: Just a practice problem, not for marks.
This is a practice problem given in a first year Java course:
Design and implement an application that reads an arbitrary number of integers, by the user, that are in the range 0 to 50 inclusive, and counts how many occurrences of each are entered. After all the input has been processed, print all of the values (with the number of occurrences) that were entered one or more times.
In addition, write a method that returns no value which would compute the average of the occurrences of all numbers entered by the user.
This is what I have (I have skipped the "average occurrence" part until I clean this up):
import java.util.Scanner;
public class Main
{
public static Scanner scan = new Scanner(System.in);
public static int[] userIntegers() // this method will build the array of integers, stopping when an out-of-range input is given
{
System.out.println("Enter the number of integers to be recorded: ");
int numInts = scan.nextInt();
int[] userArray = new int[numInts];
int i = 0;
while(i < numInts)
{
System.out.println("Enter an integer between 1-50 inclusive: ");
int userInteger = scan.nextInt();
if(isValidInteger(userInteger))
{
userArray[i] = userInteger;
i++;
}
else if(isValidInteger(userInteger) == false)
{
System.out.println("Try again.");
}
}
return userArray;
}
public static void occurrenceOutput(int[] input) // this method will print the occurrence data for a given array
{
int[] occurrenceArray = new int[51];
int j = 0;
while(j < 51) // iterates through all integers from 0 to 50, while the integer in the array is equal to integer j, the corresponding occurance array element increments.
{
for(int eachInteger : input)
{
occurrenceArray[j] = (eachInteger == j)? occurrenceArray[j]+=1: occurrenceArray[j];
}
j++;
}
int k = 0;
for(int eachOccurrence : occurrenceArray) // as long as there is more than one occurrence, the information will be printed.
{
if(eachOccurrence > 1)
{
System.out.println("The integer " + k + " occurrs " + eachOccurrence + " times.");
}
k++;
}
}
public static boolean isValidInteger(int userInput) // checks if a user input is between 0-50 inclusive
{
boolean validInt = (51 >= userInput && userInput >= 0)? true: false;
return validInt;
}
public static void main(String[] args)
{
occurrenceOutput(userIntegers());
}
}
Can someone point me in a more elegant direction?
EDIT: Thanks for the help! This is where I am at now:
import java.util.Scanner;
public class simpleHist
{
public static void main(String[] args)
{
getUserInputAndPrint();
getIntFreqAndPrint(intArray, numberOfInts);
}
private static int numberOfInts;
private static int[] intArray;
private static int[] intFreqArray = new int[51];
public static void getUserInputAndPrint()
{
// The user is prompted to choose the number of integers to enter:
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of Integers: ");
numberOfInts = input.nextInt();
// The array is filled withchInteger = integer; integers ranging from 0-50:
intArray = new int[numberOfInts];
int integer = 0;
int i = 0;
while(i < intArray.length)
{
System.out.println("Enter integer value(s): ");
integer = input.nextInt();
if(integer > 50 || integer < 0)
{
System.out.println("Invalid input. Integer(s) must be between 0-50 (inclusive).");
}
else
{
intArray[i] = integer;
i++;
}
}
// Here the number of integers, as well as all the integers entered are printed:
System.out.println("Integers: " + numberOfInts);
int j = 0;
for(int eachInteger : intArray)
{
System.out.println("Index[" + j + "] : " + eachInteger);
j++;
}
}
public static void getIntFreqAndPrint(int[] intArray, int numberOfInts)
{
// Frequency of each integer is assigned to its corresponding index of intFreqArray:
for(int eachInt : intArray)
{
intFreqArray[eachInt]++;
}
// Average frequency is calculated:
int totalOccurrences = 0;
for(int eachFreq : intFreqArray)
{
totalOccurrences += eachFreq;
}
double averageFrequency = totalOccurrences / numberOfInts;
// Integers occurring more than once are printed:
for(int k = 0; k < intFreqArray.length; k++)
{
if(intFreqArray[k] > 1)
{
System.out.println("Integer " + k + " occurs " + intFreqArray[k] + " times.");
}
}
// Average occurrence of integers entered is printed:
System.out.println("The average occurrence for integers entered is " + averageFrequency);
}
}
You are actually looking for a histogram. You can implement it by using a Map<Integer,Integer>, or since the range of elements is limited to 0-50, you can use an array with 51 elements [0-50], and increase histogram[i] when you read i.
Bonus: understanding this idea, and you have understood the basics of count-sort
To calculate occurences, you can do something like this:
for(int eachInteger : input) {
occurrenceArray[eachInteger]++;
}
This will replace your while loop.
I am trying to write a program which can calculate factorial from 1-9 by iteration, but I encounter some problems while I am trying to. Please help me figure out my problems in my program, I am just learning programming.
The following is my program, please tell me what's wrong with it:
public class iterative {
static int ans=1;
public static void iteration() {
System.out.println("n n!");
for (int n=1; n<10; n++) {
while ((n-1)>0)
ans=n*(n-1);
System.out.println(n + " " + ans);
}
}
public static void main(String[] args) {
iteration();
}
}
First of all, don't use a static for ans. A local is what you want.
Secondly the factorial recurrence relationship you use is incorrect. You should do it like this.
int ans = 1;
for (int n=1; n<=9; n++) {
ans = ans*n;
System.out.println(n + " " + ans);
}
The answers above is close perfect,you also get it with the recursion:
here is code:
public class iterative {
public static int iteration(int n) {
int result;
if(n==1)return n;
else
result = n*iteration(n-1);
return result;
}
public static void main(String[] args) {
System.out.println("Result is :" + iteration(9));
}
}
I see three big problems.
Firstly, "ans" is global and is never reassigned. So over time it will display an accumulated incorrect value.
The other is that the while loop will run forever for n > 1.
Lastly, the recurrence relationship is wrong. Should be ans = ans * (n-1). See code.
The fact that you have nested loops suggests to me that you are trying to print a table of factorials.
Try this:
for (int n=1; n<10; n++) {
int ans = 1;
int x = 0;
while ((n-x)>0){
ans=ans*(n-x);
x++;
}
System.out.println(n + " " + ans);
}
Like #David's solution but shorter
for(int i=1, ans=1; i <= 9; i++, ans *= i)
System.out.println(i + " " + ans);
Your algorithm needed work as well:
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
int i = 1;
while(i < 10)
iteration(i++);
}
public static void iteration(int max) {
System.out.println("n n!");
int ans = 1;
for (int n=1; n<=max; n++) {
ans *= n;
}
System.out.println(" " + ans);
}
ideone example