Random numbers mean and standard deviation Java - java

So I have a program that has a 50 number long list with random numbers between 1 and 50. I need to find the mean and the standard deviation of said list. I'm having trouble with adding all the random numbers together.
This is the code I have so far:
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 1; i < 51; i++) {
list.add(new Integer(i));
}
Collections.shuffle(list);
for (int i = 0; i < 50; i++) { // Set to 50 as max number just for example
}
}
}

As #azro mentioned you are not using random ints from 1 to 50. You are just shuffling the numbers from 1 to 50 in the list.
If you really want a list of Random numbers from 1-50 then you can use Random::nextInt to get a random number like this:
ArrayList<Integer> list = new ArrayList<>();
Random r = new Random();
for (int i = 1; i <= 50; i++) {
list.add(r.nextInt(50) + 1);
}
or even easier using Random::ints in Java 8:
List<Integer> list = new Random().ints(50,1,51) // generate 50 random numbers from 1 inclusive to 51 exclusive
.boxed() // box each int
.collect(Collectors.toList()); // get a list with the numbers

A couple issues I see with the code. It sounds like you're attempting to add 50 random numbers to a list. What your above code actually does is add the numbers 1:50 (inclusive) to a list, and then randomly shuffle the order of those numbers in the list. You will still have non-random numbers (all the numbers 1:50 will still be in the list, just in a random order).
What you should be doing is randomly generating the numbers and then adding them to the list. For example:
Random rand = new Random();
int upperBound = 50;
int sum = 0;
for (int i = 0; i < 50; i++) {
int randInt = rand.nextInt(upperBound) + 1;
list.add(randInt);
sum += randInt;
}

I'm not sure about naming conventions. Does mean mean average? Sum divided by count?
Random random = new Random ();
int[] ia = IntStream.generate (()-> random.nextInt (50)).limit (50).toArray();
// ia wieder zu Stream machen?
IntStream is = IntStream.of (ia);
double avg = is.summaryStatistics().getAverage()
// indeed, summaryStatistics exists.
// Expression value is:
// IntSummaryStatistics{count=50, sum=1159, min=0, average=23,180000, max=47}
// but no stddev
double stddev (int[] l, double avg) {
double sum = 0.0;
for (double d : l) {
double xd = d - avg;
sum += xd * xd;
}
return sum;
}
double std = stddev (ia, avg);
A different way, working with mapToDouble:
is = IntStream.of (ia);
double qabw (int i, double avg) {
double abw = 1.0 * i - avg;
double q = abw * abw;
return q;
}
DoubleStream ds = is.mapToDouble(i-> qabw (i, avg));
double qsum ds.sum ();
I'm pretty fresh to the stream thing. It should be possible to feed the function stddev, which is, btw., incomplete, into a stream.
On the other side, by summaryStatistics().getAverage(), the stream is consumed and gone. So I have to store the values in an Array, for example, first, and then recreate a stream from the array.
Pretty complicated.
However, I think we need a Math.sqrt in the end for a correct value, and/or a division by count, so the mathematical part needs surely correction.
For improvement on working with streams: you're welcome.

Related

Not able to proceed with Series sum

I wanted to find the missing number in series so i thought a simple idea why not add all the numbers in array which are in series and hold it in one variable and then calculate the sum of series by formula Sn=n/2(a+l) but while calculating the series sum i am getting some error.
public class Missing {
public static void main(String[] args) {
int ar [] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int sum = 0; int total=0;
for(int num: ar)
{
sum = sum+num;
}
int n = ar.length;
int a = ar[0];
int l =ar[ar.length-1];
total = [n/2*(a+l)];
System.out.print("The missing number is "+(sum-total));
}}
total = [n/2*(a+l)]; ............................(1)
This is where i am getting error.
enter image description here
You can use the below logic which is much simpler to use and understand
for(int i=0;i<ar.length-1;i++)
{
if(ar[i]!=ar[i+1]-1)
{
System.out.print("The missing number is "+(ar[i]+1)+"\n");
break;
}
}
The first thing is in total = [n/2*(a+l)]; [] is not valid syntax in this context. The second thing I noticed, is that your formula to calculate the sum seems odd, maybe you meant Sn = (n * (a + l)) / 2?. After making those two changes the code should look as follows:
public class Missing {
public static void main(String[] args) {
int ar [] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int sum = 0;
for(int num: ar)
{
sum = sum+num;
}
int n = ar.length;
int a = ar[0];
int l =ar[ar.length - 1];
int total = (n * (a + l)) / 2;
System.out.print("The missing number is "+(sum - total));
// outputs 0 which is correct nothing is missing
// Now if you remove say 12 from the array
// by changing the array to int ar [] = {1,2,3,4,5,6,7,8,9,10,11,0,13};
// you should get back -12 which means 12 is missing
}
}
If you don't want to use my above logic. You have to make changes to your code:
Edit this:
int n = ar.length+1;
n has been assigned ar.length + 1 because that +1 is needed to compensate for the missing element in the array list
Also, the formula has not been correctly written into the code:
total = (n* (a + l))/2;
If you first divide n by 2 then, it will truncate the places after decimal point because n is an integer not a floating number. So, your logic would fail when n is not even.
And lastly, the missing number would be (sum-total) not the other way around because 'total' contains the missing number and 'sum' does not.
System.out.print("The missing number is "+(total-sum));

Random numbers in array where the mean is a whole number

I'm working on a a game where I have to generate an int array of 4 elements randomly. My problem is that the mean of all the array elements always have to be a whole number.
Example :
array 1 {4 , 2 , 3, 7} , the mean of the array is 28,75 which is not what I'm looking for,
array 2 {3 , 7 , 6 , 4} , the mean is 20 which is good
Now I could make a loop where I check if the mean of the randomly generated numbers is a whole number but that doesn't seems like an efficient way to do that.
The game I'm working for is mean sum for those who know it.
If the mean is a whole number, then the sum must be divisible by 4.
int[] n = new int[4];
Pick four numbers, and calculate their sum:
int sum = 0;
for (int i = 0; i < 4; ++i) {
sum += (n[i] = random.nextInt());
}
Calculate the remainder of sum / 4:
int r = sum % 4;
So you now need to adjust the sum so that sum % 4 == 0. You can either:
subtract r from any of the elements of the array:
n[random.nextInt(4)] -= r;
or add 4 - r to any element:
n[random.nextInt(4)] += 4 - r;
Ideone demo
Pick a target mean m and random integers n1, n2.
Your array is [m-n1, m+n1, m-n2, m+n2]. Haven't thought about what the properties of this distribution would be, but it should work.
I believe the following function does what you want, given arguments of how many values you want to generate (n) and what's an upper limit for the sum of the values (max).
private static Random r = new Random();
public static int[] makeSet(int n, int max) {
// The next line guarantees the result is divisible by n
int currentMax = n * (1 + r.nextInt(max / n));
Set<Integer> s = new HashSet<Integer>();
// Generate a set of unique values between 0 and the currentMax,
// containing those bounds
s.add(0);
s.add(currentMax);
do {
s.add(r.nextInt(currentMax));
} while(s.size() <= n);
Integer[] values = new Integer[n + 1];
/*
* Convert to array, sort the results, and find successive
* differences. By construction, those differences WILL sum
* to the currentMax, which IS divisible by the number of
* values generated by differencing!
*/
s.toArray(values);
Arrays.sort(values);
int[] results = new int[n];
for(int i = 0; i < n; ++i) {
results[i] = values[i+1] - values[i];
}
return results;
}

Sum and average of values in an array

I want to ask how to add the values and find average of values in an array. I have tried searching multiple times, but I could find something that explains how to do all that in simple code that a new programmer such as myself could understand. If someone could tell me how to do it and explain the codes used, that will be great. Thanks in advance :>
I leave the normal answers for others to do. For java people,Here we go!
public static void main(String[] args) {
int myarr[]={1,2,3,4,4,5,6,5,7,8,4};
IntSummaryStatistics statisticalData=Arrays.stream(myarr).summaryStatistics();
System.out.println("Average is " + statisticalData.getAverage());
System.out.println("Sum is " + statisticalData.getSum());
}
Other data like count,minimum element,maximum element can also be obtained from the IntSummaryStatistics object
public static void main(String args[]) {
Scanner s = new Scanner(System.in); //Define Scanner class object which will aid in taking user input from standard input stream.
int a[] = new int[10]; //Define an array
int i,sum = 0;
for(i = 0; i < 10; i++) {
a[i] = s.nextInt(); //Take the arrays elements as input from the user
}
for(i = 0; i < 10; i++) { //Iterate over the array using for loop. Array starts at index 0 and goes till index array_size - 1
sum = sum + a[i]; //add the current value in variable sum with the element at ith position in array. Store the result in sum itself.
}
double avg = (double) sum / 10; //Compute the average using the formula for average and store the result in a variable of type double (to retain numbers after decimal point). The RHS of the result is type casted to double to avoid precision errors
System.out.print(sum + " " + avg); //print the result
}
At first you have to take an array of numbers. Iterate all the numbers in the array and add the numbers to a variable. Thus after iteration you will get the sum of the numbers. Now divide the sum by count of numbers (which means the size of array). Thus you will get the average.
int[] numbers = {10, 20, 15, 56, 22};
double average;
int sum = 0;
for (int number : numbers) {
sum += number;
}
average = sum / (1.0 * numbers.length);
System.out.println("Average = " + average);
You can also iterate in this way:
for (int i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
void sumAndAverage(int a[]){
if(a!=null&&a.length>0{
int sum=0;
//traverse array and add it to sum variable
for(int i=0;i<a.length;i++){
sum=sum+a[i];
}
double avg=(1.0*sum)/a.length;
System.out.println("sum= "+sum);
System.out.println("average= "+avg);
}
}

find all possible sums of a list without target

im trying to find all possible sums from a list.
The list consist of ints that are user inputed, and the number of inputs are decided by the user aswell( see code).
What i want is to check all possible sums without having a target.
The reason i dont want a target is because the program is then later suposed to chose one of these sums which is closest to 1000.
So if i was to pick 1000 as target i wouldnt be able to get say 1001.
Example input from user:
5 // user chose 5 numbers.
500,400,300,50,60 // numbers chosen by user.
Output would then be:
1010 // because 500+400+60+50= 1010 and closest to 1000.
Next example could be:
3 // user chose 3 numbers.
1,2,3 // numbers chosen by user.
Output would then be:
6 // because 1+2+3 = 6.
So back to my original question, how do is this done? Everytime i search "all possible sums of a list of ints" or simular i get with a target and it dosent work in this example.
public static void main(String[] args) throws Exception {
int bästaVikt;
int räknare = 0;
Scanner sc = new Scanner(System.in);
ArrayList<Integer> mylist = new ArrayList<Integer>();
int s;
s = sc.nextInt();
int ans = 0;
for(int i = 1; i <= s; i++) {
mylist.add(sc.nextInt());
}
for(int i = 0; i < mylist.size(); i++) {
Collections.sort(mylist);
System.out.print(mylist.get(i));
System.out.print(" ");
}
}
Half actual code half pseudo code, hope it helps.
input // the array that holds all numbers than the user input
int n = input.length();
ArrayList<Integer> combinations = new ArrayList<Integer>();
int totalSum = input.sum(); // sum of all the values the user input
ArrayList<Integer> allSums = new ArrayList<Ingeter>();
for(int i = 0; i < n; i++){
combinations = combine(i) // find all possible combinations of i integers in the input array; you can surely find code for retrieving combinations in another thread
foreach combination in combinations{
allSums.add(totalSum - combination.sum())
}
combinations = new ArrayList<Integer>(); // clear the combinations arraylist
}
return allSums; //all possible sums
minDistanceToNumber = absolute(allSums.get(0) - 1000); // define a function "int absolute(int value)" which will multiply value by -1 if it is less than 0 and return it or just return it if it is bigger than 0
minNumber = allSums.get(0); // this will hold the number which has the minimum distance to 1000, as in the example above
for each sum in allSums
if(absolute(sum - 1000) < minDistanceToNumber){
minDistanceToNumber = absolute(sum - 1000);
minNumber = sum;
}
}
return minNumber;

How to generate 6 different random numbers in java

I want to generate 6 different random numbers by using Math.random and store them into an array.
How can I make sure that they are different? I know I need to use for-loop to check the array but how...
This is the range. I only need numbers between 1 and 49.
( 1 + (int) (Math.random() * 49) )
In Java 8:
final int[] ints = new Random().ints(1, 50).distinct().limit(6).toArray();
In Java 7:
public static void main(final String[] args) throws Exception {
final Random random = new Random();
final Set<Integer> intSet = new HashSet<>();
while (intSet.size() < 6) {
intSet.add(random.nextInt(49) + 1);
}
final int[] ints = new int[intSet.size()];
final Iterator<Integer> iter = intSet.iterator();
for (int i = 0; iter.hasNext(); ++i) {
ints[i] = iter.next();
}
System.out.println(Arrays.toString(ints));
}
Just a little messier. Not helped by the fact that it's pretty tedious to unbox the Set<Integer> into an int[].
It should be noted that this solution should be fine of the number of required values is significantly smaller than the range. As 1..49 is quite a lot larger than 6 you're fine. Otherwise performance rapidly degrades.
Create a list containing the numbers 1 to 49.
Create a random number x between 0 and the size of the list, take the number being at index x in the list, and remove it from the list.
Repeat the previous step 5 times. And you're done. Note that java.util.Random has a nextInt(int max) method that you should use instead of Math.random().
Note regarding performance: this solution has an advantage compared to the "try until you get 6 different numbers" various solutions: it runs in a O(n) time. It doesn't matter much for 6 unique numbers out of 50, but if you want to get 48 or 49 unique random numbers out of 50, you'll start seeing a difference, because you might have to generate many random numbers before getting one that isn't already in the set.
EDIT:
to reduce the cost induced by the removal of the elements in the list, you could instead simply replace the element at index x with the last element of the list (and at the second iteration, with the element at size - 2, etc.)
You can use a Set.
Set<Integer> s = new HashSet<>();
while(s.size() != 6){
s.add(1 + (int) (Math.random() * 49));
}
Integer[] arr = s.toArray(new Integer[s.size()]);
This is enough to do this in your case because the number of distinct random numbers is relatively small compared to the size of the range you generate them.
Otherwise I would go with #JBNizet approach.
Generate any 6 numbers (not necessarily different). Order them.
a1 <= a2 <= a3 <= a4 <= a5 <= a6
Now take these 6 numbers
a1 < a2 + 1 < a3 + 2 < a4 + 3 < a5 + 4 < a6 + 5
These 6 are different and random.
The idea of this construct comes from some combinatorial proofs.
Its advantage is that it's simple, fast, and deterministic.
I think the time complexity is O(count*log(count)).
I wonder if it can be improved.
import java.util.TreeMap;
public class Test005 {
public static void main(String[] args) {
int count = 6;
int min = 1;
int max = 49;
// random number mapped to the count of its occurrences
TreeMap<Integer, Integer> mp = new TreeMap<Integer, Integer>();
for (int i=0; i<count; i++){
int d = ( min + (int) (Math.random() * (max-count+1)) );
if (!mp.containsKey(d)){
mp.put(d, 0);
}
mp.put(d, mp.get(d) + 1);
}
// now ensure the output numbers are different
int j = 0;
for (int num : mp.keySet()){
int cnt = mp.get(num);
for (int i=0; i<cnt; i++){
System.out.println(num + j);
j++;
}
}
}
}
I've just came up with a small idea for Java 8-.
Set<Integer> set = new LinkedHashSet<>();
while(set.size() != 6)
set.add(rnd.nextInt(49) + 1);
Instead of checking that the array has no duplicates, you can use a bit more smartness while generating the numbers, such that uniqueness is enforced at the outset.
Create a boolean[] as long as your range (49 entries);
generate a random number from the full range;
put that number into your output array;
"cross out" the corresponding index in the boolean[];
now generate another random number, but curtail the range by one (now 48);
instead of directly using that number as output, scan your boolean[], counting all the non-crossed entries. Stop when you reach the count equal to the random number generated in step 5. The number corresponding to that entry is your output number;
go to step 4.
in your case n=6
public static int[] chooseAny(int n){
int[] lottery = new int[n];
int[] chooseFrom = new int[49];
for(int i=1 ; i <= 49 ; i++)
chooseFrom[i-1] = i;
Random rand = new Random();
int N = 49;
int index;
for(int i=0 ; i < n ; i++){
//pick random index
index = rand.nextInt(N);
lottery[i] = chooseFrom[index];
chooseFrom[index] = chooseFrom[N-1];
N--;
}
return lottery;
}
Just keep generating numbers and adding them to the array as long as they are unique; psuedocode:
num = genNextRand()
For (array length)
If (num not in array)
addToArray()
Repeat while length not equal 6
Create a variable last; initialize it to 0.
Next, in a loop x from 0 to 5, create a random number between last+1 and 49-6+x. Store this number in a list, and set last to the number generated this way.
You will end up with an ordered list of 6 random numbers in the range of 1..49 with no repeats.
That code generate numbers from 6 to 0 and save in ArrayList.
If generated number was duplicated the program generate numbers again.
If generated number is different that number is added.
Code:
private ArrayList<Integer> arraylist = new ArrayList<Integer>();
private Random rand = new Random();
public void insertNumber() {
while (true) {
int i = generateNumber();
if(!isGenerateNumberExists(i)){
addNumber(i);
break;
}
}
}
//Generate numbers
private int generateNumber() {
return rand.nextInt(6);
}
//Confirm if that number exists
private boolean isGenerateNumberExists(int y) {
for (int num : arraylist) {
if (num == y) {
return true;
}
}
return false;
}
//Add number to arrayList
private void addNumber(int x) {
arraylist.add(x);
}

Categories