How to use a Counter - java

I'm trying to create a counter controlled while loop. Currently I'm having difficulty getting the counter to increase by 1 for each pass through off the loop.
I set my code to
int numberCounter = 0; // Numbers 0 through 10.
String head1 = "Number: " + numberCounter;
String head2 = " Multiplied by 2: " + numberCounter * 2;
String head3 = " Multiplied by 10: " + numberCounter * 10;
int byTwo; // Stores the number multiplied by 2.
int byTen; // Stores the number multiplied by 10.
final int NUM_LOOPS = 11; // Constant used to control loop.
// This is the work done in the housekeeping() method
System.out.println("Numbers 0 through 10 multiplied by 2 and by 10" + "\n");
System.out.println(head1 + head2 + "\n");
System.out.println(head1 + head3 + "\n");
while (numberCounter != 10) numberCounter = numberCounter + 1;
System.out.println(head1 + head2 + "\n");
System.out.println(head1 + head3 + "\n");
but it just reads the 0 value and exits after one pass.
I expect each pass to add one to the counter, but it seems to stay at 0. I say that because the output reads:
Numbers 0 through 10 multiplied by 2 and by 10
Number: 0 Multiplied by 2: 0
Number: 0 Multiplied by 10: 0
Number: 0 Multiplied by 2: 0
Number: 0 Multiplied by 10: 0

as mentioned in the comments, make sure your counter variable starts from 0 :
int numberCounter = 0;
while (numberCounter != 10) {
System.out.println(numberCounter);
numberCounter = numberCounter + 1; // or numberCounter++;
}
UPDATE
After you posted your full code, it seems clear that you expect that each iteration of your integer would change the value assigned to your Strings, eg head2 & head3. This is wrong. At the point you initialized these String variables your integer was converted to a String inside that variable (since you used string concatenation). To see the effect of the iterated integer, you can add the below println statements inside your loop, eg :
while (numberCounter != 10) {
numberCounter = numberCounter + 1;
System.out.println(" Multiplied by 2: " + numberCounter * 2);
System.out.println(" Multiplied by 10: " + numberCounter * 10);
}

Related

Dice simulation in java

I'm trying to simulate rolling a die 100 times, and printing the results of how many 1/2/3/4/5/6 i landed. Here's my code thus far: I'm trying to use a while loop for my assignment, and i need to use (Math.random( )*6 + 1) to generate numbers.
public class RollingDice {
public static void main(String args[]) {
int count = 0; // number of times die was rolled
int count1s = 0; // number of times 1 was rolled
int count2s = 0; // number of times 2 was rolled
int count3s = 0;
int count4s = 0;
int count5s = 0;
int count6s = 0;
while (count < 100) {
count1s = (int) (Math.random( )*6 + 1);
count2s = (int) (Math.random( )*6 + 1);
count3s = (int) (Math.random( )*6 + 1);
count4s = (int) (Math.random( )*6 + 1);
count5s = (int) (Math.random( )*6 + 1);
count6s = (int) (Math.random( )*6 + 1);
count++;
}
System.out.println("Number of times the die was rolled: "+ count);
System.out.println("Number of times 1 was rolled: " + count1s);
System.out.println("Number of times 2 was rolled: " + count2s);
System.out.println("Number of times 3 was rolled: " + count3s);
System.out.println("Number of times 4 was rolled: " + count4s);
System.out.println("Number of times 5 was rolled: " + count5s);
System.out.println("Number of times 6 was rolled: " + count6s);
}
}
My code currently prints:
Number of times the die was rolled: 100
Number of times 1 was rolled: 3
Number of times 2 was rolled: 1
Number of times 3 was rolled: 5
Number of times 4 was rolled: 2
Number of times 5 was rolled: 4
Number of times 6 was rolled: 4
As you can see, its rolling 100 times, but its only saving the results of 1 roll, not 100, How do I fix this?
On each iteration of your while loop, you are reassigning the value of count1s, count2s, and the others. Instead what you should do is you should "roll the dice" and then see what value it is, and increment the proper variable.
while (count < 100) {
int diceRoll = (int) (Math.random() * 6 + 1);
if (diceRoll == 1)
count1s++;
else if (diceRoll == 2)
count2s++;
// ... you get the idea
count++;
}
And as a fun sidenote, using Java 8 there is a significantly easier, and more cool way to do this.
Stream.generate(() -> (int) (Math.random() * 6 + 1))
.limit(100L)
.collect(Collectors.groupingBy(num -> num,
Collectors.counting()))
.forEach((num, count) -> System.out.println("number of times " + num + " was rolled: " + count));
Each iteration you are replacing the previous roll's data.You can rewrite the logic as
// initialization
while(count < 100){
int currentRoll = (int) (Math.random() * 6 + 1);
if(currentRoll == 1)
count1s++;
// Same logic for all occurances
}
Because your logic is incorrect.
Inside while loop, you assigned appearance time of each roll with value of dice.
=> Counter of each always < 7.
Also, each time your call Math.random() will give you new value => Should call it once each roll.
In this case, use switch - case statement will be correct.
while (count < 100) {
int num = (int) (Math.random( )*6 + 1);
switch(num) {
case 1:
count1s++;
break;
case 2:
count2s++;
break;
case 3:
count3s++;
break;
case 4:
count4s++;
break;
case 5:
count5s++;
break;
case 6:
count6s++;
break;
}
count++;
}

Beginner Java program (calculating deficient, abundant, prime, and perfect numbers)

do
{
System.out.println("Enter either limit, abundant, deficient, perfect, or prime = value:");
condition = scan.next();
String equals = scan.next();
num = scan.next();
value=Integer.parseInt(num);
if (Type.isInteger(condition) || !Type.isInteger(num) || value<0)
System.out.println("Please enter in condition = value format");
else
break;
}while(stop);
System.out.println("N" + "\t" + "Abundant" + " " + "Deficient" + " " + "Perfect" + " " + "Prime");
sigma = 0; //sets sigma=0
n=1;
while (stop)
{
for (f = 1; f <= n/2; f++)
{
if (n % f == 0)
sigma = sigma + f;
}
System.out.print(n + "\t");
if (sigma>n)
acount++;
if (sigma == 1)
p++; //prime counter
if (sigma<n)
dcount++; //deficient counter
if (sigma == n)
pcount++; //perfect counter
System.out.print(acount + " " + "\t" + " " + dcount + "\t" + " " + pcount + "\t" + " " + p); //prints abundant column
System.out.println();
if (condition.equals("limit"))
{
if(n<value)
n++;
else
break;
}
if(condition.equals("abundant"))
{
if(acount<value)
n++;
else
break;
}
if (condition.equals("deficient"))
{
if (dcount<value)
n++;
else
break;
}
if (condition.equals("perfect"))
{
if (pcount<=value)
n++;
else
break;
}
if (condition.equals("prime"))
{
if (p<value)
n++;
else
break;
}
}
}
}
Essentially, the code is supposed to print out 5 columns: n, abundant, deficient, perfect, and prime. And each row will have a column of numbers under it. The user is supposed to type in specifications in a 'condition = value' format. So if they type in limit = 10 then it will print 10 rows. And if they input abundant = 10 then it will continue to print rows until the value of abundant reaches 10. The problem I am encountering is that my program will infinity loop when I input certain values and I am not sure what the cause is. For example, if I input deficient = 2 it will work fine but if I input deficient = 10 then it will start an infinite loop. However, when I input perfect = 10 it will only print out 1 row. Like my title says I am a beginner and I can't figure out what is causing the error. Any suggestions?
Try initializing the value of sigma inside the loop:
while (stop)
{
sigma = 0;
...
}
Since sigma is never reset to zero, it just keeps growing for every number. So you will quickly stop finding deficient numbers or perfect numbers, and everything will be be abundant. That's why the abundant keyword works, but deficient does not.

Printing from a loop

I need to print the factors of a perfect number. Here's the gist of my main class:
ArrayList<Integer> perfNums = new ArrayList<>();
Scanner in = new Scanner(System.in);
System.out.print("Enter the upperbound: ");
upperbound = in.nextInt();
for (int i = 1; i <= upperbound; i++) {
if (isPerfect(i)) { //boolean to check if number is a perfect number
perfNums.add(i);
}
}
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for (int i = 0; i < perfNums.size(); i++) {
System.out.print(perfNums.get(i) + " = ");
printFactor((int)perfNums.get(i));
System.out.println();
}
Here's the printFactor class.
private static void printFactor(int number){
int factor = 1;
while(factor < number){
if (number%factor == 0) System.out.print(factor+ " + ");
//I don't know how to print the + sign otherwise.
factor++;
}
}
And here's a sample output:
Enter the upperbound: 10000
Perfect numbers between 1 and 10000 are:
6 = 1 + 2 + 3 +
28 = 1 + 2 + 4 + 7 + 14 +
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248 +
8128 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064 +
I've got the main gist of it but I've struggled with an output issue. Due to the restrictions of my online submission system, my output needs to fit exact specifications.
My question is how do I go about printing all the factors of my perfect number but removing the + sign at the end? (e.g)6 = 1 + 2 + 3
I'm not too sure of many methods to print from a while loop. Would a for-loop be better for my goals? Or are there alternative methods to print the factors of a number?
The least amount of change to address this might be something like this:
private static void printFactor(int number)
System.out.print(1);
int factor = 2;
while (factor<number) {
if (number%factor == 0) System.out.print(" + " + factor);
factor++;
}
}
1 is always a factor, so you can print that before the loop and then prepend + to every subsequent factor.
You should cache the output you want to print into a StringBuilder. Then you are able to remove the last plus sign before you print the whole String. It also has a better performance.
private static void printFactor(int number)
{
StringBuilder output = new StringBuilder();
int factor = 1;
while (factor < number)
{
if (number % factor == 0)
output.append(factor + " + ");
factor++;
}
// remove last plus sign
output.deleteCharAt(output.length() - 1);
// print the whole string
System.out.print(output.toString());
}
Since factor starts from value 1 and number % 1 == 0 will always be true, you might print 1 first and then flip factor and + in System.out.print. Like this:
private static void printFactor(int number) {
if(number > 0) {
System.out.print(1);
}
int factor = 2;
while (factor<number) {
if (number % factor == 0) {
System.out.print(" + " + factor);
}
factor++;
}
}
Not the best solution, but it will do the job.
Try to create a variable String numb and use substring method like this:
String numb ="";
while(factor<number){
if(number%factor == 0)
numb= numb + factor+ " + ";
factor++;
}
System.out.print(numb.substring(0, numb.trim().length()-1));
Just for the sake of using Java 8 :)
private static void printFactor(int number){
System.out.println(IntStream.range(1, number)
.filter(p -> number % p == 0)
.mapToObj(i -> String.valueOf(i))
.collect(Collectors.joining(" + ")));
}
Thanks everyone for the quick response. You all have been a lifesaver, and I managed to pick up some new things to consider when I code in the future.
Anyway, while waiting for a reply I was fiddling with the code and came up with a rather inelegant solution, if anybody's interested. Here's the changes to the main class:
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for(int i=0; i<perfNums.size(); i++){
System.out.print(perfNums.get(i) + " = ");
outputString = printFactor2(perfNums.get(i));
if(outStr.endsWith(" + ")) outStr = outStr.substring(0, outStr.length()-3);
//because the submission system would cry foul with even a single extra space
System.out.println(outStr);
}
And here's the changes to the printFactor class:
private static String printFactor2(int number){
String out = "";
int factor = 1;
while(factor<number){
if(number%factor == 0) out += factor + " + ";
factor++;
}
return out;
}
Basically, what I did was append the factors to a string, then removing the trailing + sign using the substring method. On hindsight, I probably should've called the substring method inside the printFactor class instead. Something like return out.substring(0, out.length()-3); perhaps?
Nevertheless, thanks everyone!

Why does the for loop output this?

I am just very confused from this homework problem. I do not understand why the values of i and sum come out this way. I just do not understand the concept of the algorithm here, can someone please explain this?
int i = 0;
int sum = 0;
for(i=0; i < 5; i++)
{
sum += i;
}
System.out.println(i + "\n" + sum);
The output is:
5
10
----jGRASP: operation complete.
5 - because there are 5 iterations
10 - because the sum is 10 :)
Sum
Iteration 1: 0 + 0 = 0
Iteration 2: 0 + 1 = 1
Iteration 3: 1 + 2 = 3
Iteration 4: 3 + 3 = 6
Iteration 5: 6 + 4 = 10
Verification code
int i = 0;
int sum = 0;
for (i = 0; i < 5; i++) {
System.out.println(String.format(
"Iteration %s: %s + %s = %s", (i + 1), sum, i, (sum + i)));
sum += i;
}
This code :
int i = 0;
int sum = 0;
for(i=0; i < 5; i++)
{
sum += i;
}
System.out.println(i + "\n" + sum);
output in sum this : 0 + 1 + 2 + 3 + 4 which is equal to 10 and i the number of iterations = 5.
You have created a variable i with value of 0 and then incrementing it 5 times in for-loop. So you got i's value as 5.
Now the value of sum is 0+1+2+3+4 which is 10
Because you iterate through your loop, which makes i == 5, then print it,
Sum goes as below, you are adding i to the previously calculated sum
0 + 1 = 1
1 + 2 = 3
3 + 3 + 6
6 + 4 = 10
Try put your print command inside the loop, they you can see better what's going on.
The only non-obvious thing is (in my opinion): i will be 5, because you used i++, which also incremented i by 1 even though the body did not execute after the last iteration. Inside the body i only can be maximum 4.
int sum = 0; int i = 0;
for (i = 0; i < 5; i++)
{
sum += i;
if (i == 5)
System.out.println("never executed");
};
Other answers tell the other things.

what is wrong with my method for avg? [duplicate]

This question already has answers here:
How do I get this code to stop input when the sum exceeds 100 and still preform the sum and average?
(2 answers)
Closed 9 years ago.
Yes, I know there are a lot of methods here. It's part of the assignment. In this code everything works as intended except that when numbers are entered that equal sum<=100, the "average" output is wrong. For example: if I put in 8,10,19 and zero to exit the output is count 3 sum 37 average 9.25.... the average should be 12.3333. Now, if i enter in 8, 10, 99 the output is count 3 sum 117 and average 39 which is correct. Why is it working for sum>100 but not sum<=100??? I don't get it. What am I missing?
public static void main(String[] args) {
//Use Main Method for gathering input
float input = 1;
// Declare variable for sum
float theSum = 0;
// Declare variable for average
float average = 0;
// Declare variable for counting the number of user inputs
int counter = 0;
/* Initialize the while loop using an input of 0 as a sentinel value
* to exit the loop*/
while (input != 0) {
if (input!=0){
counter++;
}
input = Float.parseFloat(
JOptionPane.showInputDialog(
null, "Please enter a number. Enter 0 to quit: "));
// Invoke sum method and pass input and summation to sum method
theSum = (sum(input, theSum));
if (theSum > 100)
{
JOptionPane.showMessageDialog(null, "The sum of your numbers "
+ "are greater than 100!");
break;
}
}
// Invoke display method and pass summation, average, and counter variables to it
average = (avg(theSum, counter));
display(theSum, average, counter);
}
public static float sum(float num1, float sum) {
//Add the user's input number to the sum variable
sum += num1;
//Return value of sum variable as new summation variable
return sum;
}
public static float avg(float num1, float num2) {
//Declare and initialize variable for average
//Calculate average
float average = num1 / num2;
//Return value of average variable
return average;
}
public static void display(float sum, float average, int counter) {
/* I am subtracting 1 from variable counter so as not to include the sentinel value
* of 0 that the user had to enter to exit the input loop in the overall count*/
// Display the count, sum, and average to the user
if (sum > 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter) + ", Sum = " + sum + ", Average = " + average);
}
if (sum <= 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter - 1) + ", Sum = " + sum + ", Average = " + average);
}
}
}
The reason is that you're exiting the while loop in different ways depending on the total sum. If the sum is less than 100, even when you enter the number 0 to "exit", you're still going through the loop an extra time. To be honest, the entire loop needs to be completely restructured; a do...while loop would be much easier to read and debug.
The issue is because of the way you exit the while loop as mentioned by #chrylis. So in case where the sum is <= 100 the counter is 1 larger. But when you print it you get correct result because you update the counter value here:
if (sum <= 100) {
JOptionPane.showMessageDialog(null, "Count = " + (counter - 1) + ", Sum = " + sum + ", Average = " + average);
}
As you see in your example:
"if I put in 8,10,19 and zero to exit the output is count 3 sum 37 average 9.25"
it is because the counter value is 4 (so the avg will be 37/4 = 9.25), but while displaying the result you subtract counter by 1, therefore you get the count as 3.
The do-while loop will solve the issue as the condition would be checked at the last thus the loop will exit in same manner for both <=100 and '>100`.
The do-while loop would be like this:
do{
//here goes your code
}while (input != 0);
Your counter is 1 larger than necessary. Dividing by (counter - 1) would fix it.

Categories