Having trouble producing two seperate outputs using Random - java

I'm trying to create two separate outputs of 10 columns and 10 rows of numbers. The first output using numbers 4 through 7 and the second output using numbers 10 through 90 (e.g. 10, 20, 30 and so on). But calling these numbers randomly, not in a special order. Below is the Java code I have:
import java.util.Random;
public class LabRandom
{
private static final Random rand = new Random();
public static void main(String[] args)
{
int number;
int i = 1;
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(4) + 4);
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
System.out.println();
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(10 *(80) + 10));
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
}
}
I just can't figure out what I am missing, The code only runs the first while statement and not the second while statement.

You haven't reinitialised i, and after the first loop, it will already equal 101, so the second loop will not be entered.
As was mentioned in the comments on your question, a for loop would be a more appropriate construct here.
Also, in that second loop, the statement:
rand.nextInt(10 *(80) + 10)
Doesn't seem like it will do what you want. You probably need something like:
rand.nextInt(9) * 10 + 10

You need to reset i before your second while.

set the value of i before the second while loop.
import java.util.Random;
public class LabRandom
{
private static final Random rand = new Random();
public static void main(String[] args)
{
int number;
int i = 1;
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(4) + 4);
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
System.out.println();
i = 1;//modified here
while (i <= 100)
{
//number = rand.nextInt(4) + 4;
System.out.printf("%-5d", rand.nextInt(10 *(80) + 10));
if (i % 10 == 0)
{
System.out.println();
}
i++;
}
}
}

Related

Return the minimum number from the given array using while loop Java

Hi guys. How are you? =)
I'm new to Java and currently
I have a task to create a method, it takes one parameter sum - the amount of money to be given out, and returns the minimum number of banknotes that can be given out this amount.
Only While loop can be used.
I made it with for loop, but I can't find where I made mistake in while loop.
Could you please give me hint or advice?
Thank you!
public class ATM {
public static int countBanknotes(int sum) {
int[] notes = new int[] { 500, 200, 100, 50, 20, 10, 5, 2, 1 };
int[] noteCounter = new int[9];
int amount = 0;
for (int i = 0; i < 9; i++) {
if (sum >= notes[i]) {
noteCounter[i] = sum / notes[i];
sum -= noteCounter[i] * notes[i];
}
}
for (int i = 0; i < 9; i++) {
if (noteCounter[i] != 0) {
amount += noteCounter[i];
}
}
return amount;
}
public static void main(String[] args) {
// 6 (500 + 50 + 20 + 5 + 2 + 1
int sum = 578;
System.out.print(ATM.countBanknotes(sum));
}
}
And while loop
public class JustATest {
public static int countBanknotes(int sum) {
int[] notes = new int[] { 500, 200, 100, 50, 20, 10, 5, 2, 1 };
int[] noteCounter = new int[9];
int amount = 0;
int i = 0;
while ( i < 9 ) {
if (sum >= notes[i]) {
i++;
noteCounter[i] = sum / notes[i];
sum -= noteCounter[i] * notes[i];
}
}
while ( i < 9 ) {
if (noteCounter[i] != 0) {
i++;
amount += noteCounter[i];
}
}
return amount;
}
public static void main(String[] args) {
// Should be 6 (500 + 50 + 20 + 5 + 2 + 1)
int sum = 578;
System.out.print(JustATest.countBanknotes(sum));
}
}
You need to reinitialize your i variable between the loops, or use another variable, like j.
Furthermore, you should not have your i++ inside the if statements in your while loops. Otherwise, there are scenarios where the counter is never incremented and you will have an endless loop. That is bad!
Put your i++ in the bottom of the while loop outside the if statement like this:
while ( i < 9 ) {
if (sum >= notes[i]) {
noteCounter[i] = sum / notes[i];
sum -= noteCounter[i] * notes[i];
}
i++;
}
int j = 0;
while ( j < 9 ) {
if (noteCounter[j] != 0) {
amount += noteCounter[j];
}
j++;
}
This way, the counters are always incremented no matter what, and you will not have endless loops.
I included a fix for your problem in the code above as well.
You need to reinitialize your i value to 0 for the second while loop
You must execute i++ in your while loop everytime. Otherwise you will get into endless loop.
You must reset i before going to next loop. So one iterator i for two loops is not recommended.
public static int countBanknotes(int sum) {
int[] notes = new int[]{500, 200, 100, 50, 20, 10, 5, 2, 1};
int[] noteCounter = new int[9];
int amount = 0;
int i = 0;
while (i < 9) {
if (sum >= notes[i]) {
noteCounter[i] = sum / notes[i];
sum -= noteCounter[i] * notes[i];
}
i++;
}
i = 0;
while (i < 9) {
if (noteCounter[i] != 0) {
amount += noteCounter[i];
}
i++;
}
return amount;
}

Adding a specifically chosen number in a For loop to work out the total mutiplies number Java

public class totalCount {
public static void main(String[] args){
int total = 0;
for (int i=1; i<=100;i++){
if(i%2==0){
System.out.println(i);
} else if(i%4==0){
System.out.println(i);
}
total +=i;
}
System.out.println(total);
}
}
I am in a bit of confusion, I tried to create a for loop function to specifically pick out the mutiplies of 2 and 4 up to 100 and then finding the sum of the number. However, I am unable to find the sum of the number as I can't seem to add up the total number generated by the for loop. How do I find the total sum?
First of all you only need i % 2 == 0 as anything divisible by four is also divisible by two. Second you need to move the line total += i; into the if statement:
for (int i = 1; i <= 100; i++){
if(i % 2 == 0){
System.out.println(i);
total += i;
}
}
System.out.println(total);
Another solution using Lambda
import java.util.stream.IntStream;
public class TotalCount {
public static void main(String[] args) {
final int[] total = new int[2];
final int START = 1;
final int END = 100;
// loop from 1 through 100. endExclusive so need to use END + 1
IntStream.range(START, END + 1)
.filter(number -> number % 2 == 0)
.forEach(multipleOf2 -> total[0] += multipleOf2);
IntStream.range(START, END + 1)
.filter(number -> number % 4 == 0)
.forEach(multipleOf4 -> total[1] += multipleOf4);
System.out.println("Sum of multiples of 2: " + total[0]);
System.out.println("Sum of multiples of 4: " + total[1]);
}
}

Collatz Conjecture Recursion Error

I've lurked around for years, but today I have a question concerning my code. I am currently trying to create a collatz program that puts the number of steps for a certain number in an array, but at the same time puts the number of steps for every single number it passes through. Here's my code:
public class GenerousRecursion {
public static short steps;
public static int length;
public static short[] array = new short[101];
public static void main(String[] args) {
length = 100;
for (int count = 2; count < length + 1; count++){
steps = 0;
System.out.println(count + ": " + findCollatz(count));
}
}
public static short findCollatz(int number) {
if (number < length){
if (array[number] > 0) {
steps = array[number]++; return steps;
}
else if(number % 2 == 0) {
array[number] = findCollatz(number / 2);
steps ++;
return steps;
}
else {
array[number] = findCollatz(3 * number + 1);
steps ++;
return steps;
}
}
else {
if(number % 2 == 0) {
findCollatz(number / 2);
steps ++;
return steps;
}
else {
findCollatz(3 * number + 1);
steps ++;
return steps;
}
}
}
}
Here's a great video on the Collatz Conjecture: Numberphile
So here is the error being thrown (reduced), but I don't understand, because I am not anywhere near the bounds of any int or short:
Exception in thread "main" java.lang.StackOverflowError
at GenerousRecursion.findCollatz(GenerousRecursion.java:22)
at GenerousRecursion.findCollatz(GenerousRecursion.java:33)
at GenerousRecursion.findCollatz(GenerousRecursion.java:27)
I just listed these first three lines because these same three lines draw errors for hundreds of lines.
Whats the problem and how do I fix it? Thanks abunch!
Edit: When I ran the debugger, my program continously throws exceptions whenever the array is refrenced.
As stated in the video-clip continuing with 1 will end in an endless loop.
Try the following.
static int[] collatzCounts = new int[100];
static final int NO_COUNT = -1;
static {
Arrays.fill(collatzCounts, NO_COUNT);
collatzCounts{1] = 0; // Define collatz(1) = 0 (1, 4, 2, 1, ...)
}
public static void main(String[] args) {
for (int n = 2; n < 120; n++) {
int steps = countCollatz(n);
System.out.println(n + ": " + steps);
}
}
public static int countCollatz(int n) {
IntFunction f = k ->
k % 2 == 0
? 1 + countCollatz(k / 2)
: 1 + countCollatz(3 * k + 1);
//: 2 + countCollatz((3 * k + 1) / 2);
//if (n == 1) {
// return 0;
//}
if (n < collatzCounts.length) {
if (collatzCounts[n] == NO_COUNT) {
collatzCounts[n] = f.apply(n);
}
return collatzCounts[n];
} else {
return f.apply(n);
}
}
countCollatz simply counts the steps needed - to reach 1 actually. Though till further proof there might be a cycle of higher numbers.
I have used a Java 8 lambda expression, the IntFunction f, as it is more natural to repeat the calculation, once to fill the array, once for too large numberss.

Why does my program not work as expected?

I am working on problem twelve on project Euler. It is all about triangle numbers; I am trying to find the first triangle number with more than 500 divisors. I have written a program to find this, however, it is not giving me the correct answer and I can not see why. I have provided my code below:
public class problemTwelve {
public static void main(String [] args) {
int i = 1;
int number = 1;
while(getDivisors(number) < 500) {
number += i;
i++;
}
System.out.println("The first triangle number to have greater than 500 divisors is: " + number);
}
private static int getDivisors(int triangleNum) {
int noOfDivisors = 0;
int numToTest = (int) Math.sqrt(triangleNum);
for(int i = 1; i <= numToTest; i++) {
if((triangleNum % i) == 0) {
noOfDivisors += 2;
}
}
if((numToTest * numToTest) == triangleNum) {
noOfDivisors--;
}
return noOfDivisors;
}
}
The output given by the program upon running it is as follows:
The first triangle number to have greater than 500 divisors is: 146611080
Upon entering this number as the answer on project Euler, we can see that it is wrong. I don't know where I have gone wrong in my program...
It seems that the number you are checking are not triangle. Just at looking at the code, the second number checked is 2 which is not a triangle number.
Try moving the line i++; before the line number+=i;
you have to start your numbers from 0 not 1 , here is the correct code :
int i = 1;
int number = 0;
while(getDivisors(number) < 500) {
number += i;
i++;
}
System.out.println("The first triangle number to have greater than 500 divisors is: " + number);
}
private static int getDivisors(int triangleNum) {
int noOfDivisors = 0;
int numToTest = (int) Math.sqrt(triangleNum);
for(int i = 1; i <= numToTest; i++) {
if(triangleNum % i == 0) {
noOfDivisors += 2;
}
}
if((numToTest * numToTest) == triangleNum) {
noOfDivisors--;
}
return noOfDivisors;
}

How do you generate a random number with equal probability using Math.random() in Java [duplicate]

This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 9 years ago.
I'm currently working through an exercise where I am required to generate a random number which can be one of 4 values. (note I'm only allowed to use Math.random())
0
1
2
or 3
Currently I am using this: randno = (int) (Math.random()*4); // range 0-3
However, the outcome MUST have equal probability. My tests so far (although the method is lacking) shows that 3 occurs far less than the other numbers.
Is this coincidence? Or does my generator not have equal probability.
Thanks!
Your code works well:
public static void main(String[] args) {
int countZero = 0;
int countOne = 0;
int countTwo = 0;
int countThree = 0;
for(int i=0; i<400000; i++){
int randno = (int)(Math.random() * ((3) + 1));
if(randno == 0){
countZero++;
}
else if(randno == 1){
countOne++;
}
else if(randno == 2){
countTwo++;
}
else if(randno == 3){
countThree++;
}
}
System.out.println("Zero: " + countZero);
System.out.println("One: " + countOne);
System.out.println("Two: " + countTwo);
System.out.println("Three: " + countThree);
}
Output:
Zero: 99683
One: 99793
Two: 100386
Three: 100138
With random numbers, you can random get what appears to be non random. There is no guarantee that all sequences appear random. http://vanillajava.blogspot.com/2011/10/randomly-no-so-random.html
For the right random seed you can appear to get a non-random sequence, but these are just as likely as any other.
Random random = new Random(441287210);
for (int i = 0; i < 10; i++)
System.out.print(random.nextInt(10)+" ");
}
prints
1 1 1 1 1 1 1 1 1 1
and
Random random = new Random(-6732303926L);
for(int i = 0; i < 10; i++)
System.out.println(random.nextInt(10)+" ");
}
prints
0 1 2 3 4 5 6 7 8 9
Lastly
public static void main(String ... args) {
System.out.println(randomString(-229985452)+' '+randomString(-147909649));
}
public static String randomString(int seed) {
Random rand = new Random(seed);
StringBuilder sb = new StringBuilder();
for (int i = 0; ; i++) {
int n = rand.nextInt(27);
if (n == 0) break;
sb.append((char) ('`' + n));
}
return sb.toString();
}
prints
hello world
Just to make the comparison, I've put your approach next to this one.
public class Test {
private static int min = 0;
private static int max = 3;
private static Map<Integer, Integer> count = new HashMap<>();
public static void main(String[] args) {
OptionOne();
System.out.println("Option One: ");
for (Entry<Integer, Integer> entry : count.entrySet()) {
System.out.println(entry.getKey() + "\t " + entry.getValue());
}
count = new HashMap<Integer, Integer>();
OptionTwo();
System.out.println("\nOption Two:");
for (Entry<Integer, Integer> entry : count.entrySet()) {
System.out.println(entry.getKey() + "\t " + entry.getValue());
}
}
private static void OptionOne() {
for (int i = 0; i < 800000; i++) {
int number = min + (int) (Math.random() * ((max - min) + 1));
if (count.containsKey(number)) {
int sofar = count.get(number) + 1;
count.put(number, sofar);
} else {
count.put(number, 1);
}
}
}
private static void OptionTwo() {
for (int i = 0; i < 800000; i++) {
int number = (int) (Math.random() * 4);
if (count.containsKey(number)) {
int sofar = count.get(number) + 1;
count.put(number, sofar);
} else {
count.put(number, 1);
}
}
}
Output:
Option One:
0 199853
1 200118
2 200136
3 199893
Option Two:
0 199857
1 200214
2 199488
3 200441
Conclusion: your method works. Maybe your sample size wasn't enough?

Categories

Resources