What is wrong with my looping? - java

public class Prices {
public static void main(String[] args) {
int i = 100;
int z = 0;
int x = 0;
int a = 0;
int v = 0;
double sum = 0;
double[][] MovingAvgArray = new double[i][i];
double[] List = {20.19, 21.67, 22.49, 22.26,23.99, 23.75, 23.34, 23.54, 23.25, 23.9, 23.84, 23.19, 22.03, 22.7, 21.14, 22.54, 24.36, 24.85, 23.96, 25.1, 20.79, 19.96, 19.98, 19.54, 19.09, 18.47, 18.59, 18.96, 18.93, 18.79, 19.06, 19.82, 19.5, 19.13, 19.25, 18.9, 19.05, 19.02, 19.09, 18.73, 18.44, 18.65, 18.07, 18.12, 17.92, 18.21, 17.81, 18.57, 18.92, 18.4, 17.83, 17.83, 18.55, 18.25, 18.55, 17.72, 17.28, 17.37, 16.99, 16.28, 17.02, 15.68, 15.73, 16.45, 15.54, 15.15, 15.51, 15.51, 15.54, 15.05, 14.98, 15.88, 16.14, 16.2, 16, 16.82, 17.74, 18.01, 17.99, 18.01, 16.99, 18, 18.3, 19.02, 18.14, 18.95, 19.19, 18.67, 17.63, 17.6, 17.56, 18.59, 18.57, 19.07, 19.57, 19.59, 18.71, 18.71, 18.75, 19.37};
do{
do{
for(;v < a + x +2;)
{
sum = sum + List[v];
v++;
}
MovingAvgArray[x][z] = sum;
MovingAvgArray[x][z] = (MovingAvgArray[x][z])/(x + 2.0);
System.out.println(MovingAvgArray[x][z]);
z++;
a++;
sum = 0;
v--;
}while(z<100-(x+1));
v = 0;
z=0;
x++;
}while(x<i-2);
}
}
The goal of this program is to get the moving average(which is calculated in the for loop) of the List of data, starting at the moving average of the first two numbers, then the first three, ect. and plug it into MovingAvgArray. The moving average of two numbers would be on the array values [0][0 through (i-3)], the average of three numbers would be on values [0][0 through (i-4)], ect ect. Until this is no longer possible.
If i take out the outermost do-while loop the program runs without error, but only calculates the moving average for two numbers(there will be 98 of them).
When i try to loop it to do three numbers which is the above code i get the error "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100" on the line that says "sum=sum+List[v];
which im pretty sure means that the v in List[v] is a number that is greater than the values listed in List[v]. (its trying to get the 101th value in a array that only has 100 values).
The problem is i have no idea why this is happening because "v" should be set back to 0 before this loop tries to run again.

I have allowed myself to add extra println's to the code, like
v--;
System.out.println(" ------------------ v=" + v);
System.out.println(" ------------------ z=" + z);
System.out.println(" ------------------ x=" + x);
System.out.println(" ------------------ a=" + a);
} while (z < 100 - (x + 1));
System.out.println(" HERE ");
v = 0;
just to observe that:
19.060000000000002
------------------ v=99
------------------ z=99
------------------ x=0
------------------ a=99
HERE
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100
at Prices.main(Prices.java:24)
this means that the loop controlled by
while (z < 100 - (x + 1))
ends. a is still 99, x is increased by 1, making a + x + 2=102

Related

JAVA Code that checks for duplicates doesn't work

I am learning how to code and my teacher gave me an exercise to create a lottery program that generates 6 random numbers between 1 and 49 with no duplicates and one bonus number that could be a duplicate. My program generates all the numbers fine, but for some reason duplicates still appear. Could someone please explain why the code that checks for duplicates doesn't work, as I have been struggling to understand why it doesn't work. Please bear in mind that I'm a new programmer so try and keep explanations beginner friendly. Thanks in advance.
int[] lottonums = new int[6];
//Generates 6 random numbers between 1-49
for(int i = 0; i < lottonums.length; i++){
lottonums[i] = (int)(Math.random()* 49 +1);
}
//Checks for duplicates
for(int x = 0; x < 6; x ++){
for(int y = x + 1; y < 6; y ++){
while(lottonums[x] == lottonums[y]){
lottonums[y] = (int)(Math.floor(Math.random() * 49 + 1));
}
}
}
//Bonus ball, no checks for duplicates
int bonusBall = (int)(Math.random() * 49 + 1);
Arrays.sort(lottonums);
System.out.println("\nThe lottery numbers are: ");
for( int nu = 0; nu < lottonums.length; nu ++){
System.out.print(lottonums[nu] + " " );
}
System.out.println("\nThe bonus number is: " + bonusBall + "\n");
Best Way to have unique number is by using Set instead of array.
if you are not aware much about set have a look into it set TreeSet
Basically if you look at your code
//Checks for duplicates
for(int x = 0; x < 6; x ++){
for(int y = x + 1; y < 6; y ++){
while(lottonums[x] == lottonums[y]){
//below line does not gurrantee its going to insert unique number
//example [1,2,6,6] here at index 2 and 3 6 is there
//now you got this while checking duplicate
//after you are generating new random suppose new generated number is 2
// as you are not going back to check duplicate so it will be inserted
lottonums[y] = (int)(Math.floor(Math.random() * 49 + 1));
}
}
}
you can try the below solution using set
which fits yous requirement
// TreeSet will have unique element in sorted manner no need to sort again
TreeSet<Integer> set=new TreeSet<>();
int n=6;
while(set.size()<n-1)
{
set.add((int)(Math.random()* 49 +1));
}
//Bonus ball, no checks for duplicates
int bonusBall = (int)(Math.random() * 49 + 1);
System.out.println("\nThe lottery numbers are: ");
for( int nu :set){
System.out.print(nu + " " );
}
System.out.println("\nThe bonus number is: " + bonusBall + "\n");
}

Not receiving correct output for the following nested for loop

I need an explanation for the following loop:
public static void main(String[] args) {
int x = 0;
int y = 30;
for (int outer = 0; outer < 3; outer++) {
for (int inner = 4; inner > 1; inner--) {
x = x + 6;
y = y - 2;
if (x == 6) {
break;
}
x = x + 3;
}
y = y - 2;
}
System.out.println(x + " " + y);
}
The way I'm seeing it is that the 'outer' loop is running 3 times and the 'inner' loop is running 9 times. When I go through the 'inner' loop, x becomes 6, and we break out of the 'inner' loop after we get the value for y, which is 28. So now, the value of x is 6, and now I go through the 'outer' loop which runs 3 times, so 3 times 2 is equal to 6, so I subtract that from 28, and I end up with 22.
Output:
6 22
Does anyone know what I am doing wrong? I know the output should be 60 10, but I am not getting this. Thanks for your help.
I have copied and pasted your code in my pc and I get the out put
60 10
I think your are running a different file in your IDE.
What IDE do you use?

Printing Small Numbers Between 1 and 100 in Java

I'm new to Java and this is a simple question but i'm having trouble printing small numbers between 1 and 100. Small numbers are those less than 20 and I want my program to print out "small x" for each small number.
When I run this I'm not getting what I'm suppose to I just get "small x" printed 100 times.
Here's my code:
class ExerciseA {
public static void main(String[] args) {
int x = 1;
while ( x < 100 ) {
x = x + 1;
if( x > 20) {
System.out.println("small x");
}
}
}
}
> means greater, but you want lesser. So use <. Another thing in your code, 1 would not be printed as it's being incremented before printing. This should be:
int x = 0;
while ( x < 100 ) {
x++; // shorter than x = x + 1;
if (x < 20) {
System.out.println("small x");
//System.out.println("small " + x); //if want to print like small 1, small 2 etc.
}
}
Your System.out.println is printing small x since it is using the whole string instead of using the value of variable x.
Also, if you want to print small x for numbers less than 20, you should use x<20.
int x = 0;
while ( x < 100 ) {
x = x + 1;
if( x < 20) {
System.out.println("small " + x);
}
}
You can write down such kind of loops in the more matching for-loop style:
for (int i = 1; i <= 100; i++) {
if (isSmall(i)) {
System.out.println("small i");
}
using a bit of "re-factoring" by putting the check "is this a small number" into its own method:
private boolean isSmall(int i) {
return i < 20;
}
Using such small methods is something that you should get used to as soon as possible - as it helps to "isolate" certain functionality. Another change I made: in computer science, variables for whole numbers are typically called "i,j,k" ... and so on; whereas x, y, ... would be for floating point numbers!
And of course: you got the comparison wrong - if you want numbers smaller than 20, well, than you have to say so ( i < 20 ).

Simulating unfair dice with java/R (programming done)

Task : Unfair die(6 sides) is being rolled n times. Probability of 1 is p1, probability of 2 is p2 and so on. Write a computer program, that for given n (n<100), the probability of set (p1,p2,p3,p4,p5,p6) and $x \in [n,600n]$ would find the probability of sum of dice values is less than x. Program cannot work more than 5 minutes. This is an extra question that will give me extra points, but so far nobody has done it. I quess beginner computer scientist like me can learn from this code also, since i found 0 help with bias dice in the web and came up with roulette like solution. I kind of wanted to show the world my way also.
I have 2 solutions - using geometrical and statistical probability.
My question is: 1) Is it correct when i do it like this or am i going wrong somewhere ?
2) Which one you think gives me better answer geometric or statistical probability ?
My intuition says it is geometric, because it is more reliable.
i think it is correct answer that my code is giving me - more than 0.99..... usually.
I wanted somebody to check my work since i'm not sure at all and i wanted to share this code with others.
I prefer Java more since it is much faster than R with loops, but i gave R code also for statistical , they are very similar i hope it is not a problam.
Java code :
import java.util.ArrayList;
public class Statistical_prob_lisayl2_geometrical {
public static double mean(ArrayList<Double> a) {
double sum=0;
int len = a.size();
for (int i = 0; i < len; i++) {
sum = sum + a.get(i);
}
return (sum/len);
}
public static double geom_prob(double p1,double p2,double p3,double p4,double p5,double p6){
ArrayList<Double> prob_values = new ArrayList<Double>();
int repeatcount = 1000000;
int[] options = {1,2,3,4,5,6};
int n = 50;
double[] probabilities = {p1,p2,p3,p4,p5,p6};
for (int i = 0 ; i < repeatcount ; i++ ) { // a lot of repeats for better statistical probability
int sum = 0; //for each repeat, the sum is being computed
for (int j = 0; j < n ; j++ ) { // for each repeat there is n cast of dies and we compute them here
double probability_value=0; // the value we start looking from with probability
double instant_probability = Math.random(); // we generate random probability for dice value
for (int k = 0; k < 6; k++ ) { // because we have 6 sides, we start looking at each probability like a roulette table
probability_value = probability_value + probabilities[k]; // we sum the probabilities for checking in which section the probability belongs to
if (probability_value>instant_probability) {
sum = sum + options[k]; // if probability belongs to certain area , lets say p3 to p4, then p3 is added to sum
break; // we break the loop , because it would give us false values otherwise
}
}
}
double length1 = (600*n)-n-(sum-n); //length of possible x values minus length of sum
double length2 = 600*n-n;
prob_values.add( (length1/length2) ); // geometric probability l1/l2
}
return mean(prob_values); // we give the mean value of a arraylist, with 1000000 numbers in it
}
public static double stat_prob(double p1,double p2,double p3,double p4,double p5,double p6){
ArrayList<Double> prob_values = new ArrayList<Double>();
int repeatcount = 1000000;
int[] options = {1,2,3,4,5,6};
int n = 50;
double[] probabilities = {p1,p2,p3,p4,p5,p6};
int count = 0;
for (int i = 0 ; i < repeatcount ; i++ ) {
int sum = 0;
for (int j = 0; j < n ; j++ ) {
double probability_value=0;
double instant_probability = Math.random();
for (int k = 0; k < 6; k++ ) {
probability_value = probability_value + probabilities[k];
if (probability_value>instant_probability) {
sum = sum + options[k];
break;
}
}
}
int x = (int)Math.round(Math.random()*(600*n-n)+n);
if( x>sum ) {
count = count + 1;
}
}
double probability = (double)count/(double)repeatcount;
return probability;
}
public static void main(String[] args) {
System.out.println(stat_prob(0.1,0.1,0.1,0.1,0.3,0.3));
System.out.println(geom_prob(0.1,0.1,0.1,0.1,0.3,0.3));
}
}
R code:
repeatcount = 100000
options = c(1,2,3,4,5,6)
n = 50
probabilities = c(1/10,1/10,1/10,1/10,3/10,3/10)
count = 0
for (i in 1:repeatcount) {
sum = 0
for (i in 1:n) {
probability_value=0
instant_probability = runif(1,0,1)
for (k in 1:6){
probability_value = probability_value + probabilities[k]
if (probability_value>instant_probability) {
sum = sum + options[k]
break
}
}
}
x = runif(1,n,600*n)
x
sum
if ( x> sum ) {
count = count + 1
}
}
count
probability = count/repeatcount
probability
Is this what you are trying to do??
n <- 50 # number of rolls in a trial
k <- 100000 # number if trials in the simulation
x <- 220 # cutoff for calculating P(X<x)
p <- c(1/10,1/10,1/10,1/10,3/10,3/10) # distribution of p-side
X <- sapply(1:k,function(i)sum(sample(1:6,n,replace=T,prob=p)))
P <- sum(X<x)/length(X) # probability that X < x
par(mfrow=c(1,2))
hist(X)
plot(quantile(X,probs=seq(0,1,.01)),seq(0,1,.01),type="l",xlab="x",ylab="P(X < x)")
lines(c(x,x,0),c(0,P,P),col="red",lty=2)
This makes sense because the expected side
E(s) = 1*0.1 + 2*0.1 + 3*0.1 + 4*0.1 + 5*0.3 + 6*0.3 = 4.3
Since you are simulating 50 rolls, the expected value of the total should be 50*4.3, or about 215, which is almost exactly what it is.
The slow step, below, runs in about 3.5s on my system. Obviously the actual time will depend on the number of trials in the simulation, and the speed of your computer, but 5 min is absurd...
system.time(X <- sapply(1:k,function(i)sum(sample(1:6,n,replace=T,prob=p))))
# user system elapsed
# 3.20 0.00 3.24

Making a basic multiplication table in java using loop

Hi I am a beginner so please don't use any complicated stuff.
Here is a SS of what i mean. http://prntscr.com/1ffec0
as of now don't worry about having numbers vertically and horizontally that display what columns and row number it is.
I have my code but am totally confused on how to go about it and how to make them multiply.
import java.util.Scanner;
public class test
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner (System.in);
int x=0, y=0;
System.out.print("Enter rows ");
x = keyboard.nextInt();
System.out.print("Enter columns ");
y = keyboard.nextInt();
for (int i=1; i<=x; i++)
{
for (int j=1; j<=y; j++)
{
System.out.print(" "+i+j);
}
System.out.println();
}
}
}
I'm not going to give you the answer straight out, but I'm going to help you understand the problem better with some pseudocode. Assume that your x-range goes from 1 to 3, and your y-range also goes from 1 to 3.
You did correctly set up 2 loops
Loop x = 1 to 3
Loop y = 1 to 3
//Do stuff
End innerloop
End outerloop
Now consider the values that will be printed at //do stuff, in pairs like (x, y):
(1, 1) , (1, 2), (1, 3), (2, 1), (2, 2), and so on until (3, 3);
Obviously you want the product to be displayed, so create some variable z = x * y inside the loops
//Do stuff:
z = x * y
Print z + " "
Print z out and leave a space, because you want to print the next value without it being adjacent to the first value.
This will print all your solutions in a straight, single line. But you want it to be in a matrix obviously. The answer is to simple a simple change, taking only one line of code. After each full cycle of your inner loop, you essentially finish one row of multiplication (think about why). So the solution is that after your inner loop finishes running, right before going to the next outer loop value for x, you want to print a new line. All in all we have something like:
Loop x = 1 to 3
Loop y = 1 to 3
z = x * y
Print z + " "
End innerloop
Print NewLine // "\n" is the way to do that
End outerloop
And you're done. You just need to put it into code, as well as accept user input instead of hard coding the range as from 1 to 3, or whatever. This is trivial and I'm sure you'll be able to put it together.
change the i+j by i*j
btw you are printing only half of the matrix
You need to use "*" instead of "+" ?
Like this:
public static void print(int x, int y) {
for (int i = 1; i <= x; i++) {
for (int j = 1; j <= y; j++) {
System.out.print(" " + i * j);
}
System.out.println();
}
}
And after that you might want to think about the formatting!? My advice: think about the length of the longest value (is always x*y) and "reservice" enought space for it!
Change:
System.out.print(" "+i+j);
To:
if ((i + j) <= 9) {
System.out.print(i + j + " ");
} else if ((i + j) <= 99) {
System.out.print(i + j + " ");
} else
System.out.print(i + j + " ");

Categories