0

I have to write a program for my Intro to CS class as a project. The program must

  1. ask the user for a min value (can be negative)
  2. ask the user for a max value (also may be negative, must be greater than min though)
  3. produce twenty random numbers that are in between the min/max values given by the user and
  4. produce an average of the twenty random numbers produced.

I thought I had completed the program but the numbers are never random when I execute the program, all twenty numbers come out to be the same value as the max value I enter into emacs. And of course the average is the same as the max value in this case as well. This is my program so far...

import java.util.Scanner;
import java.util.Random;

public class CS_ProjectOne
{
    public static void main(String[] args)
    {
    int minimum_integer;
    int maximum_integer;
    int rn1;
    int rn2;
    int rn3;
    int rn4;
    int rn5;
    int rn6;
    int rn7;
    int rn8;
    int rn9;
    int rn10;
    int rn11;
    int rn12;
    int rn13;
    int rn14;
    int rn15;
    int rn16;
    int rn17;
    int rn18;
    int rn19;
    int rn20;
    double total;
    double average;
    Scanner keeper;
    Scanner keeper2;
    Random gen;
    gen = new Random();

    keeper = new Scanner(System.in);
    System.out.print("Please enter an integer for the MINIMUM value: ");
    minimum_integer = keeper.nextInt();

    keeper2 = new Scanner(System.in);
    System.out.print("Please enter an integer for the MAXIMUM value: ");
    maximum_integer = keeper2.nextInt();

    rn1 = gen.nextInt();
    rn1 = rn1 % minimum_integer + maximum_integer;
    rn2 = gen.nextInt();
    rn2 = rn2 % minimum_integer + maximum_integer;
    rn3 = gen.nextInt();
    rn3 = rn3 % minimum_integer + maximum_integer;
    rn4 = gen.nextInt();
    rn4 = rn4 % minimum_integer + maximum_integer;
    rn5 = gen.nextInt();
    rn5 = rn5 % minimum_integer + maximum_integer;
    rn6 = gen.nextInt();
    rn6 = rn6 % minimum_integer + maximum_integer;
    rn7 = gen.nextInt();
    rn7 = rn7 % minimum_integer + maximum_integer;
    rn8 = gen.nextInt();
    rn8 = rn8 % minimum_integer + maximum_integer;
    rn9 = gen.nextInt();
    rn9 = rn9 % minimum_integer + maximum_integer;
    rn10 = gen.nextInt();
    rn10 = rn10 % minimum_integer + maximum_integer;
    rn11 = gen.nextInt();
    rn11 = rn11 % minimum_integer + maximum_integer;
    rn12 = gen.nextInt();
    rn12 = rn12 % minimum_integer + maximum_integer;
    rn13 = gen.nextInt();
    rn13 = rn13 % minimum_integer + maximum_integer;
    rn14 = gen.nextInt();
    rn14 = rn14 % minimum_integer + maximum_integer;
    rn15 = gen.nextInt();
    rn15 = rn15 % minimum_integer + maximum_integer;
    rn16 = gen.nextInt();
    rn16 = rn16 % minimum_integer + maximum_integer;
    rn17 = gen.nextInt();
    rn17 = rn17 % minimum_integer + maximum_integer;
    rn18 = gen.nextInt();
    rn18 = rn18 % minimum_integer + maximum_integer;
    rn19 = gen.nextInt();
    rn19 = rn19 % minimum_integer + maximum_integer;
    rn20 = gen.nextInt();
    rn20 = rn20 % minimum_integer + maximum_integer;

    System.out.println("Your random numbers are: " + rn1 + ", " + rn2 + ", " + rn3 + ", " + rn4 + ", " + rn5 + ", " + rn6 + ", " + rn7 + ", " + rn8 + ", " + rn9 + ", " + rn10 + ", " + rn11 + ", " + rn12 + ", " + rn13 + ", " + rn14 + ", " + rn15 + ", " + rn16 + ", " + rn17 + ", " + rn18 + ", " + rn19 + ", " + rn20 + ".");

    total = rn1 + rn2 + rn3 + rn4 + rn5 + rn6 + rn7 + rn8 + rn9 + rn10 + rn11 + rn12 + rn13 + rn14 + rn15 + rn16 + rn17 + rn18 + rn19 + rn20;
    average = total / 20;

    System.out.print("The average is " + average);
    }
}

Could anyone be of some help and steer me in the right direction? I'm sure there is something I'm not doing correctly (or many things) I just don't know what exactly that is.

Here is a shorter version of me trying to get this to work...

import java.util.Random;
import java.util.Scanner;

public class p1
{
    public static void main(String[] args)
    {
    Random gen;
    gen = new Random();
    Scanner keeper;
    int range, user_min, user_max, num1, num2, num3, total;
    double average;

    keeper = new Scanner(System.in);
    System.out.print("Please enter a maximum integer value: ");
        user_max = keeper.nextInt();

        keeper = new Scanner(System.in);
    System.out.print("Please enter a minimum integer value: ");
    user_min = keeper.nextInt();

    range = user_max - user_min + 1;

    num1 = gen.nextInt() % range + user_min;
    num2 = gen.nextInt() % range + user_min;
    num3 = gen.nextInt() % range + user_min;

    System.out.print("The random numbers computed are " + num1 + ", " + num2 + ", " + num3 + ", ");
    }
}

Why can't this handle negatives? And my values still aren't within the specified range? HELP?

Tim
  • 11
  • 4

4 Answers4

2

Some tips/hints:

  1. Use an array for the 20 numbers. Then when you find a mistake, you only have to correct it once rather than 20 times.

  2. Random number generators have seeds. Make sure that you provide a different seed each time, otherwise your random number generator will always generate the same set of random numbers.

  3. How many values can there be between MIN and MAX? For example, how many different values can there be between 3 and 7? 45 and 80? 3 and 1200? Find the pattern.

  4. Understand why your program needs the '%' operator. What is being achieved by doing "gen.nextInt() % NUM"?

wookie919
  • 3,054
  • 24
  • 32
  • I see what you're saying with #3, it'd be max - min. I just don't understand how to make this work in my code. Also we haven't went over arrays so I'm not exactly sure how to do that. I tried doing gen.nextInt() % range + min; to get my code to work where range = max - min + 1; but that didn't work either. – Tim Oct 20 '13 at 23:53
  • I also don't know what you mean by #2? Do you mean I have to have a gen1, gen2, gen3,...etc.? – Tim Oct 20 '13 at 23:55
  • @Tim gen.nextInt() % range + min, where range = max - min + 1 is EXACTLY what you needed. Well done getting to this point. When you say "that didn't work either", what exactly didn't work with this? As for #2, you could take a look at: http://stackoverflow.com/questions/12458383/java-random-numbers-using-a-seed – wookie919 Oct 21 '13 at 00:12
  • Thank you! And what I mean is when I enter a max and min value in the terminal after executing the program, such as 5 and 3 I get values below 3 such as 1 and 2. And when I enter a max of 6 and min of 1 I get all 6s like before. – Tim Oct 21 '13 at 03:23
  • This is what part of my code looks like presently: keeper = new Scanner(System.in); System.out.print("Please enter a maximum integer value: "); user_max = keeper.nextInt(); keeper = new Scanner(System.in); System.out.print("Please enter a minimum integer value: "); user_min = keeper.nextInt(); range = user_max - user_min + 1; num1 = gen.nextInt() % user_min + range; num2 = gen.nextInt() % user_min + range; num3 = gen.nextInt() % user_min + range; System.out.print("The random numbers computed are " + num1 + " ," + num2 + " ," + num3 + " ,"); } } – Tim Oct 21 '13 at 03:26
  • (gen.nextInt() % range) + user_min is what you need. You currently have (gen.nextInt() % user_min) + range. – wookie919 Oct 21 '13 at 08:39
  • I changed that and I still get numbers that are negative or below the minimum. It can't handle negative values either. Would you be able to help me out some more? – Tim Oct 22 '13 at 20:15
  • Sorry, I was assuming that we were dealing with positive numbers. I am not a Java programmer, but I just looked up the documentation. The following will work for you "num1 = gen.nextInt(range) + user_min". – wookie919 Oct 22 '13 at 22:15
1

Random List Example:
(In Python instead of Java for ease of demonstration.)

1   #!/usr/bin/env python
2   def spawn(user_min, user_max, rounds):
3     import random 
4     sum = 0
5     user_range = user_max - user_min + 1  
6     for i in range(rounds):
7       result = int((random.random() * user_range)) + user_min
8       sum = sum + result
9       print(str(i) + ': ' + str(result))
10     mean = sum / rounds
11    print('range: ' + str(user_range))
12    print('mean: ' + str(mean))

The lines of interest for you are:

  • Line 5: This determines the spread of the random number.
  • Line 7: This fetches a random value of range [0.0, 1.0); multiplies by the desired user range; then casts to integer to 'chop off' the trailing decimal points; and then adds the result to the minimum allowed value of the range.

For example:

range = (10) - (-5) + 1 = 16
a_result = (int)(0.14159265359 * 16) + -5 = 3 - 5 = -3
another_result = (int)(0.71828182845 * 16) + -5 = 11 - 5 = 6
LateralFractal
  • 331
  • 2
  • 11
  • Your code would never output userMaxInt. Try it with userMinInt = 0 and userMaxInt = 1 to get only zeroes. (This is assuming the (int) computes the floor of a positive real. If it rounds the integer then all values are possible, but not equally likely. For example, if userMinInt = 0 and userMaxInt = 2 then you get 1 with probability 1/2.) – Yuval Filmus Oct 18 '13 at 21:52
  • @YuvalFilmus Doh. You are correct. This is why I prefer posting code snippets in python. The range equation was off by one. I'll update the post. – LateralFractal Oct 18 '13 at 23:43
  • So what I should be doing is taking the maximum_integer and subtracting the minimum_integer? I assume that I would then make a new line for the random value to be computed within the the range defined? – Tim Oct 20 '13 at 23:09
  • It would something like... range = maximum_integer - minimum_integer + 1; and then a line of code adding the range to the minimum_integer? I'm not exactly sure how I'd go about this. – Tim Oct 20 '13 at 23:16
  • @Tim In order to be general purpose, most programming languages have a function that provides a random number of [interval](http://en.wikipedia.org/wiki/Interval_%28mathematics%29) `[0, 1)` at an arbitrary precision. This way, an application can fetch the number and multiply by the desired range to get a random number of the desired range. Since `[0, 1) * range` provides only positive values and will start from 0, you need add the `user_min` to "shift" the range into place. – LateralFractal Oct 21 '13 at 00:01
  • Incidentally - [backticks](http://en.wikipedia.org/wiki/Backtick) can be used in comments induce `` formatting markup. – LateralFractal Oct 21 '13 at 00:03
0

The line

rn1 = rn1 % minimum_integer + maximum_integer;

is wrong. Consider for example generating numbers in the range 1 to 6. Then you are calculating

rn1 = rn1 % 1 + 6;

Now, rn1 % 1 is always equal to 0, so you always get 6. You should use a different formula.

Yuval Filmus
  • 413
  • 4
  • 14
  • I'm still at a loss. How do I make it so that for whatever number the user enters for the max and min values, the random numbers will be computed between those values stated by the user? I see what you're saying, but the user isn't always going to enter 1 and 6 for the values. – Tim Oct 18 '13 at 03:32
  • Your formula already doesn't work in the case min = 1, max = 6. You should find a different formula that does work. You can start with a formula that works in the case min = 1 and max = 6, then try to generalize it. – Yuval Filmus Oct 18 '13 at 04:04
  • *[T]he user isn't always going to enter 1 and 6* - your program should work for *all* values of *min* and *max*. In particular, it should work for the values 1 and 6. Already in that case, it fails. In order for it to work in general, it should first work in this particular case. You're right that getting it to work in this particular case isn't enough, but it's a prerequisite to getting it to work in general. – Yuval Filmus Oct 18 '13 at 04:06
  • I see that it doesn't work for any numbers. I'm at a complete loss of what to do to make it work...? – Tim Oct 18 '13 at 04:11
  • I realize from looking intently at my notes that I had one (repeating) part of my code in reverse. The part: rn1 = rn1 % minimum_integer + maximum_integer; should read: rn1 = rn1 % maximum_integer + minimum_integer; correct? So then rn1 = rn1 % 1 + 6; would now read rn1 = rn1 % 6 + 1; – Tim Oct 18 '13 at 04:30
  • That would work for 1 and 6, but wouldn't work in general (when *min* is different from 1), though you're getting closer. The expression rn1 % 6 has value in the range 0,1,2,3,4,5, and when you add 1 you get a value in the range 1,2,3,4,5,6. More generally, rn1 % maximum_integer would be in the range 0,...,maximum_integer–1, and after adding minimum integer, we would get something in the range minimum_integer,...,maximum_integer-1+minimum_integer, which is not exactly what we want. – Yuval Filmus Oct 18 '13 at 05:19
  • So are you suggesting that I put the line for maximum_integer in its own line of code and minimum_integer in its own line of code as well? I'm a total newbie so I'm at a complete loss for what to do. – Tim Oct 18 '13 at 20:16
  • The number of lines of code is irrelevant. I'm just saying that your updated formula is still wrong. It only works when min is 1. This is not a programming issue, it's an elementary math issue. – Yuval Filmus Oct 18 '13 at 21:49
  • The line is correct, but now you've started guessing. You should understand *why* it's correct. What I was claiming is that in general, `m1 = m1 % maximum_integer + minimum_integer` wouldn't work. – Yuval Filmus Oct 21 '13 at 01:04
0

Thats what I came up with..

import java.util.*;
class RandNegToPos {
    public static void main(String[] args) 
    {

            Scanner scan = new Scanner(System.in);
            int array[]=new int[20];
            System.out.println("What is the minimum? ");
            int min = scan.nextInt();

            System.out.println("What is the maximum? ");
            int max = scan.nextInt();

            if (max < min)
                System.out.println("Sorry the maximum is less than the miniumum.");

            else{

            int rnd = (int) (min + Math.random() * ((max) - min));   
            for (int i=0; i < 20 ; i++)
            {
                rnd = (int) (min + Math.random() * ((max) - min));
                array[i] = rnd;
            }
            int sum=0;
            for (int t : array)
                sum += t;
            System.out.println("Your randoms are:");
            System.out.println(Arrays.toString(array));
            System.out.println("The average is: " + (sum/20) );
            }
   }

}
0x2bad
  • 308
  • 2
  • 11