Counting 100 Random Numbers - java

I am trying to generate 100 random numbers between 0 and 9, and display the count for each number
Is this solution correct? I want to improve, what could I have done better?
java.util.Scanner k = new Scanner(System.in);
int[] numbers = new int[100];
for (int i = 0;i<numbers.length;i++)
{
numbers[i] = (int) (Math.random() * 10);
}
int [] counts = new int[10];
for (int i = 0;i<numbers.length;i++)
{
counts[numbers[i]%numbers.length]++;
}
for (int i=0;i<counts.length;i++)
{
if (counts[i]>1)
System.out.println(i+1+" Generates: "+(counts[i])+" times");
else
System.out.println(i+1+" Generated: "+(counts[i])+" time");
}

I think you have overthought this, you only need one array - of 10 values (for the range 0 - 9 there are ten unique values), generate one hundred values in that range, and increment the value in the array (that is your count of numbers), then loop to display. Something like,
int[] numbers = new int[10];
for (int i = 0; i < 100; i++) {
int ndx = (int) (Math.random() * numbers.length);
numbers[ndx]++;
}
for (int i = 0; i < numbers.length; i++) {
System.out.printf("%d was generated %d times.%n", i, numbers[i]);
}
And in Java 8+ you might write the above with IntStream and lambda(s) like
int[] numbers = new int[10];
IntStream.range(0, 100).forEach( //
x -> numbers[(int) (Math.random() * numbers.length)]++);
IntStream.range(0, numbers.length) //
.forEachOrdered(x -> System.out.printf( //
"%d was generated %d times.%n", x, numbers[x]));

Related

Generating random numbers array in Java

I'm working on a code that should generate an array with a length of 100 and then separates numbers form the array to:
Numbers that are multiples of 4.
Numbers that are not multiples of 4.
Below is my code, however, I'm getting a weird output (lots of zeros). How can I identify the problem?
public class Assignment8 {
public static void main(String[] args) {
// Defined array to hold the values
int[] randomValueArray = new int[100];
int[] mod4ValueArray = new int[100];
int[] nonMod4ValueArray = new int[100];
// Initiate the randomValue Array
for (int i = 0; i < 100; ++i) {
// Generate a random number from the range 1 to 100
int randomValue = (int) (Math.random() * 100 + 1);
randomValueArray[i] = randomValue;
}
// Pass the array to the class method to separate mod4
// value and non mod4 value from the randomized array
mod4ValueArray = isMod4(randomValueArray);
nonMod4ValueArray = isNonMod4(randomValueArray);
// Print out the two result arrays
System.out.println("Randomly generated numbers that are multiples of four: ");
for (int i = 0; i < mod4ValueArray.length; ++i) {
System.out.println(mod4ValueArray[i]);
}
System.out.println("Randomly generated numbers that are not multiples of four: ");
for (int i = 0; i < nonMod4ValueArray.length; ++i) {
System.out.println(nonMod4ValueArray[i]);
}
}
// Mod4 Checker Method
public static int[] isMod4(int[] array) {
int[] resultArray = new int[array.length];
for (int i = 0; i < array.length; ++i) {
int itemValue = array[i];
if ((array[i] % 4) == 0) {
resultArray[i] = itemValue;
}
}
return resultArray;
}
// Non Mod 4 Checker Method
public static int[] isNonMod4(int[] array) {
int[] resultArray = new int[array.length];
for (int i = 0; i < array.length; ++i) {
int itemValue = array[i];
if ((itemValue % 4) != 0) {
resultArray[i] = itemValue;
}
}
return resultArray;
}
}
Try this.
int[] randomValueArray = new Random().ints(100, 1, 101).toArray();
int[] mod4ValueArray = IntStream.of(randomValueArray).filter(i -> i % 4 == 0).toArray();
int[] nonMod4ValueArray = IntStream.of(randomValueArray).filter(i -> i % 4 != 0).toArray();
try this:
new Random().ints(100, 1, 100).filter(n -> n % 4 == 0).toArray();
new Random().ints(100, 1, 100).filter(n -> n % 4 != 0).toArray();
Java 8 Stream-esque solution:
Map<Boolean, int[]> map = new Random().ints(10, 1, 100)
.mapToObj(i -> i)
.collect(partitioningBy(i -> i % 4 == 0, collectingAndThen(toList(), list -> list.stream()
.mapToInt(i -> i)
.toArray()
)));
This pulls 100 random integers from 1 to 100, then boxes all ints to Integers, then partitions by whether the number is dividable by 4. Then, the resulting List<Integer> is converted to an int[].
However, I think a plain old for loop is better. The only difficulty you have, is that you don't know how large each array will get. So at the end, you'll need to resize the arrays.
int[] fourMods = new int[100];
int[] nonFourMods = new int[100];
int fourModsCardinality = 0;
int nonFourModsCardinality = 0;
Random random = new Random();
for (int i = 0; i < 100; i++) {
int num = random.nextInt(100) + 1;
if (num % 4 == 0) {
fourMods[fourModsCardinality] = num;
fourModsCardinality++;
}
else {
nonFourMods[fourModsCardinality] = num;
nonFourModsCardinality++;
}
}

How to randomly fill in 10% 2 dimensional array with int = 1?

I have little problem , im starting learn java .
I need to create 2dimensional array , and i need fill this array in 10% only int 1 of course my code need fill this array randomly .
Need some hints how to fill in 10% .
public static void main(String[] args) {
int maxX = 10;
int maxY = 10;
int[][] Arr = new int[maxX][maxY];
Random r = new Random();
// random ints
for (int x = 0; x < maxX; x++) {
for (int y = 0; y < maxY; y++) {
Arr[x][y] = r.nextInt(2);
}
}
// printing Arr
for (int i = 0; i < Arr.length; i++) {
for (int j = 0; j < Arr[i].length; j++) {
System.out.print(Arr[i][j] + " ");
}
System.out.println();
}
}
Make the array, take a random row and column, while the percentage is not exceeded, check if the position has 0, if yes fill it with 1.
int[][] array = new int[N][N];
int percentage = N*N/10;
int filled = 0;
while(filled <= percentage)
{
Random rand = new Random();
int i = rand.nextInt(N+1);
int j = rand.nextInt(N+1);
if(array[i][j] == 0)
{
filled++;
array[i][j] = 1;
}
}
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
System.out.print(array[i][j] + " ");
}
System.out.println();
}
You can take the following steps:
Suppose you need to fill an N * N array.
Create a List and add to it (N * N) / 10 1s and (N * N * 9) / 10 0s. list.addAll(Collections.nCopies(count,1 or 0)) can help you here.
Run Collections.shuffle on that List to obtain random order.
Iterate over the elements of the List. The first N elements will become the first row the the 2D array, the next N elements will become the second row of the array, and so on...
An alternative to shuffling is to pick 10% x N random positions and put a 1 (if a 0 was in the position, otherwise pick another position). In pseudo code:
int[][] array = new int[N][N]
apply N * N / 10 times {
index = random(0 .. N * N)
if array(index) = 0 then array(index) = 1
else retry with another index
}
You will need to convert the index from 0 to N*N into a pair of i,j in the 2D array.
I would use "double random = Math.random();"
And then an if to check if the variable random is less or equal to 0.1

How to sort array in to 'bins', and print out stars for how many numbers are in that bin?

//so basically for all that is below, I'm trying to sort the random numbers that have been generated, and then 'sort' then into bins, and then for how many numbers there are in the bin, a star * will print out for every number. it will look like a histogram at the end. like this:
12 random integers in [0, 10) sorted into 2 bins:
******* 7 0.5833333 [5.0, 10.0)
***** 5 0.41666666 [0.0, 5.0)
but its like its skips that last two methods - generateBins, and printBins. how would i sort the random numbers into bins depending on the number (like above) and print a * for every number in that array bin?
public class BinSort {
final int totalBins;
final int totalRandom;
final float widthBin;
int [] storeNumbers;
int [] binCount;
public BinSort (int nBins, int nSamples, int max) {
totalBins = nBins; //total # of bins, ie 2
totalRandom = nSamples; //total random number generated, ie 12
widthBin = (float) (max/totalBins); ie 2
int [] storeNumbers = new int [max];
for (int i = 0; i < totalRandom-1; i++) {
storeNumbers[i] = Random.rand(i, max);
System.out.println(storeNumbers[i]);
}
}
void generateBins () {
int [] binCount = new int [totalBins];
for (int i=0; i < totalRandom-1; i++) {
int bin = (int)(storeNumbers[i]/ totalBins);
Math.floor(bin);
bin = binCount [i];
}
}
void printBins () {
for (int i = 0; i < binCount.length - 1; i++) {
for (int j=0; j < binCount[j]; j ++) {
System.out.print("*");
System.out.println(); }
float freq = (binCount[i]/totalRandom);
float binMin = (i * widthBin);
float binMax = (binMin * widthBin);
System.out.print(binCount[i] + freq + binMin + binMax);
System.out.println();
}
}
}
In your constructor you have
int [] storeNumbers = new int [max];
The problem here is that this will create a new local variable with the same name as your instance variable, storeNumbers. Also, the size should be totalRandom, not max. You need to create a Random object that you'll use to generate random numbers. Putting this together we get:
public BinSort (int nBins, int nSamples, int max) {
totalBins = nBins; //total # of bins, ie 2
totalRandom = nSamples; //total random number generated, ie 12
widthBin = (float) (max/totalBins); //ie 2
storeNumbers = new int [totalRandom];
Random rand = new Random();
for (int i = 0; i < totalRandom; i++) {
storeNumbers[i] = rand.nextInt(max);
}
}
This will generate totalRandom random numbers between 0 and max(exclusive) and store them the instance variable storeNumbers.
Next, in generateBins you have the same issue with
int [] binCount = new int [totalBins];
Which again will hide your instance variable binCount. The bin that a storeNumber falls into will be given by (int)(storeNumbers[i] / widthBin), and you need to increment the resulting bin by 1.
void generateBins()
{
binCount = new int[totalBins];
for (int i = 0; i < totalRandom; i++)
{
int bin = (int)(storeNumbers[i] / widthBin);
binCount[bin] += 1;
}
}
Finally, to the printing of the bins. This line
for (int j=0; j < binCount[j]; j ++)
should be
for (int j=0; j < binCount[i]; j ++)
Also, you should use printf to format the numbers you want to print.
void printBins()
{
for (int i = 0; i < binCount.length; i++)
{
for (int j = 0; j < binCount[i]; j++)
{
System.out.print("*");
}
float freq = (float)binCount[i] / totalRandom;
float binMin = i * widthBin;
float binMax = (i+1) * widthBin;
System.out.printf(" %d %.3f %.3f %.3f\n", binCount[i], freq, binMin, binMax);
}
}
Test:
public static void main(String[] args)
{
BinSort bs = new BinSort(2, 12, 10);
bs.generateBins();
bs.printBins();
}
Output:
***** 5 0.417 0.000 5.000
******* 7 0.583 5.000 10.000
Which I think is what you were looking for.
Be sure to compare your original code with the changes above and make sure you understand what the issues were and why the changes work.

How do I effectively generate Perfect digit-to-digit invariant numbers in Java?

A PDDI is a number such the the sum of all the digits raised to themselves is equal to the number itself.
For example, 3435 = (3^3) + (4^4) + (3^3) + (5^5)
The code below takes too long to check for PDDIs between one to a huge number. Is there any way to make it faster?
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0;
// We're going to try all integers between one to n.
for(int i = 1; i<=n; i++){
sum = 0;
m = i;
while(m>0){
k = m % 10;
sum = sum + (int)Math.pow(k, k);
m = m/10;
}
if(i == sum)
System.out.println(i);
}
The number from 0 to 9 to the power of 2 can be precalculated and kept in a an array.
int powered [] = new int [10];
powered[0] = 0;
powered[1] = 1;
powered[2] = 4;
..
powered[9] = 81;
Then for each digit fech the powered number using the digit as an index to the powered array.
For example 234 would be powered[2] + powered[3] + powered[4]
This will save some math operations.
Also you could think of a multithreaded approach having N threads doing the calculations for different numbers in parallel.
Use cached values instead of Math.pow
Since you are using only power from 0 to 9, you could cache these values in a int[] instead of computing Math.pow(k, k) everytime. It won't improve that much but, it's a start.
int[] pows = new int[] {0, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489 };
for (int i = 0; i < 10; ++i) {
pows[i] = (int) Math.pow(i, i);
}
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0;
// We're going to try all integers between one to n.
for(int i = 1, i<=n, i++){
sum = 0;
m = i;
while(m>0){
k = m % 10;
sum = sum + pows[k]; // use cached values here
m = m/10;
}
if(i == sum)
System.out.println(i);
}
Skip useless values
Based on logic you may skip some iterations.
Lets take the number 281 as an example, which gives 4 + 16777216 + 1 = 16777251, the result is above 281, so theres no changes that 282, 283, 284, ... 289 gives a number equals to 281.
In such cases you may want to skip these useless iterations by manually incrementing i.
int[] pows = new int [10];
for (int i = 0; i < 10; ++i) {
pows[i] = (int) Math.pow(i, i);
}
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0, lastNumberDigit;
// We're going to try all integers between one to n.
for(int i = 1, i<=n, i++){
sum = 0;
m = i;
while(m>0){
lastNumberDigit = m; // on the last iteration, we'll get the last digit
k = m % 10;
sum = sum + pows[k]; // use cached values here
m = m/10;
}
if(i == sum) {
System.out.println(i);
} else if (sum > i) {
i += (10 - lastNumberDigit - 1); // jump to the next decade (-1 because the for will apply i++ on it)
}
}
I used this logic on decade, but you may want to extend it to hundreds or even more, but it will be much more tricky.

how to add random number to an array

This is classwork. I've been reading and searching and everything is telling me to use the java.util.Random of which I understand how that works and wish I could use it. but my assignment specifically tells me to use the (int) (Math.random * number) of which I am having difficulty seeing where to apply into my array. everything I've seen has been the Random pulled from java.
It is the generate 100 random integers 0-9 and how many times they occur. If someone can assist?
My error is - Exception in "main" java.lang.array index out of bounds exemption:10 and obviously there is something in my code wrong too.
public class NumberOfTimes{
public static void main(String[] args){
int rand = (int)(Math.random() * 10);
int[] counts = new int [10];
for(int i = 0; i < 100; i++){
counts[i]++;
}//end for
System.out.println("number\t" + "occurence ");
for (int num = 0; num < counts.length; num++){
System.out.println(num + "\t" + counts[num]);
}//end for
}//end main
}//end NumberOfTimes
make this change
int[] counts = new int[100];
for (int i = 0; i < counts.length; i++) {
counts[i] = (int) (Math.random() * 10);
}// end for
Your array can only hold 10 items, and on your loop you are accessing more than 10. Can be solved in two ways.
Either Increase your array length
int[] counts = new int [100];
Or either decrease your count in for loop.
for(int i = 0; i < 10; i++){

Categories