I need to select a value based on a percentage chance of that value being selected. For example:
10% of the time increment value a
20% of the time increment value b
30% of the time increment value c
40% of the time increment value d
The percentages will always add up to exactly 100%
I have encountered several solutions like this one, but have determined that they cannot possibly be correct. Here is a sample program built using the solution mentioned:
import java.util.Random;
public class Main {
private static Random r = new Random();
public static void main(String[] args) {
final int iterations = 1000000;
System.out.println("Testing percentage based random, " + iterations + " iterations");
int onePercent = 0;
int sixPercent = 0;
int sevenPercent = 0;
int thirtySixPercent = 0;
int fiftyPercent = 0;
// Those values add up to 100% overall
for (int i = 0; i < iterations; i++) {
int random = r.nextInt(100);
if (random < 1) {
onePercent++;
continue;
}
if (random < 6) {
sixPercent++;
continue;
}
if (random < 7) {
sevenPercent++;
continue;
}
if (random < 36) {
thirtySixPercent++;
continue;
}
if (random < 50) {
fiftyPercent++;
continue;
}
// That can't be right because if random > 50 then nothing at all happens
}
System.out.println("One percent happened about " + (onePercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Six percent happened about " + (sixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Seven percent happened about " + (sevenPercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Thirty six percent happened about " + (thirtySixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Fifty percent happened about " + (fiftyPercent / Float.valueOf(iterations)) * 100 + "% of the time");
}
}
Output:
Testing percentage based random, 1000000 iterations
One percent happened about 0.99649996% of the time
Six percent happened about 4.9925% of the time
Seven percent happened about 1.0029999% of the time
Thirty six percent happened about 29.001299% of the time
Fifty percent happened about 14.0191% of the time
Expected output:
Testing percentage based random, 1000000 iterations
One percent happened about 0.99649996% of the time
Six percent happened about 6.9925% of the time
Seven percent happened about 7.0029999% of the time
Thirty six percent happened about 36.001299% of the time
Fifty percent happened about 50.0191% of the time
I believe I need to use some sort of algorithm to convert the percentages into a scale from 0 to 99 so that the random number generator can select a value accurately. I cannot think of how to do that, though.
Your results are correct :
Fifty percent happened about 14.0191% of the time
50 - 36 = 14
Thirty six percent happened about 29.001299% of the time
36 - 7 = 29
Seven percent happened about 1.0029999% of the time
7 - 6 = 1
....
Delete all 'continue' statements if you want them to sum up.
Figured it out. You need to keep track of the percentage tested so far and add it to the current test.
import java.util.Random;
public class Main {
private static Random r = new Random();
public static void main(String[] args) {
final int iterations = 1000000;
System.out.println("Testing percentage based random, " + iterations + " iterations");
int onePercent = 0;
int sixPercent = 0;
int sevenPercent = 0;
int thirtySixPercent = 0;
int fiftyPercent = 0;
// Those values add up to 100% overall
for (int i = 0; i < iterations; i++) {
int random = r.nextInt(100);
int totalPercent = 0;
if (random < totalPercent + 1) {
onePercent++;
continue;
}
totalPercent += 1;
if (random < totalPercent + 6) {
sixPercent++;
continue;
}
totalPercent += 6;
if (random < totalPercent + 7) {
sevenPercent++;
continue;
}
totalPercent += 7;
if (random < totalPercent + 36) {
thirtySixPercent++;
continue;
}
totalPercent += 36;
if (random < totalPercent + 50) {
fiftyPercent++;
continue;
}
totalPercent += 50;
// That can't be right because if random > 50 then nothing at all happens
}
System.out.println("One percent happened about " + (onePercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Six percent happened about " + (sixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Seven percent happened about " + (sevenPercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Thirty six percent happened about " + (thirtySixPercent / Float.valueOf(iterations)) * 100 + "% of the time");
System.out.println("Fifty percent happened about " + (fiftyPercent / Float.valueOf(iterations)) * 100 + "% of the time");
}
}
Related
so for class I'm supposed to make a guessing game that gives you clues as you get closer to the answer. My question is when i run it and i get one Number correct, I would obviously keep that number and keep going with the other 4 numbers, when I do that, the problem is my correct digits counter keeps rising even if I don't get other digits correct.. how would I remedy this? Would i be able to add breaks in each of the if statements or would that completely exit me out of my do while loop?
public class GuessingGame {
public static void main(String[] args) {
int guess,numDigitsCorrect=0,sumDigitsCorrect=0,attempts=0,answer;
Random rng = new Random();
Scanner consoleScanner = new Scanner(System.in);
answer = rng.nextInt(90000) + 10000;
System.out.println("I have randomly chosen a 5-digit code for you to guess.Each time you guess,\n"
+ "I will tell you how many digits are correct and the sum of the digits that are correct."
+ "For example, if the number is \"68420\" and you guess 12468, I will respond:\n"
+ "Number of Digits Correct: 1\n"
+ "Sum of Digits Correct: 4\n"
+ "From deduction, you will know the 4 was correct in the guess."
+ "\nNow its your turn..................................................................");
do{
System.out.print("Please enter a 5-digit code (your guess): ");
guess = consoleScanner.nextInt();
int g1 = guess/10000;
int g2 = guess%10000/1000;
int g3 = guess % 10000 % 1000 / 100;
int g4 = guess % 10000 % 100 /10;
int g5 = guess % 10000 % 10 / 1;
int a1 = answer/10000;
int a2 = answer%10000/1000;
int a3 = answer % 10000 % 1000 / 100;
int a4 = answer % 10000 / 100 / 10;
int a5 = answer % 10000 % 10 / 10;
if(g1 == a1)
{
numDigitsCorrect ++;
sumDigitsCorrect += a1;
System.out.println("\nNumber of digits correct: " + numDigitsCorrect) ;
System.out.println("Sum of digits correct: " + sumDigitsCorrect);
System.out.println();
}
if(g2 == a2)
{
numDigitsCorrect ++;
sumDigitsCorrect += a2;
System.out.println("Number of digits correct: " + numDigitsCorrect) ;
System.out.println("Sum of digits correct: " + sumDigitsCorrect);
System.out.println();
}
if (g3 == a3)
{
numDigitsCorrect ++;
sumDigitsCorrect += a3;
System.out.println("Number of digits correct: " + numDigitsCorrect) ;
System.out.println("Sum of digits correct: " + sumDigitsCorrect);
System.out.println();
}
if (g4 == a4)
{
numDigitsCorrect ++;
sumDigitsCorrect += a4;
System.out.println("Number of digits correct: " + numDigitsCorrect) ;
System.out.println("Sum of digits correct: " + sumDigitsCorrect);
System.out.println();
}
if (g5 == a5)
{
numDigitsCorrect ++;
sumDigitsCorrect += a5;
System.out.println("Number of digits correct: " + numDigitsCorrect) ;
System.out.println("Sum of digits correct: " + sumDigitsCorrect);
System.out.println();
}
if(guess == answer)
{
System.out.println("****HOORAY! You solved it. You are so smart****");
break;
}
}while (guess != answer);
}
}
Few things to fix -
Make sure your a4, a5 are correct
int a4 = answer % 10000 % 100 / 10; // note the modulus
int a5 = answer % 10000 % 10; // note divided by 1 or remove the redundant statement
Move your print statement out of your if block to the end of all if inside the do block as -
if (g1 == a1) {
numDigitsCorrect++;
sumDigitsCorrect += a1;
}
... //other if statements
if (guess == answer) {
System.out.println("****HOORAY! You solved it. You are so smart****");
break;
}
System.out.println("Number of digits correct: " + numDigitsCorrect);
System.out.println("Sum of digits correct: " + sumDigitsCorrect);
Also since you already do a check
if (guess == answer) {
System.out.println("****HOORAY! You solved it. You are so smart****");
break;
}
within your do you can change your while condition to true as -
do {
... your existing code
} while(true);
To answer
Would i be able to add breaks in each of the if statements
If you do so, for even a single digit match your loop will exit(break).
Importantly to fix the counter, initialize the counter within the do block as
do {
numDigitsCorrect = 0;
sumDigitsCorrect = 0;
.. // existing logic
}
I have Loop and I am trying to print the nth term when the loop is less than 40, all of this without stoping the loop when is less than 40. I have tried to print it when the total is less than 40 but I it is pringting the last nth value.
All I need is th nth value when the loop drops bellow 40. I have almost complete my code but this problem is slowing me down.
Working example, This is what the output is supposed to be
Please input mark: 82
Please input number of days to display: 3
Scheme 1
(0) 82.0 (1) 73.80 (2) 66.42 (3) 59.78
This work can be up to 6 days late before failing.
.
.
This is what my program outputs
Please input mark: 82
Please input number of days to display: 3
Scheme 1
(0) 82.0 (1) 73.80 (2) 66.42 (3) 59.78
.
.
loop
int yourValue = -1;
// Loop
while (true)
{
if (numOfDays >= i) System.out.print("(" + i + ") ");
System.out.printf("%.02f",total);
System.out.print(" ");
total = total * 0.9;
if (total <= 20) {
if (numOfDays >= i) System.out.print("\nBecause mark drops below 20, mark stays as 20. final mark="+ finalMark);
break;
}
if (total < 40 && yourValue == -1) yourValue = i;
i++;
}
System.out.print("\nThis work can be up to " + yourValue + " days late before failing.");
I don´t know for sure if I correctly understand what you problem is, but try this code:
int yourValue = -1;
// Loop
for(i = 0;i <= numOfDays;i++){
System.out.print("(" + i + ") " + total+ " ");
total = total -5;
//yourValue will only be filled the first time total is below 40
if (total < 40 && yourValue == -1) yourValue = i;
if (total<=20){
System.out.print("\nBecause mark drops below 20, mark stays as 20. final mark="+ finalMark);
break;
}
} // End
if (yourValue > -1) System.out.print("\nThis work can be up to " + yourValue + " days late before failing.");
If total falls under 40, the value of i is stored in yourValue
If total falls under 20 the loop is exited and you can continue with the code behind the loop
Edit:
You can´t "get value beyond loop" but you easily can restructure you code:
(code not tested)
int total2 = total;
//Loop
for(i = 0;i <= numOfDays;i++){
System.out.print("(" + i + ") " + total+ " ");
total -= 5;
if (total<=20){
System.out.print("\nBecause mark drops below 20, mark stays as 20. final mark="+ finalMark);
break;
}
}
System.out.print("\nThis work can be up to " + Math.floor((total2 – 40) / 5)+ " days late before failing.");
Edit2:
Note that you either have to round the value for total into an integer or you have to use a double for total (In example i expect that total is a double)
int i = 0;
int yourValue = -1;
while (true)
{
if (numOfDays > i) System.out.print("(" + i + ") " + total+ " ");
total = total * 0.9;
if (total <= 20) {
if (numOfDays > i) System.out.print("\nBecause mark drops below 20, mark stays as 20. final mark="+ finalMark);
break;
}
if (total < 40 && yourValue == -1) yourValue = i;
i++;
}
System.out.print("\nThis work can be up to " + yourValue + " days late before failing.");
The loop is running as long as the total as greater than 20 or i is smaller than numOfDay, but for the output it is checked if i is still lower than numOfDays
Edit3:
double total2 = total;
//Loop
...
//End Loop
int counter = -1;
while(total2 >= 40) {
counter++;
total2 = total2 + 0.9;
}
System.out.print("\nThis work can be up to " + counter+ " days late before failing.");
Edit4:
I think I found a formula in exchange for this one Math.floor((total2 – 40) / 5)
try out following:
Math.floor((Math.log(40/total2)/log(0.9))+0.5)
had no time to check this out in practice but it should work.
I am not sure if I understand this correctly, but a code which outputs your expected behavior is something like:
boolean isFinished = false;
int lastValue = 0;
for(i = 0;i <= numOfDays;i++){
System.out.print("(" + i + ") " + total+ " ");
total = total -5;
if (total<=20){
System.out.print("\nBecause mark drops below 20, mark stays as 20. final mark="+ total);
break;
}
if (!isFinished && total < 40){
isFinished = true;
lastValue = i;
}
}
if(isFinished) {
System.out.print("\nThis work can be up to " + lastValue);
}
your if statement it out of the for the for loop block it suppose to be like this:
// Loop
for(int i = 0;i <= numOfDays;i++){
System.out.print("(" + i + ") " + total+ " ");
total = total -5;
if (total<=20){
System.out.print("\nBecause mark drops below 20, mark stays as 20.
final mark="+ finalMark);
return;
}
if (total < 40){
System.out.print("\nThis work can be up to " + i);
}
}
So I have a piece of code where I want to output the seconds as an integer, but I don't want to lose the decimal value as I need to use it as part of the count in a for loop to code the program correctly, here is the code (for loop is unfinished obviously as there is no count)
System.out.println("Recommended Splits for Marathon for time of "
+ hours + ":" + minutes + ":" + seconds);
hoursInSeconds = hours * 3600;
minutesInSeconds = minutes * 60;
totalTime = hoursInSeconds + minutesInSeconds + seconds;
double totalSecondsPerKM = totalTime/42;
int hoursPerKM = (int) (totalSecondsPerKM/3600);
double remainderHours = totalSecondsPerKM%3600;
int minutesPerKM = (int) (totalSecondsPerKM/60);
double secondsPerKM = (totalSecondsPerKM%60);
for (int index = 1; index <=42; index++){
System.out.print(index + " ");
System.out.print("" +hoursPerKM);
System.out.print("");
System.out.print(":"+minutesPerKM);
System.out.print("");
System.out.print(":"+secondsPerKM);
System.out.println("");
You could use
System.out.println(String.format("%.0f", 1.6));
or
System.out.println((int)1.6);
The first will round the value, output 2, the second will truncate it, outputting 1
Java input;
import java.util.*;
public class NetPay3
{
public static void main()
{
// Define Scanner object
Scanner inLine = new Scanner (System.in);
// Define other variables
float pay;
int OneHundredPounds, FiftyPounds, TwentyPounds, FivePounds,
OnePound, FiftyPence, TwentyPence, FivePence, TwoPence, OnePenny;
// Ask for the time in seconds
System.out.print ("Enter Net Pay : ");
pay = inLine.nextFloat();
// Calculate the hours. There are (3600)
// i.e. 60 x 60 seconds in every hour
OneHundredPounds = (int) pay / 100;
// Calculate what is left over and store back into seconds
pay = pay % 100;
// Calculate the minutes. There are 60 seconds
// in a minute.
FiftyPounds = (int) pay / 50;
// Whatever is left over must be the seconds
pay = pay % 50;
// Calculate the hours. There are (3600)
// i.e. 60 x 60 seconds in every hour
TwentyPounds = (int) pay / 20;
// Calculate what is left over and store back into seconds
pay = pay % 20;
// Calculate the hours. There are (3600)
// i.e. 60 x 60 seconds in every hour
FivePounds = (int) pay / 5;
// Calculate what is left over and store back into seconds
pay = pay % 5;
// Calculate the hours. There are (3600)
// i.e. 60 x 60 seconds in every hour
OnePound = (int) pay / 1;
// Calculate what is left over and store back into seconds
pay = pay % 1;
// Calculate the hours. There are (3600)
// i.e. 60 x 60 seconds in every hour
FiftyPence = (int) pay / 2;
// Calculate what is left over and store back into seconds
pay = pay % 2;
// Display the hours, minutes and seconds
System.out.println ("Amount of £100 notes " + OneHundredPounds);
System.out.println ("Amount of £50 notes " + FiftyPounds);
System.out.println ("Amount of £20 notes " + TwentyPounds);
System.out.println ("Amount of £5 notes " + FivePounds);
System.out.println ("Amount of £1 coins " + OnePound);
System.out.println ("Amount of 50p coins " + FiftyPence);
}
}
Screen input and output;
Enter Net Pay : 176.50
Amount of £100 notes 1
Amount of £50 notes 1
Amount of £20 notes 1
Amount of £5 notes 1
Amount of £1 coins 1
Amount of 50p coins 0
Hi relatively new to programming,
having trouble with me modulus and int operators in terms of getting them to function with the correct output on screen, previous syntax's worked correctly bar the 50p, anyone care to shed any light? thanks :)
Try changing FiftyPence = (int) pay / 2; toFiftyPence = (int) (pay / 0.5f);
Here is your code corrected and improved.
Don't use floats here, use integer arithmetic.
import java.util.*;
public class NetPay3 {
public static void main(String[] args) {
// Define Scanner object
Scanner inLine = new Scanner(System.in);
// Define other variables
int pay;
int OneHundredPounds, FiftyPounds, TwentyPounds, FivePounds, OnePound, FiftyPence, TwentyPence, FivePence, TwoPence, OnePenny;
System.out.print("Enter Net Pay : ");
float pay1 = inLine.nextFloat();
pay = (int) (100 * pay1);
OneHundredPounds = (int) pay / 10000;
pay = pay % 10000;
FiftyPounds = (int) pay / 5000;
pay = pay % 5000;
TwentyPounds = (int) pay / 2000;
pay = pay % 2000;
FivePounds = (int) pay / 500;
pay = pay % 500;
OnePound = (int) pay / 100;
pay = pay % 100;
FiftyPence = (int) pay / 50;
pay = pay % 50;
System.out.println("Amount of £100 notes " + OneHundredPounds);
System.out.println("Amount of £50 notes " + FiftyPounds);
System.out.println("Amount of £20 notes " + TwentyPounds);
System.out.println("Amount of £5 notes " + FivePounds);
System.out.println("Amount of £1 coins " + OnePound);
System.out.println("Amount of 50p coins " + FiftyPence);
System.out.println("Leftover pence: " + pay);
}
}
But I would further simplify this to (for example) this program:
import java.util.*;
public class NetPay3 {
public static void main(String[] args) {
Scanner inLine = new Scanner(System.in);
float[] val = new float[]{100, 50, 20, 5, 1, 0.5f, 0.2f, 0.05f, 0.02f, 0.01f};
int pay;
System.out.print("Enter Net Pay : ");
float pay1 = inLine.nextFloat();
pay = (int) (100 * pay1);
for (int i=0; i<val.length; i++){
int m = ((int)(val[i] * 100));
int cnt = pay / m;
String s1 = val[i] < 1 ? " coins: " : " notes: ";
String s2 = val[i] < 1 ? "" : "£";
String s3 = val[i] < 1 ? "p" : "";
String s4 = val[i] < 1 ? m + "" : (m/100) + "";
System.out.println("Amount of " + s2 + s4 + s3 + s1 + cnt);
pay = pay % m;
}
}
}
I wrote a programm to get the cross sum of a number:
So when i type in 3457 for example it should output 3 + 4 + 5 + 7. But somehow my logik wont work. When i type in 68768 for example i get 6 + 0 + 7. But when i type in 97999 i get the correct output 9 + 7 + 9. I know that i have could do this task easily with diffrent methods but i tried to use loops . Here is my code: And thanks to all
import Prog1Tools.IOTools;
public class Aufgabe {
public static void main(String[] args){
System.out.print("Please type in a number: ");
int zahl = IOTools.readInteger();
int ten_thousand = 0;
int thousand = 0;
int hundret = 0;
for(int i = 0; i < 10; i++){
if((zahl / 10000) == i){
ten_thousand = i;
zahl = zahl - (ten_thousand * 10000);
}
for(int f = 0; f < 10; f++){
if((zahl / 1000) == f){
thousand = f;
zahl = zahl - (thousand * 1000);
}
for(int z = 0; z < 10; z++){
if((zahl / 100) == z){
hundret = z;
}
}
}
}
System.out.println( ten_thousand + " + " + thousand + " + " + hundret);
}
}
Is this what you want?
String s = Integer.toString(zahl);
for (int i = 0; i < s.length() - 1; i++) {
System.out.println(s.charAt(i) + " + ");
}
System.out.println(s.charAt(s.length()-1);
The problem with the code you've presented is that you have the inner loops nested. Instead, you should finish iterating over each loop before starting with the next one.
What's happening at the moment with 68768 is when the outer for loop gets to i=6, the ten_thousand term gets set to 6 and the inner loops proceed to the calculation of the 'thousand' and 'hundred' terms - and does set those as you expect (and leaving zahl equal to 768 - notice that you don't decrease zahl at the hundreds stage)
But then the outer loop continues looping, this time with i=7. With zahl=768, zahl/1000 = 0' so the 'thousand' term gets set to 0. The hundred term always gets reset to 7 with zahl=768.
The 97999 works because the thousand term is set on the final iteration of the 'i' loop, so never gets reset.
The remedy is to not nest the inner loops - and it'll perform a lot better too!
You should do something like this
input = 56789;
int sum = 0;
int remainder = input % 10 // = 9;
sum += remainder // now sum is sum + remainder
input /= 10; // this makes the input 5678
...
// repeat the process
To loop it, use a while loop instead of a for loop. This a great example of when to use a while loop. If this is for a class, it will show your understanding of when to use while loops: when the number of iterations is unknown, but is based on a condition.
int sum = 0;
while (input/10 != 0) {
int remainder = input % 10;
sum += remainder;
input /= 10;
}
// this is all you really need
Your sample is a little bit complicated. To extract the tenthousand, thousand and the hundreds you can simply do this:
private void testFunction(int zahl) {
int tenThousand = (zahl / 10000) % 10;
int thousand = (zahl / 1000) % 10;
int hundred = (zahl / 100) % 10;
System.out.println(tenThousand + "+" + thousand + "+" + hundred);
}
Bit as many devs reported you should convert it to string and process character by character.