Math.random() not giving unique number; is there any issue in API? - java

Math.random() not working properly. Can you please help me to fix this issue?
public class MethodTest {
static Set<Long>dups=new HashSet<Long>();
public static void main(String[] args) {
while(true){
long value= (long) (Math.random() * 1000000000l);
if(dups.add(value)){
System.out.println(value);
} else{
System.out.println("Dup "+value);
break;
}
}
}
}

Random numbers aren't guaranteed to be distinct.
Think about rolling a dice: you're going to roll the same number twice if you keep rolling it repeatedly. Once you've rolled a 6-sided dice 7 times, it is impossible not to have a duplicate.
Randomness isn't about whether the value is distinct - it is the property that all values could be obtained with equal probability on each roll. If you can't roll numbers you've seen before, this decreases the probability of those numbers occurring again (to zero), whilst increasing the probability of numbers you've not seen before.
The consequence of the non-uniqueness is sometimes called the Birthday paradox - which gives the somewhat surprising result that you only need 23 people in a room before it is more likely than not that 2 people share a birthday.
According to the birthday paradox, one would expect your code to be more likely than not to have found a duplicate by (roughly) sqrt(1_000_000_000) = 10^4.5 ~= 30k iterations.

Math.random() function not guaranteed to unique value.
your program is terminated at duplicate value.
If you want unique value call the random function once again if you found duplicate value.
Some what like this.
public class Main {
static Set<Long> uniqueValues = new HashSet<Long>();
public static void main(String[] args) {
while (true) {
System.out.println("Unique Value is: "+getUniqueValue());
}
}
public static long getUniqueValue() {
boolean isUnique = false;
long value = 0;
while (!isUnique) {
value=(long) (Math.random() * 1000000000l);
isUnique = uniqueValues.add(value);
}
return value;
}
}

You will get duplicates because if you have a limited pool of numbers to choose from you will eventually end up choosing the same number twice.
Lets say you had a hat with the numbers 1 to 10 on separate pieces of paper.
You decide to choose a number. Look at it. Place it back in the hat. Then choose another number....... Keep going and the probability of choosing the same number twice before you have picked all unique numbers gets higher and higher.
You could check the number in the following line of code..
if(dups.add(value)){
System.out.println(value);
} else{
System.out.println("Dup "+value);
continue;
}
This would go to the next iteration of the loop and you would end up filling the HashSet to the brim but... you would also need to check the size of the hash set to make sure you now have all the unique numbers. So lets say you have a range of 0 - 10 then you would need to do something along the lines of...
long max = 10;
if(dups.add(value)){
System.out.println(value);
} else{
System.out.println("Dup "+value);
if (dups.size() == max) {
break;
}
continue;
}
if you want a value between a range then you have to do something along the lines of
int min = 0;
int max = 10;
int randomNum = rand.nextInt((max - min) + 1) + min;
So for your full solution you would need....
public class MethodTest {
static Set<Long>dups=new HashSet<Long>();
public static void main(String[] args) {
long value;
long min = 0;
long max = 10;
while(true) {
value = (long) rand.nextInt((max - min) + 1) + min;
if(dups.add(value)){
System.out.println(value);
} else{
System.out.println("Dup "+value);
break;
}
}
}
}

To generate a unique no first you create a list with all possible no and then suffle it.
then you can read it with iterator or other methoda as you want.

Related

Multiplying digits of a number until you reach a one digit number

Assume, you input the number 546, then you should find the product of its digits, which is 546=120, then multiply the digits of 120 until and so on, continue until you get a one digit number.
Here's the code I wrote, but the loop doesn't work correctly and I've tried to fix it, but nothing changed. Could you please help me?
import java.util.*;
public class Product {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int a = keyboard.nextInt();
System.out.println("Please input the number");
numberOfProducts(a);
}
public static void numberOfProducts(int n){
int product = 1;
while(n>10) {
int current = n;
while (current != 0) {
product = product * (current % 10);
current = current / 10;
n = product;
System.out.println(product);
}
}
}
}
For a different take on the solution you can use a recursive lambda
import java.util.Scanner;
import java.util.function.IntFunction;
public class Product {
// this simply reduces the number to the product of its digits.
static IntFunction<Integer> prod =
(a) -> a < 10 ? a : a % 10 * Product.prod.apply(a / 10);
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Please input the number");
int n = keyboard.nextInt();
// Now continue applying the lambda until the result is < 10.
while (n > 10) {
n = prod.apply(n);
}
System.out.println(n);
}
}
I think you are looking something like the code below:
import java.util.Scanner;
public class Main {
public static int numberOfProducts(String number) {
int product = 1;
do {
for (int i = 0; i < number.length(); ++i){
// This line converts the every digit of the number string to an integer.
product *= number.charAt(i) - '0';
}
// Remove this line, if you don't want to print the product of each iteration.
System.out.println(number);
// Update number with the new product.
// This line converts the int product to a new string.
number = "" + product;
} while (product > 10);
return product;
}
public static void main(String[] args) {
System.out.print("Please input the number: ");
Scanner keyboard = new Scanner(System.in);
int a = keyboard.nextInt();
// Treat number as a string for easier indexing.
String number = "" + a;
System.out.println(numberOfProducts(number));
}
}
When the above code runs, with 546 as input, it outputs:
Please input the number: 546
546
120
0
After looking through your code, your issue seems to be in this expression:
current % 10.
The modulo operation gives you the remainder of a division by ten.
In the case of your input 120, the result of that operation would be 0.
Following the rest of your application logic, your iteration variable will be set to zero, ending your loop immediately.
I will not give you copy-paste code to fix this problem, as it seems like a programming course assignment. I will however help you solve it.
My suggested fix is to change your approach to this problem and not try to solve this the mathematical way, but rather in a way that takes advantage of the Java programing language.
You could change your input from an Integer to a String.
In which case, you can use String.length() to ensure your requirement is fulfilled when exiting the loop.
In your loop, you split the String into substrings of length 1. Afterwards, you just multiply these.
When the loop exits (because String length is no longer greater than 1) you will have your intended result.
Good luck!
Actually your code is very close to being correct, the only thing you're doing wrong is that you are not resetting the product variable between iterations. You simply need to move the int product = 1; instruction inside the outer while loop.
Also, if you want a single digit at the end, your condition should be while(n >= 10) or while(n > 9), since 10 is still 2 digits, so we need one more iteration !
Final remark: sometimes it's easier to break your code into smaller pieces. It is easier to understand and easier to test/debug ! For example you could have first created a function productOfDigits(n) that returns the result of a single iteration, and then another function productOfDigitsUntilSingleDigit(n) that repeatedly calls the previous function.
import java.util.*;
public class Product {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int a = keyboard.nextInt();
System.out.println("Please input the number");
numberOfProducts(a);
}
public static void numberOfProducts(int n){
int product = 1;
while (n != 0) {
product = product * (n % 10);
n = n / 10;
}
if(product > 10) {
System.out.println("Intermediate result="+product);
numberOfProducts(product);
}
else
System.out.println("Final 1 digit product="+product);
}
}
function getProductUntilSingleDigit(n) {
let product = 1;
while (n > 0 || product > 9) {
if (n == 0) {
n = product;
product = 1;
}
product = product * (n % 10);
n = Math.floor(n / 10);
}
return product;
}
console.log(getProductUntilSingleDigit(546));

Unexpected result when trying to calculate Mean and Median

I made a simple program that calculate the Mean and Median value of given array from command-line.
import java.util.Arrays;
public class EdankJaya {
public static void main(String args[]) {
double sum = 0;
double d;
if(args.length < 1) {
System.out.println("Usage : java EdankJaya <Number1> <Number2> ..");
System.exit(1);
}
//Mean
for(String s : args) {
d = Double.parseDouble(s);
sum = sum+d;
}
double mean = sum/args.length;
System.out.println("Mean: " + mean);
//Median
Arrays.sort(args);
int med = args.length/2;
if((args.length % 2) == 0) {
double median1 = Double.parseDouble(args[med-1]);
double median2 = Double.parseDouble(args[med]);
System.out.println("Median :"+(median1+median2)/2);
} else {
double median = Double.parseDouble(args[med]);
System.out.println("Median :"+median);
}
}
}
Technique that i used for Median value is divide args.length by 2 and store it in med. If args.length value is even, it'll be args[med-1] + args[med], no problem for even number. And for odd args.length value, it'll just be args[med], which is works fine on the paper since integer will not produce fraction(11/2 gonna be 5), but here's what happened:
Everything's good until i inputted 1-10, the value turned back to the result when i inputted 1-8, and 1-11 just like 1-7, and so on.
What could be the issue here.
Thanks.
Your array has strings in it, not numbers, so they are not sortting in numerical order. They're probably sorting in ASCII order. Since you're already iterating over the array and converting them to numbers, build a second array with them and sort that one.

Mistake in code.What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Hello I am doing a Euler Project :
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
But I cant't see what is wrong in my code.
Please help.
public long mainNumber()
{
long number=1;
for(int i=2;i<=20;)
{
while(number%i!=0)
{
number++;
}
i++;
}
return number;
}
public static void main(String[] args)
{
Smallest_multiple result =new Smallest_multiple();
System.out.println("The smalest multiple "+result.mainNumber());
}
Try:
public long mainNumber() {
long number = 1;
for (int i = 1; i <= 20; i++) {
if (number % i != 0) {
i = 1; //restart i
number++;
}
}
return number;
}
This will loop from 1 through 20, each time checking if i divides number evenly. If it doesn't then it sets i back to 1 and tries the next number. Of course, there's much more elegant ways of getting to this. But just I'll keep it in the iterative fashion that was presented in the post. Running this results in 232792560 as the final outcome.
Your number is almost always going to be divisible by i, after one increment of number i.e. as you increase number, it becomes divisible by the current value of i, so it will simply stop at 20, as that's the last number you're checking that it's divisible by. It needs to be divisible by ALL of them simultaneously. That's where you've gone wrong here. You simply need to keep incrementing the number and check that it's divisible by all of the numbers from 1 to 20. And once it does, then you've got your desired number. But be careful of variable type limits as you keep incrementing.
It's really not a difficult algorithm. Here's a very simple implementation of it...
public class Test {
public static void main(String[] args) {
long number = 0;
int factors = Integer.parseInt(args[0]);
boolean found = false;
while (!found) {
number++; // OR you could use [number += 2;] instead, as we know it will be even. Performance improvement! :)
found = true;
for (int i = 2; i <= factors; i++) {
found = found && number % i == 0;
}
}
System.out.println("Number: " + number);
}
}
I've written this console app to allow you to enter the number of factors you wish to check. Usage: java Test 20 to get the value you desire of 232792560.
The problem is that your outer loop may get completely exhausted and you still might not find the number that you are looking for.
You should be doing something like this:
private static long gcd(long a, long b)
{
while (b > 0)
{
long temp = b;
b = a % b;
a = temp;
}
return a;
}
public static long mainNumber()
{
long number = 1;
for(int i = 2; i <= 20; i++) {
number = number * (i / gcd(number, i));
}
return number;
}
public static void main(String[] args)
{
Smallest_multiple result =new Smallest_multiple();
System.out.println("The Smallest Multiple: " + result.mainNumber());
}
Output:
The Smallest Multiple: 232792560
Your current algorithm will fail for the large numbers but still if you want to give it a try then you can do something like this:
public long mainNumber()
{
long number = 3;
while(true)
{
boolean flag = true;
for(int i = 2; i <= 10; i++) {
if(number % i != 0) {
flag = false;
break;
}
}
if(flag) break;
else number++;
}
return number;
}
public static void main(String[] args)
{
Smallest_multiple result =new Smallest_multiple();
System.out.println("The Smallest Multiple: " + result.mainNumber());
}
Note that here I'm calculating the result for 10 and not 20. You can modify the condition in the loop as you desire.
Output:
The Smallest Multiple: 2520
Warning: You need to choose the data type carefully as it might overflow for bigger numbers.

Why am I getting an OutOfMemoryError in java?

I am working on a projecteuler problem, and I have run into an OutOfMemoryError.
And I don't understand why because my code was working beautifully (to my novice eyes at least :P).
Everything works just fine until the loop reaches 113383.
If someone could help me debug this it would be greatly appreciated because I don't understand at all why it is failing.
My Code
import java.util.Map;
import java.util.HashMap;
import java.util.Stack;
/*
* The following iterative sequence is defined for the set of positive integers:
n = n/2 (n is even)
n = 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 40 20 10 5 16 8 4 2 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains
10 terms. Although it has not been proved yet (Collatz Problem), it is thought
that all starting numbers finish at 1. Which starting number, under one million,
produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
*/
public class Problem14 {
static Map<Integer, Integer> map = new HashMap<Integer, Integer>();
final static int NUMBER = 1000000;
public static void main(String[] args) {
long start = System.currentTimeMillis();
map.put(1, 1);
for (int loop = 2; loop < NUMBER; loop++) {
compute(loop);
//System.out.println(map);
System.out.println(loop);
}
long end = System.currentTimeMillis();
System.out.println("Time: " + ((end - start) / 1000.) + " seconds" );
}
private static void compute(int currentNumber) {
Stack<Integer> temp = new Stack<Integer>();
/**
* checks to see if current value is already
* part of the map. if it isn't, add to temporary
* stack. also if current value exceeds 1 million,
* don't check map or add to stack.
*/
while (!map.containsKey(currentNumber)){
temp.add(currentNumber);
currentNumber = realCompute(currentNumber);
while (currentNumber > NUMBER){
currentNumber = realCompute(currentNumber);
}
}
System.out.println(temp);
/**
* adds members of the temporary stack to the map
* based on when they were placed in the stack
*/
int initial = map.get(currentNumber) + 1;
int size = temp.size();
for (int loop = 1; loop <= size; loop++){
map.put(temp.pop(), initial);
initial++;
//key is the top of stack
//value is initially 1 greater than the current number that was
//found at the map, then incremented by 1 afterwards;
}
}
private static int realCompute(int currentNumber) {
if (currentNumber % 2 == 0) {
currentNumber /= 2;
} else {
currentNumber = (currentNumber * 3) + 1;
}
return currentNumber;
}
}
Seems to me it's just what the error says: you're running out of memory. Increase the heap size with -Xmx (eg java -Xmx512m).
If you want to reduce the memory footprint, take a look at GNU Trove for a more compact (and faster) implementation of primitive maps (instead of using HashMap<Integer,Integer>).
I have the exactly same problem as you had...
The problem actually lies with the "Stack temp", and change it to Long would be fine.
It is a simple overflow.
Which OutOfMemory error is it? Heap, PermGen..? Probably need to increase heap size or permgen size.
you should define HashMap like: map = new HashMap(NUMBER).
you know, "Entry[] table" is the map data structure,auto capacity.
the reason for inital capacity:1,not array copy. 2,run faster.

Java: do something x percent of the time

I need a few lines of Java code that run a command x percent of the time at random.
psuedocode:
boolean x = true 10% of cases.
if(x){
System.out.println("you got lucky");
}
You just need something like this:
Random rand = new Random();
if (rand.nextInt(10) == 0) {
System.out.println("you got lucky");
}
Here's a full example that measures it:
import java.util.Random;
public class Rand10 {
public static void main(String[] args) {
Random rand = new Random();
int lucky = 0;
for (int i = 0; i < 1000000; i++) {
if (rand.nextInt(10) == 0) {
lucky++;
}
}
System.out.println(lucky); // you'll get a number close to 100000
}
}
If you want something like 34% you could use rand.nextInt(100) < 34.
If by time you mean times that the code is being executed, so that you want something, inside a code block, that is executed 10% of the times the whole block is executed you can just do something like:
Random r = new Random();
...
void yourFunction()
{
float chance = r.nextFloat();
if (chance <= 0.10f)
doSomethingLucky();
}
Of course 0.10f stands for 10% but you can adjust it. Like every PRNG algorithm this works by average usage. You won't get near to 10% unless yourFunction() is called a reasonable amount of times.
To take your code as a base, you could simply do it like that:
if(Math.random() < 0.1){
System.out.println("you got lucky");
}
FYI Math.random() uses a static instance of Random
You can use Random. You may want to seed it, but the default is often sufficient.
Random random = new Random();
int nextInt = random.nextInt(10);
if (nextInt == 0) {
// happens 10% of the time...
}
public static boolean getRandPercent(int percent) {
Random rand = new Random();
return rand.nextInt(100) <= percent;
}
You could try this:
public class MakeItXPercentOfTimes{
public boolean returnBoolean(int x){
if((int)(Math.random()*101) <= x){
return true; //Returns true x percent of times.
}
}
public static void main(String[]pps){
boolean x = returnBoolean(10); //Ten percent of times returns true.
if(x){
System.out.println("You got lucky");
}
}
}
You have to define "time" first, since 10% is a relative measure...
E.g. x is true every 5 seconds.
Or you could use a random number generator that samples uniformly from 1 to 10 and always do something if he samples a "1".
You could always generate a random number (by default it is between 0 and 1 I believe) and check if it is <= .1, again this is not uniformly random....

Categories

Resources