generate random number with restrictions - java

I'm new to programming in general so I'm trying to be as specific as possible in this question.
There's this book that I'm doing some exercises on. I managed to do more than half of what they say, but it's just one input that I have been struggling to find out.
I'll write the question and thereafter my code,
"Write an application that creates and prints a random phone number of the form XXX-XXX-XXXX. Include the dashes in the output. Do not let the first three digits contain an 8 or 9 (but don't be more restrictive than that), and make sure that the second set of three digits is not greater than 742. Hint: Think through the easiest way to construct the phone number. Each digit does not have to be determined separately."
OK, the highlighted sentence is what I'm looking at.
Here's my code:
import java.util.Random;
public class PP33 {
public static void main (String[] args) {
Random rand = new Random();
int num1, num2, num3;
num1 = rand.nextInt (900) + 100;
num2 = rand.nextInt (643) + 100;
num3 = rand.nextInt (9000) + 1000;
System.out.println(num1+"-"+num2+"-"+num3);
}
}
How am I suppose to do this? I'm on chapter 3 so we have not yet discussed if statements etcetera, but Aliases, String class, Packages, Import declaration, Random Class, Math Class, Formatting output (decimal- & numberFormat), Printf, Enumeration & Wrapper classes + autoboxing. So consider answer the question based only on these assumptions, please.
The code doesn't have any errors.
Thank you!

Seeing as this appears to be homework I feel like an explanation of what is happening should be given.
You have three sets of numbers you need to generate.
The first number has the most requirements. It has to be greater than 100 but not contain an 8 or 9.
You ensure it will always be greater than 100 by using:
(rand.nextInt(7)+1) * 100.
This says, generate a random number between 0 and 6. Add 1 to that number to ensure that it can never be 0. So if it picks 0, +1 is added making it 1. If it picks 6, +1 is added making it 7, etc. This satisfies rule #1 and rule #2.
You ensure the first number never has an 8 or 9.
(rand.nextInt(8) * 10) + rand.nextInt(8)
Genreate a random number from 0-7. The *10 makes sure it will be in the tenth position while the last one places the number in the last position.
Instead of trying to fix the other answer as it also uses DecimalFormat incorrectly.
package stackoverflow_4574713;
import java.text.DecimalFormat;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random rand = new Random();
int num1 = (rand.nextInt(7) + 1) * 100 + (rand.nextInt(8) * 10) + rand.nextInt(8);
int num2 = rand.nextInt(743);
int num3 = rand.nextInt(10000);
DecimalFormat df3 = new DecimalFormat("000"); // 3 zeros
DecimalFormat df4 = new DecimalFormat("0000"); // 4 zeros
String phoneNumber = df3.format(num1) + "-" + df3.format(num2) + "-" + df4.format(num3);
System.out.println(phoneNumber);
}
}
Output:
662-492-1168

For the first three digits, you need to generate each digit separately. See variables i1, i2, and i3 below.
For the three digits, any number between 0 and 741 should work.
For the final set of four digits, any number between 0 and 9999 should work.
The trick here is how you format the output. You could do it with a NumberFormat object, but I chose to do it with the String.format() method. In it, you specify how you want each number to be formatted. So, I used the format string "%d%d%d-%03d-%04d". The %d inserts a base-10 formatted integer into the string. The %03d makes sure that it is three characters wide and that any additional space is left-padded with a 0. In other words, 4 is formatted as "004" and 27 is formatted as "027". The %04d works similarly, except it is four characters wide.
Here's how you put it all together.
Random r = new Random();
int i1 = r.nextInt(8); // returns random number between 0 and 7
int i2 = r.nextInt(8);
int i3 = r.nextInt(8);
int i4 = r.nextInt(742); // returns random number between 0 and 741
int i5 = r.nextInt(10000); // returns random number between 0 and 9999
String phoneNumber = String.format("%d%d%d-%03d-%04d", i1, i2, i3, i4, i5);
System.out.println(phoneNumber);`

Hmm, just a really simple idea to change this to
num1 = rand.nextInt(8)*100 + rand.nextInt(8)*10 + rand.nextInt(8);
num2 = rand.nextInt(743);
For easier output you may use DecimalFormat
DecimalFormat df3 = new DecimalFormat ( "000" ); // 3 zeros
DecimalFormat df4 = new DecimalFormat ( "0000" ); // 4 zeros
System.out.println(df3.format(num1)+"-"+df3.format(num2)+"-"+df4.format(num3));

I had this same question as the first assignment for my Java class, with the caveat that we could only use the methods that we have learned in class up to that point. Therefore, we could not use the .format method. Here is what I came up with:
import java.util.Random;
/**
*
* #author
*/
public class Randnum {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Random num = new Random();
int num0, num1, num2, num3, num4, num5, num6, num7;
num0 = num.nextInt(7) + 1;
num1 = num.nextInt(8);
num2 = num.nextInt(8);
num3 = num.nextInt(643) + 101;
num4 = num.nextInt(10);
num5 = num.nextInt(10);
num6 = num.nextInt(10);
num7 = num.nextInt(10);
String randnum= "A random phone number: ";
System.out.print (randnum);
System.out.print (num0);
System.out.print (num1);
System.out.print (num2);
System.out.print ("-" + num3 + "-");
System.out.print (num4);
System.out.print (num5);
System.out.print (num6);
System.out.println (num7);
}
}

You might also want to check that the prefix is not 555

var num1 = Math.floor(Math.random()*7) + 1;
var num2 = Math.floor(Math.random()*8);
var num3 = Math.floor(Math.random()*8);
var part2 = Math.floor(Math.random()*742);
if(part2 < 100){
part2 = "0" + part2;
}else if (part2 < 10) {
part2= "00" + part2;
}else{
part2 = part2;
}
var part3 = Math.floor(Math.random()*10000);
if(part3 < 1000){
part3 = "0" + part3;
}else if (part3 < 100) {
part3 = "00"+ part3;
}else if(part3 < 10){
part3 = "000" + part3;
}else{
part3 = part3;
}
document.getElementById("demo").innerHTML= " " + num1 + num2 + num3 + "-" + part2 + "-" + part3;

public String GetRandomPhone(){
return String.format("(%03d) %03d-%04d",
(int) Math.floor(999*Math.random()),
(int) Math.floor(999*Math.random()),
(int) Math.floor(9999*Math.random()));
}

Related

Calculating sum of odd numbers between two user inputs

I am trying to calculate the sum of the odd numbers between two user inputted numbers.
This is the code I have so far:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("#1: ");
int num1 = s.nextInt();
System.out.print("#2: ");
int num2 = s.nextInt();
int sum = 0;
for (int i = num1; i <= num2; i += 2) {
sum = sum + i;
}
System.out.print(sum);
}
}
When I input 3 and 11, it outputs 35, which is correct.
However, with 4 and 20, it outputs 108, which is not correct. It should instead be 96.
Where have I gone wrong in the code?
You need to check if the first number is even or odd first, because if it is even, it is going to sum the even numbers instead of odd ones since you are increasing "i" by 2 after every iteration. Try adding the line below before the for loop.
if(num1%2==0){num1++);
Explanation
Your loop sums the even numbers if you start with an even number.
Check your code:
for (int i = num1; i <= num2; i += 2)
Assume num1 is even, e.g. 4. Then your loop starts with i = 4. And then you continue with += 2, so you end up with 6, 8, 10, ..., i.e. the even numbers.
Solution
You can simply fix it by patching num1 before your loop.
// Put this before your loop
if (num1 % 2 == 0) { // checks if num1 is even
num1++;
}
This way you will start with 5 then, and then get 7, 9, 11, ....
To sum a range of numbers:
Take the average of the first number and the last number, and multiply by the number of numbers.
But, first you need to make sure you lower and upper bounds are odd numbers. This is actually what is the problem with the code in the question.
Once that is done, calculate the average number, and the number of numbers:
public static long sumOddNumbers(int min, int max) {
long minOdd = (min % 2 == 1 ? min : min + 1); // Round up to odd number
long maxOdd = (max % 2 == 1 ? max : max - 1); // Round down to odd number
if (minOdd > maxOdd)
return 0;
// average = (minOdd + maxOdd) / 2
// count = (maxOdd - minOdd) / 2 + 1
// sum = count * average
return ((maxOdd - minOdd) / 2 + 1) * (minOdd + maxOdd) / 2;
}
Test
System.out.println(sumOddNumbers(3, 11)); // prints: 35
System.out.println(sumOddNumbers(4, 20)); // prints: 96
This can be done easily with a mathematical formula. But based on your question I presume you want to use a loop so here goes.
An odd number has the low order bit set to 1.
If the number is already odd, resetting that bit has no effect so it is still odd.
But setting that bit for an even number makes it the next higher odd number.
So use the bitwise OR operator.
3 | 1 = 3
4 | 1 = 5
And do the following:
int start = 4;
int end = 20;
int sum = 0;
for (int i = (start | 1); i <= end; i += 2) {
sum += i;
}
System.out.println(sum);
If you want to use streams in Java 8+ you can do it this way.
int sum = IntStream.rangeClosed(start, end).filter(i -> i & 1 == 1).sum();
And the formula I was talking about is the following, derived using simple series summation.
For ints, start and end
start |= 1; // ensure start is next odd number
end = (end | 1) - 2;// ensure end is last odd - 2
int sum = ((start + end) * ((end - start) / 2 + 1)) / 2;
If the two numbers are natural numbers, you can apply the formula:
Sum of odd natural numbers from m to n = sum of natural odd numbers up to n - sum of natural odd numbers up to m
= (n/2)^2 - (m/2)^2
where n is an even number or the next even number in case it is an odd number
In the program:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("#1: ");
int num1 = Math.abs(s.nextInt());
System.out.print("#2: ");
int num2 = Math.abs(s.nextInt());
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
num1 = 5;
num2 = 15;
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
num1 = 5;
num2 = 16;
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
num1 = 6;
num2 = 15;
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
}
static int sumNaturalOddOfRange(int num1, int num2) {
if(num2%2==1)
num2++;
return (int)(Math.pow(num2 / 2, 2) - Math.pow(num1 / 2, 2));
}
}
A sample run:
#1: 10
#2: 20
Sum of natural odd numbers from 10 to 20 = 75
Sum of natural odd numbers from 5 to 15 = 60
Sum of natural odd numbers from 5 to 16 = 60
Sum of natural odd numbers from 6 to 15 = 55
**Here is the answer**
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("#1: ");
int num1 = s.nextInt();
System.out.print("#2: ");
int num2 = s.nextInt();
int sum = 0;
if (num1%2==0) {
num1++;
}
for (int i = num1; i <= num2; i++) {
sum +=i;
}
System.out.print(sum);
}

subtraction operation with 2 random numbers

I am trying to create a simple math game for my son. I have the addition operation working perfect. My problem is with subtraction. I am using the same code as my addition operation, problem is sometimes the 2nd number is larger than the 1st number resulting in a negative number. I need help correcting the order of the random numbers so the 1st number is greater than or equal to the 2nd number. Please help.
Scanner input = new Scanner(System.in);
int answer;
public static void main(String[] args) {
// TODO code application logic here
int SIDES = 6;
int a = 1 + (int) (Math.random() * SIDES);
int b = 1 + (int) (Math.random() * SIDES);
System.out.println("What is " + a + " - " + b + " = ");
int difference = a - b;
Scanner one = new Scanner (System.in);
System.out.println("What is the answer?");
int answer = Integer.parseInt(one.next());
//int answer = one.next();
System.out.println("your answer is " + answer);
if (answer==difference) {
System.out.println("You are correct!");
System.out.println("You gain 5 points");
}
else{
System.out.println("You are wrong.");
System.out.println("The correct answer is " + difference);
System.out.println("You lose 5 points");
}
Just use an inequality operator to compare their values, than subtract from the larger one:
int difference = a > b ? a - b : b - a;
// ^ Inequality operator
If the ? operator is confusing you, you can alternatively write it like this:
int difference;
if(a > b) difference = a - b;
else difference = b - a;
You can read more about operators such as ?, >, &&, ||, etc. on the Equality, Relational, and Conditional Operators page.
There are many ways, but in order not to mess up your code, an easy fix would be checking the 2 generated random numbers before assigning them to a and b:
int r1 = (int) Math.random()*SIDES;
int r2 = (int) Math.random()*SIDES;
int a = Math.max(r1, r2);
int b = Math.min(r1, r2);
This way, a will always be greater or equals to b.
You can make sure that your b never becomes bigger than a by adjusting your random number generation logic:
int b = 1 + (int) (Math.random() * a);
That's probably better than swapping the numbers, because swapping will skew a to the high end (close to SIDES) which may not be what you want.
Since you are only subtracting two numbers you can simply use if(a >= b) then a - b else b - a to control the order.
If there are more numbers in the question you can always put all the random numbers into an array and sort them before generating the question.

Display 2 floats rounded up to 2 decimal places without losing which one is bigger

I get two numbers num1 and num2 from a network service that can be represented by a double and have an unknown number of decimal places (I mean could be 3, 4 or 5 etc).
These numbers represent a percentage so could be something like 0.34567 which is 34.567%
I need to display them with 2 decimal places (or no decimal places instead of e.g. 34.00%) if num1 is greater than num2.
I tried the following:
String num1 = "0.3547";
String num2 = "0.354";
int fixed = 2;
int diff = Math.abs(num1.length() - num2.length());
double tmp = 0.0d;
double d1 = Double.valueOf(num1);
double d2 = Double.valueOf(num2);
tmp = (d1 > d2)? d1 : d2;
while(diff > 0) {
StringBuilder sb = new StringBuilder("%.");
sb.append(String.valueOf(fixed + diff)).append("f");
String formatter = sb.toString();
System.out.println(formatter);
String round = String.format(formatter, tmp);
tmp = Double.parseDouble(round);
--diff;
}
String final1 = String.format("%.2f", tmp);
String final2 = String.format("%.2f", (d1 < d2)? d1 : d2);
System.out.println(final1 + " vs " + final2);
The output is:
0.36 vs 0.35
How sane is this approach and the result? May be I am thinking this wrong?
For ceation of two decimal places just do:
num = (Maht.round(num * 10_000))
num /= 10_000
If you just divide by 100 instead of 10_000 you get directly percent.
and for removing zeros just convert the number to a String with
String.valueOf(num)
and search for the regex pattern
"\\.0"
and act accordingly by removing it if it is found.
Complet solution (a bit diffrent, because I had some trouble with regex):
//Rounding on to two decimalplaces and writing to a String
numX = (Math.round(numX * 10_000));
String numXStr = String.valueOf(numX /= 100);
//Removing of ".0" endings
if (numXStr .endsWith(".0")) {
numXStr = numXStr .substring(0, numXStr .length() - 2);
}
numXStr += "%"; //Adding the percent char at the end
System.out.println(numXStr) //outputting

Java - Recursion Program - way to convert an inputted base to base 10 on a given number

I am given a non-recursive method, that I need to modify to make recursive.
This is what I have so far:
public class BaseN {
public static final int BASEN_ERRNO = -1;
public static void main(String[] argv) {
Scanner input = new Scanner(System.in);
System.out.print("enter number followed by base (e.g. 237 8): ");
int number = input.nextInt();
int base = input.nextInt();
BigInteger answer = basen(number, base);
System.out.println(number + " base-" + base + " = " + answer);
}
static BigInteger basen(int number, int base ) {
List<Integer> remainder = new ArrayList<>();
int count = 0;
String result = "";
while( number != 0 ) {
remainder.add( count, number % base != 0 ? number % base : 0 );
number /= base;
try {
result += remainder.get( count );
} catch( NumberFormatException e ) {
e.printStackTrace();
}
}
return new BigInteger( new StringBuffer( result ).reverse().toString() );
}
}
It's converting it to base 10 then the given base. I need it to convert to the given base first then base 10.
UPDATE:
I changed around Caetano's code a bit and think I am closer.
static String basen(int number, int base) {
String result = String.valueOf(number % base);
int resultC;
String resultD;
int newNumber = number / base;
if (newNumber != 0)
result += basen(newNumber, base);
if (newNumber == 0)
resultC = Integer.parseInt(result);
resultD = Integer.toString(resultC);
return resultD;
Now when I compile it it gives me an error it says:
BaseN.java:49: error: variable resultC might not have been initialized
resultD = Integer.toString(resultC);
Am I on the right track here? Any help is appreciated
Its hard to tell what you are asking for.
I can only assume that you want to convert from a given base to base 10. The way that you would do this is explained in this page here: MathBits introduction to base 10.
The way explained in this is simple. For each digit in the number you get the base to the power of the position of the digit(reversed) and multiply that by whatever the digit is. Then add all the results. So 237 in base 8 would be
(8^2 * 2) + (8^1 * 3) + (8^0 * 7) = 159
Now you will run in to a problem when you do this with bases higher then 10 since the general notation for digits above 9 is alphabetical letters. However you could get around this by having a list of values such as [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F] and compare the digits with this list and get the index of the location of that digit as the number.
I hope this is what you were asking for.
Now then this is code that does what you want it to do. Get a number in a given base and convert it to base 10. However I don't see why you need to use a recursive method for this. If this is some kind of school task or project then please tell us the details because I don't personally see a reason to use recursion. However the fact that your question asks us to modify the code up top to make it recursive then it makes much more sense. Since that code can be edited to be as such.
public static final int BASEN_ERRNO = -1;
public static void main(String[] argv) {
Scanner input = new Scanner(System.in);
System.out.print("enter number followed by base (e.g. 237 8): ");
String number = input.next();
int base = input.nextInt();
int answer = basen(number, base);
System.out.println(number + " base-" + base + " = " + answer);
}
private static int basen(String number, int base ) {
int result = 0;
for(int i = 0; i < number.length(); i++) {
int num = Integer.parseInt(number.substring(i, i + 1));
result += Math.pow(base, number.length() - i - 1) * num;
}
return result;
}
However what I think that you want is actually this which shows recursion but instead of converting from base given to base 10 it converts from base 10 to base given. Which is exactly what the code you showed does but uses recursion. Which means '512 6' will output '2212'
public static final int BASEN_ERRNO = -1;
public static void main(String[] argv) {
Scanner input = new Scanner(System.in);
System.out.print("enter number followed by base (e.g. 237 8): ");
int number = input.nextInt();
int base = input.nextInt();
String answer = new StringBuffer(basen(number, base)).reverse().toString();
System.out.println(number + " base-" + base + " = " + answer);
}
static String basen(int number, int base) {
String result = String.valueOf(number % base);
int newNumber = number / base;
if (newNumber != 0)
result += basen(newNumber, base);
return result;
}
I figured out a way to do it recursively. Thank you everyone who provided help. I ended up using Math.pow on the base and put the length of the number -1 for how it would be exponentially increased. Math.pow puts the result in double format so I just converted it back to an int. My professor gave me 100% for this answer, so I'd imagine it would work for others too.
public static int basen(int number, int base) {
String numberStr;
int numberL;
char one;
String remainder;
int oneInt;
int remainderInt;
double power;
int powerInt;
numberStr = Integer.toString(number);
numberL = numberStr.length();
if(numberL > 1){
one = numberStr.charAt(0);
remainder = numberStr.substring(1);
oneInt = Character.getNumericValue(one);
remainderInt = Integer.parseInt(remainder);
power = Math.pow(base, (numberL - 1));
powerInt = (int)power;
return ((oneInt * powerInt) + (basen(remainderInt, base)));
}
else{
return number;
}
}

How to find the base10 of (x:g)?

I am at the end of my homework, and a little confused on the right way to go for this algorithm. I need to find the base10 of a number:base that user gives.
Basically what my program does is take user input such as, 407:8 or 1220:5 etc.
What I am trying to output is like this.
INPUT: 407:8
OUTPUT: 407 base 8 is 263 base 10
I was thinking of this long stretched out way of doing it but I am sure there is a way easier way to go about it.
Attached is what i have so far. Thanks for looking!!
import javax.swing.JOptionPane; //gui stuff
import java.util.Scanner; // Needed for accepting input
import java.text.*; //imports methods for text handling
import java.lang.Math.*; //needed for math stuff*
public class ProjectOneAndreD //my class + program name
{
public static void main(String[] args) //my main
{
String input1; //holds user input
int val=0, rad=0, check1=0; //holds integer values user gives
and check for : handler
double answer1=0; //holds the answer!
Scanner keyboard = new Scanner(System.in);
//creates new scanner class
do //will continue to loop if no : inputted
{
System.out.println("\t****************************************************");
System.out.println("\t Loading Project 1. Enjoy! "); //title
System.out.println("\t****************************************************\n\n");
input1 = JOptionPane.showInputDialog("INPUT: ","EXAMPLE: 160:2"); //prompts user with msgbox w/ example
System.out.println("Program Running..."); //gives user a secondary notice that everything is ok..
check1=input1.indexOf(":"); //checks input1 for the :
if(check1==-1) //if no : do this stuff
{
System.out.println("I think you forgot the ':'."); //let user know they forgot
JOptionPane.showMessageDialog(null, "You forgot the ':'!!!"); //another alert to user
}
else //otherwise is they remembered :
{
String numbers [] = input1.split(":"); //splits the string at :
val = Integer.parseInt(numbers[0]); //parses [0] to int and assigns to val
rad = Integer.parseInt(numbers[1]); //parses [1] to int and assigns to rad
//answer1 = ((Math.log(val))/(Math.log(rad))); //mathematically finds first base then
//answer1 = Integer.parseInt(val, rad, 10);
JOptionPane.showMessageDialog(null, val+" base "+rad+" = BLAH base 10."); //gives user the results
System.out.println("Program Terminated..."); //alerts user of program ending
}
}while(check1==-1); //if user forgot : loop
}
}
You can use Integer.parseInt(s, radix).
answer = Integer.parseInt(numbers[0], rad);
You parse number in given radix.
It's easy, just replace your commented out logic with this:
int total = 0;
for (int i = 0; val > Math.pow(rad, i); i++) {
int digit = (val / (int) Math.pow(10, i)) % 10;
int digitValue = (int) (digit * Math.pow(rad, i));
total += digitValue;
}
and total has your answer. The logic is simple - we do some division and then modulus to pull the digit out of val, then multiply by the appropriate radix power and add to the total.
Or, if you want to make it a little more efficient and lose the exponentials:
int total = 0;
int digitalPower = 1;
int radPower = 1;
while (val > radPower) {
int digit = (val / digitalPower) % 10;
int digitValue = digit * radPower;
total += digitValue;
digitalPower *= 10;
radPower *= rad;
}
You only have implemented the user interface. Define a method taking two integers (the base and the number to convert) as argument, and returning the converted number. This is not very difficult. 407:8 means
(7 * 8^0) + (0 * 8^1) + (4 * 8^2)
You thus have to find a way to extract 7 from 407, then 0, and then 4. The modulo operator can help you here. Or you could treat 407 as a string and extract the characaters one by one and transorm each of them into an int.

Categories