Reputation: 400
I need to create an array of random integers which a sum of them is 1000000 and an average of these numbers is 3. The numbers in the array could be duplicated and the length of the array could be any number.
I am able to find the array of random integers which the sum of them is 1000000.
ArrayList<Integer> array = new ArrayList<Integer>();
int a = 1000000;
Random rn = new Random();
while (a >= 1)
{
int answer = rn.nextInt(a) + 1;
array.add(answer);
a -= answer;
}
However, I don't know how to find the random numbers with average of 3.
Upvotes: 1
Views: 526
Reputation: 425063
If they are constrained to an average and random, they must be constrained to a value range. A range of 1 to 5 (median is 3) seems reasonable. Also reasonable is a smooth distribution, which gives a known total and average.
This simple code will do all that:
List<Integer> numbers = new ArrayList<>(333334); // 1000000 / 3
// one instance of 5 must be omitted to make total exactly 1000000
numbers.addAll(Arrays.asList(1, 2, 3, 4));
for (int i = 0; i < 333330; i++)
numbers.add((i % 5) + 1); // add 1,2,3,4,5,1,2,3,4,5,etc
Collections.shuffle(numbers);
// Check sum is correct
numbers.stream().reduce((a,b) -> a + b).ifPresent(System.out::println);
Output:
1000000
Note that it is mathematically impossible for the average to be exactly 3
when the total is 1000000
(because 1000000/3
has a remainder of 1/3
), however this code gets pretty close:
1000000/333334 => 2.999994
Upvotes: 1
Reputation: 51
there are many answers to this question but lets say we want our random number to be 10 max (which we can change). I guess this would give a satisfactory answer.
import java.util.Random;
import java.util.ArrayList;
public class RandomSumAverage {
public static void main(String[] args) {
Random random = new Random();
ArrayList<Integer> arr = new ArrayList<Integer>();
double sum = 0;
double avg = 0;
int k = 1;
while (sum < 1000000) {
avg = sum / k;
if (avg < 3) {
int element = random.nextInt(10)+1;
sum += element;
arr.add(element);
k++;
} else {
int element = random.nextInt(3)+1;
sum += element;
arr.add(element);
k++;
}
}
System.out.println(arr);
System.out.println(sum);
System.out.println(avg);
}
}
Upvotes: 0
Reputation: 5038
I think that you need to write a simple average function like:
public double average(ArrayList<Integer> array){
long sum = 0;
int count = 0;
for (Integer item : array){
sum += item;
count++;
}
return sum/count;
}
Then use it in your code like:
ArrayList<Integer> array = new ArrayList<Integer>();
int a = 1000000;
Random rn = new Random();
boolean isDone = true;
while (a >= 1)
{
int answer = rn.nextInt(a) + 1;
array.add(answer);
a -= answer;
if (average(array) % 3 != 0){
isDone = false;
break;
}
}
The idea is each time we adding a new number to the array, we checking that the average can be divide with 3, if not, we getting out of the while loop.
To let us know if the algorithm went well, we need to check isDone
variable at the end.
And the more efficient way is:
ArrayList<Integer> array = new ArrayList<Integer>();
int a = 1000000;
Random rn = new Random();
boolean isDone = true;
long sum = 0;
while (a >= 1)
{
int answer = rn.nextInt(a) + 1;
array.add(answer);
a -= answer;
sum += answer;
if ((sum/array.size()) % 3 != 0){
isDone = false;
break;
}
}
Upvotes: 0
Reputation: 822
As Göker Gümüş said it is mathematically impossible to have the average be exactly 3 and the sum be a million.
The average = sum / number of elements. This means that number of elements = sum / average.
In this case it would need 1000000 / 3 = 333333.(3) elements. Since you can't have a third of an element with value 3 it means your average or your sum will need to be slightly off your target for it to match up. The less notable needed difference would definitely be the average as it would only need to be a millionth of a unit off, i.e 3.000001 for you to be able to have 333333 elements summing to 1000000
Upvotes: 0
Reputation: 51
that's mathematically not possible:
you are looking for n values, sum of which makes 1000000, and the average of them is 3, which is 1000000/n. since n can only take integer values it is not possible.
Upvotes: 4
Reputation: 3
I would transverse the list twice, and IF the integers at these two positions added together and divded by 2 == 3 then return, else, increment your integer.
Upvotes: 0