Math.random called from for loop produces continous "random" numbers - java

im pretty new to java stuff. At the moment i am trying to write a programm dealing with the birthday problem(wikipedia). I want to know how many people have to be asked for their day and month of birth until one is duplicate.
I wrote a class doing the "asking" with the following code:
public class Starter {
static ArrayList<Integer> peeps = new ArrayList<Integer>();
static boolean match = false;
static int counter = 0;
public static int doRand() {
int rand = (1 + (int) (Math.random() * ((365 - 1) + 1)));
return rand;
}
public static int start() {
do {
int buffer = 0;
buffer = doRand();
if (peeps.isEmpty()) {
peeps.add(doRand());
}
counter++;
for (int i = 0; i < peeps.size(); i++) {
if (peeps.get(i) == buffer) {
match = true;
}
}
peeps.add(buffer);
} while (match == false);
return counter;
}
}
This seems to work and produces numbers somewhat between 10 and 50.
But if I run this function from the following for-loop, I get really strange result:
public class BirtdayProblem {
public static void main(String[] args) {
for (int i=0;i< 1000;i++) {
System.out.println(Starter.start());
}
}
}
It produces an output of 1000 continous numbers...why?
If I run the function multiple times manually, i have never gotten any continous number...
Can someone explain that to me?
Example Output:
25
26
27
...
...
1016
1017
1018
1019
1020
1021
1022
1023
1024
Does not look ver yRandom to me...?

Starter.start() returns the static "counter" value which is incremented by 1 after every iteration in the for loop , hence the output shows the output in increments of 1 .

You are using static member variables for counter and match. That means they belong to the class and will not be reset between calls to start().
Since these variables are used only inside the start() method I suggest you put their declarations there as well.
public static int start() {
boolean match = false;
int counter = 0;
And remove the old declarations at the top.

Related

Is there a more effecient way to repeatedly delete nodes from signifactly large linkedlist?

I'm trying to make a lottery application that has the feauture to filter out bad/undesired number combinations. The lottery system is based on Norway Lotto 34/7
Here is a sketch of my code concerning the lottery filter:
public static LinkedList<ArrayList<Integer>> lotto_comb = new LinkedList<>();
public static void generateAllComb() {
/* method for generating all possible lottery combinations and
then store it into lotto_comb */
}
//remove single number
public static void nrFilter(int nr) {
Iterator<ArrayList<Integer>> it = lotto_comb.iterator();
while(it.hasNext()) {
ArrayList<Integer> number = it.next();
if(number.contains(nr)) {
it.remove();
}
}
}
//remove the mix of odd and even numbers to occur in a ticket
public static void odd_evenFilter(int oddNr, int evenNr) {
Iterator<ArrayList<Integer>> it = lotto_comb.iterator();
while(it.hasNext()) {
int countOdd = 0, countEven = 0;
ArrayList<Integer> number = it.next();
for (Integer nr : number) {
if(nr % 2 != 0) {
countOdd++;
} else {
countEven++;
}
}
if((countOdd == oddNr && countEven == evenNr)) {
it.remove();
}
}
}
//Show the remaining number of combinations
public static void displayRemainingCombinations() {
System.out.println(lotto_comb.size());
}
The problem that I'm having is that the method "displayRemainingCombinations" is not always returning the actual size of the linkedlist that I'm expecting after some repetitive use of filter-methods to reduce the numbers.
What I sometimes get is a size that is slightly higher than the actual size when calling upon displayRemainingCombinations. For instance, if the theoretical remaing number of combinations is expected to be 1 540 548, then I will usually get a value that is rather 1 or 2 numbers higher than the theoretical one, also 1 540 549 / 1 540 550.
What am I doing wrong?
Thanks in advance
JV

Easy way to generate unique random numbers (range) using threads? Java

I want to generate a list of unique random numbers from a given input range using threads in Java. For example, given a range of 1-4, I would run 4 threads and each thread would generate a random number such that no two threads would produce the same value twice. I presume I need to implement some synchronization or something? I've tried using Join() but it doesn't seem to work.
My constructor uses input values to populate an array list with a given range. In the run method, I generate a random value (from the same range) and check if it's in the list. If it is, I remove it from the list and print the value. The idea is that when another thread comes in, it can't generate that same value again.
Here is what I have so far:
public class Main {
public static void main(String[] args) {
randomThreadGen randomRange = new randomThreadGen(1, 2);
Thread thread1 = new Thread(randomRange);
Thread thread2 = new Thread(randomRange);
thread1.start();
try {
thread1.join();
} catch (InterruptedException e) {
}
thread2.start();
}
}
And this:
public class randomThreadGen implements Runnable {
private int lowerBound;
private int upperBound;
private final ArrayList<Integer> List = new ArrayList<Integer>();
public randomThreadGen(int lowerb, int upperb) {
this.lowerBound = lowerb;
this.upperBound = upperb;
for (int i = lowerb; i < upperb + 1; i++) { // populate list with values based on lower and upperbounds specified from main
List.add(i);
}
}
#Override
public void run() {
// generate random value
// check if in list. If in list, remove it
// print value
// otherwise try again
int val = ThreadLocalRandom.current().nextInt(lowerBound, upperBound+1); // generate random value based on lower and upper bound inputs from main
while(true){
if(List.contains(val)){
List.remove(new Integer(val));
System.out.println("Random value for " + Thread.currentThread().getName() + " " + val);
System.out.println("List values: " + List);
}
break;
}
}
}'''
This test case with a low range is to make testing easy. Sometimes it works, and Thread0 will generate a different value to Thread01 (1 and 2 or 2 and 1 for example). But sometimes it doesn't (seemingly they generate the same value, in which case my code only prints one value) For example, "Thread02 1" and nothing else.
Any ideas? Is there another way to do this other than join()?
It's quite an easy task. Just use a concurrent hashmap to prevent duplicates. Make sure to declare boundary int and the hashmap as final. Thread.join is needed to guarantee that the results will be printed after all threads have complete their work. There are other effective techniques to replace join but they are not for novices.
Try this:
import java.util.concurrent.ThreadLocalRandom;
import java.util.*;
import java.util.concurrent.*;
public class Main {
final static int low = 0;
final static int up = 5;
final static Set < Integer > inthashmap = ConcurrentHashMap.newKeySet();
// threadhashmap is needed to track down all threads generating ints
final static Set < Thread > threadhashmap = ConcurrentHashMap.newKeySet();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < up - low + 1; i++) {
Thread t = new Thread() {
public void run() {
int randomNum;
try {
randomNum = ThreadLocalRandom.current().nextInt(low, up + 1);
inthashmap.add(randomNum);
System.out.println("A new random int generated : " + randomNum);
} finally {
}
}
};
threadhashmap.add(t);
t.start();
}
//by iterating through all threads in threadhashmap
// and joining them we guarantee that all threads were completed
// before we print the results of work of those threads (i.e. ints)
Iterator<Thread> iterator = threadhashmap.iterator();
while (iterator.hasNext())
iterator.next().join();
System.out.println("Unique ints from hashmap:");
inthashmap.forEach(System.out::println);
}
}
Output:
A new random int generated : 2
A new random int generated : 3
A new random int generated : 3
A new random int generated : 0
A new random int generated : 0
A new random int generated : 2
Unique ints from hashmap:
0
2
3

Java Program does not give the output for values of n>6, Why?

import java.util.*;
class A{
static int count=0;
static String s;
public static void main(String z[]){
int n;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
System.out.println(noOfBouncy(n));
}
public static int noOfBouncy(int k){
int limit=(int)Math.pow(10,k);
s=new String("1");
int num=Integer.parseInt(s);
while(num<limit){
if(isIncreasing(s) || isDecreasing(s) ){
}
else{
count++;
}
num++;
s=new String(Integer.toString(Integer.parseInt(s)+1));
}
count=limit-count;
return count;
}
}
public static boolean isIncreasing(String s){
int len=s.length();
for(int i=0;i<len-1;i++){
if(s.charAt(i)>s.charAt(i+1)){
return false;
}
}
return true;
}
public static boolean isDecreasing(String s){
int len=s.length();
for(int i=0;i<len-1;i++){
if(s.charAt(i)<s.charAt(i+1)){
return false;
}
}
return true;
}
I have given the definitions to the two functions used isIncreasing() & isDecresing()
The program runs well for the value of n<7 but does not respond for values above it, Why ?
I accept the programming style is very immature,please ignore.
I've tried to execute it with n=7 and it finishes in 810ms, returning 30817.
However, I recommend to you to optimize the performance of your program by saving unnecessary object instantiation: It will be better if you maintain the counter in num, and convert it to string just once, at the beginning of the loop:
int num=1;
while (num < limit)
{
s=Integer.toString(num);
if (isIncreasing(s) || isDecreasing(s))
{
}
else
{
count++;
}
num++;
}
Like this it takes just 450ms to finish.
The program was not actually stuck but it is taking way too much time to complete its execution when value of 'n' is larger.
So now the question is, I need to optimize the code to take minimum time #Little have an optimization bit that's not enough.
Any hint would be appreciable.
To increase the performance you should avoid the conversation to String and do the check with numbers.
As it doesn't matter for the result if you start the comparison from left to right or from right to left one computational solution could be.
as pseudo code
1) compare the value of the right most digit with the digit on it's left
2) is it lower --> we found a decreasing pair
3) else check if it is bigger --> we found an increasing pair
4) else --> not a bouncy pair
5) if we found already one decreasing and one increasing pair it's bouncy number
6) divide the number by ten if it's bigger then ten repeat with step 1)
The method to check if it's a bouncy number could look like this
static boolean isBouncyNumber(int number) {
boolean increasingNumber = false;
boolean decreasingNumber = false;
int previousUnitPosition = number % 10;
int remainder = number / 10;
while (remainder > 0) {
// step 1
int currentUnitPosition = remainder % 10;
if (currentUnitPosition > previousUnitPosition) {
// step 2
decreasingNumber = true;
} else if (currentUnitPosition < previousUnitPosition) {
// step 3
increasingNumber = true;
}
// step 5
if (decreasingNumber && increasingNumber) {
return true;
}
// step 6
previousUnitPosition = currentUnitPosition;
remainder = remainder / 10;
}
return decreasingNumber && increasingNumber;
}

Return function in void method when using Recursion

I am currently learning the basics of Java from a book and I've got this code as an example of Nested Loops using Recursion. I understand everything, but the usage of return function in the end of the code. I cannot figure out how the program decide, when to stop exactly when K=4. I've tried to debug it and this continued to be like a mystery for me. Here is the code :
import java.util.Scanner;
public class nestedLoops {
public static int numberOfLoops;
public static int numberOfIterations;
public static int[] loops;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("N = ");
numberOfLoops = input.nextInt();
System.out.print("K = ");
numberOfIterations = input.nextInt();
input.close();
loops = new int[numberOfLoops];
nestedLoops(0);
}
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
public static void printLoops() {
for (int i = 0; i < numberOfLoops; i++) {
System.out.printf("%d ", loops[i]);
}
System.out.println();
}
}
It would be very helpful if someone explain me how return works in this particular example in the end when numbers are "4.4" and also how it works at all in a void method, because I've been searching for explanation of that but did not succeed...
Thank you beforehand !
A return statement in a void method stops running the method and returns back to the calling code. In this example with the input:
numberOfLoops = 4
numberOfIterations = 4
Right after taking the input, you create an array based off of the input and then call the nestedLoops(0) method:
public static void nestedLoops(int currentLoop) {
if (currentLoop == numberOfLoops) {
printLoops();
return;
}
for (int counter=1;counter<=numberOfIterations;counter++) {
loops[currentLoop] = counter;
nestedLoops(currentLoop + 1);
}
}
The explanation
For starts, let's just ignore the for loop. The if statement checks to see if currentLoop == numberOfLoops and it does this every time this method is called. Right now currentLoop is 0 (the value we passed into this method when we called it) and numberOfLoops is 4 (the value we entered at the very beginning) so this is false and none of the code inside is called.
The for loop below the if statement is going to run numberOfIterations times. In our case, this loop is going to run 4 times. I will write out what happens below in sequential order:
- input is 4, 4
- nestedLoops(0) called- currentLoop = 0
- if evaluates to false
- for loop runs
- loops[0] = 1
- nestedLoops(1)
- if evaluates to false ( 1 != 4)
- for loop runs
- loops[1] = 1
- nestedLoops(2)
- if evaluates to false (2 != 4)
- for loop runs
- loops[2] = 1
- nestedLoops(3)
- if evaluates to false (3 != 4)
- for loop runs
- loops[3] = 1
- nestedLoops(4)
- if evaluates to TRUE (4 == 4)
- loops are printed (all values are 1 right now)
-returns to calling location
-Which is the for loop associated with this indention.
-For loop increments, and then sets loops[3] = 2.
- then this loop finishes
- then this loop finishes
etc. etc.
The return in a void method just means "okay, stop what you're doing and go back to who/whatever called this and move on" In this case its jumping back to previous for loop to keep working.
The for loop inside the nestedLoops method is calling itself numberOfIterations times. So it goes 0, then makes numberOfIterations calls. So if you entered 4 you would see 4 calls with currentLoop=1 then 16 calls with currentLoop=2 and so on....
When all else fails write some code to debug your code. I am a visual person myself so making some output helps when the debugger doing it for me.
public static HashMap<Integer, Integer> map = new HashMap();
public static void main(String[] args) {
....
System.out.println(map);
}
public static void nestedLoops(int currentLoop) {
if(map.containsKey(currentLoop)) {
map.put(currentLoop, map.get(currentLoop)+1);
} else {
map.put(currentLoop, 1);
}
...
}

Encoding codes in Java

Over the past couple of weeks I've read through the book Error Control Coding: Fundamentals and Applications in order to learn about BCH (Bose, Chaudhuri, Hocquenghem) Codes for an junior programming role at a telecoms company.
This book mostly covers the mathematics and theory behind the subject, but I'm struggling to implement some of the concepts; primarily getting the next n codewords.I have a GUI (implemented through NetBeans, so I won't post the code as the file is huge) that passes a code in order to get the next n numbers:
Generating these numbers is where I am having problems. If I could go through all of these within just the encoding method instead of looping through using the GUI my life would be ten times easier.
This has been driving me crazy for days now as it is easy enough to generate 0000000000 from the input, but I am lost as to where to go from there with my code. What do I then do to generate the next working number?
Any help with generating the above code would be appreciated.
(big edit...) Playing with the code a bit more this seems to work:
import java.util.ArrayList;
import java.util.List;
public class Main
{
public static void main(final String[] argv)
{
final int startValue;
final int iterations;
final List<String> list;
startValue = Integer.parseInt(argv[0]);
iterations = Integer.parseInt(argv[1]);
list = encodeAll(startValue, iterations);
System.out.println(list);
}
private static List<String> encodeAll(final int startValue, final int iterations)
{
final List<String> allEncodings;
allEncodings = new ArrayList<String>();
for(int i = 0; i < iterations; i++)
{
try
{
final int value;
final String str;
final String encoding;
value = i + startValue;
str = String.format("%06d", value);
encoding = encoding(str);
allEncodings.add(encoding);
}
catch(final BadNumberException ex)
{
// do nothing
}
}
return allEncodings;
}
public static String encoding(String str)
throws BadNumberException
{
final int[] digit;
final StringBuilder s;
digit = new int[10];
for(int i = 0; i < 6; i++)
{
digit[i] = Integer.parseInt(String.valueOf(str.charAt(i)));
}
digit[6] = ((4*digit[0])+(10*digit[1])+(9*digit[2])+(2*digit[3])+(digit[4])+(7*digit[5])) % 11;
digit[7] = ((7*digit[0])+(8*digit[1])+(7*digit[2])+(digit[3])+(9*digit[4])+(6*digit[5])) % 11;
digit[8] = ((9*digit[0])+(digit[1])+(7*digit[2])+(8*digit[3])+(7*digit[4])+(7*digit[5])) % 11;
digit[9] = ((digit[0])+(2*digit[1])+(9*digit[2])+(10*digit[3])+(4*digit[4])+(digit[5])) % 11;
// Insert Parity Checking method (Vandermonde Matrix)
s = new StringBuilder();
for(int i = 0; i < 9; i++)
{
s.append(Integer.toString(digit[i]));
}
if(digit[6] == 10 || digit[7] == 10 || digit[8] == 10 || digit[9] == 10)
{
throw new BadNumberException(str);
}
return (s.toString());
}
}
class BadNumberException
extends Exception
{
public BadNumberException(final String str)
{
super(str + " cannot be encoded");
}
}
I prefer throwing the exception rather than returning a special string. In this case I ignore the exception which normally I would say is bad practice, but for this case I think it is what you want.
Hard to tell, if I got your problem, but after reading your question several times, maybe that's what you're looking for:
public List<String> encodeAll() {
List<String> allEncodings = new ArrayList<String>();
for (int i = 0; i < 1000000 ; i++) {
String encoding = encoding(Integer.toString(i));
allEncodings.add(encoding);
}
return allEncodings;
}
There's one flaw in the solution, the toOctalString results are not 0-padded. If that's what you want, I suggest using String.format("<something>", i) in the encoding call.
Update
To use it in your current call, replace a call to encoding(String str) with call to this method. You'll receive an ordered List with all encodings.
I aasumed, you were only interested in octal values - my mistake, now I think you just forgot the encoding for value 000009 in you example and thus removed the irretating octal stuff.

Categories

Resources