why does Random(System.currentTimeMillis()); give me repeated values (Java)? [duplicate] - java

This question already has answers here:
Java random numbers using a seed
(7 answers)
Closed 4 years ago.
I'm a novice Java programmer and need to create two random numbers. We were instructed to use System.currentTimeMillis() however I don't know why I am getting so many repeated numbers.
import java.util.Random;
public class TestClass1 {
public static void main(String[] args) {
int points = 0;
while (points < 100) {
int[] scoreInfo = diceGen();
System.out.println(scoreInfo[0]);
System.out.println(scoreInfo[1]);
points += 1;
}
}
public static int[] diceGen() {
Random num = new Random(System.currentTimeMillis());
int dice1 = num.nextInt(6)+1;
int dice2 = num.nextInt(6)+1;
int[] numbers = {dice1, dice2};
return numbers;
}
}
Output:
6
6
6
6
6
6
6
6
6
6
6
6
6
6
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
4
2
3
4
3
4
3
4
3
4
3
4
3
4
3
4
3
4
3
4
3
4
3
4
3
4
3
4
3
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
1
4
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
2
6
5
6
5
6
5
6
5
6
5
6
5
6
5
6
5
6
5
6
5
6
5
6
5

The parameter to the Random() constructor is the seed to the random number generator. Every time you create a new Random instance with the same seed, it will generate the same numbers. Since an execution of diceGen() takes less than a millisecond, you're creating multiple instances with the same millisecond count.
Instead, you need to create a single Random instance and store it in a field or pass it as a parameter.

The code is executing fast enough that between two iterations of the loop, the value returned by System.currentTimeMillis() remains the same. Those Random instances are therefore created with the same seed and return the same values.
Consider using System.nanoTime() or construct a single Random instance and reuse it in all of your iterations.
Something like
public static void main(String[] args) {
int points = 0;
Random num = new Random(System.nanoTime());
while (points < 100) {
int[] scoreInfo = diceGen(num);
System.out.println(scoreInfo[0] + ", " + scoreInfo[1]);
points += 1;
}
}
public static int[] diceGen(Random num) {
int dice1 = num.nextInt(6) + 1;
int dice2 = num.nextInt(6) + 1;
int[] numbers = { dice1, dice2 };
return numbers;
}

Make the rng global in scope. Each call will change the number. If you seed the rng each time you call the generator, chances are you will call the seed on the same tick and so get the same number.
import java.util.Random;
public class TestClass1 {
static public Random num = new Random(System.currentTimeMillis());
public static void main(String[] args) {
int points = 0;
while (points < 100) {
int[] scoreInfo = diceGen();
System.out.println(scoreInfo[0]);
System.out.println(scoreInfo[1]);
points += 1;
}
}
public static int[] diceGen() {
int dice1 = num.nextInt(6)+1;
int dice2 = num.nextInt(6)+1;
int[] numbers = {dice1, dice2};
return numbers;
}
}
The way rngs work is x = trunc( old_x * big_prime ) + prime and on first call old_x is the seed.

Related

is not Thread-Safe for Bill Pugh Singleton?

I thought 'Thread safe' was an instance lock
But writing the test code did not produce the desired results.
The result I want should be square like this.
singleton new instance
0 0 0 0 0 0 0 0 0 0
2 2 2 2 2 2 2 2 2 2
4 4 4 4 4 4 4 4 4 4
1 1 1 1 1 1 1 1 1 1
3 3 3 3 3 3 3 3 3 3
6 6 6 6 6 6 6 6 6 6
5 5 5 5 5 5 5 5 5 5
8 8 8 8 8 8 8 8 8 8
7 7 7 7 7 7 7 7 7 7
9 9 9 9 9 9 9 9 9 9
This is the code I wrote when testing.
public class main extends Thread{
String name = "";
public main(String name) {
this.name = name;
}
#Override
public void run() {
BillPughSingleton.getInstance().addNum(name);
}
public static void main(String[] args){
for(int i=0; i< 10; i++)
new main(i+"").start();
}
}
public class BillPughSingleton {
private BillPughSingleton() {}
private static class BillPughSingletonHolder{
private static BillPughSingleton INSTANCE = new BillPughSingleton();
static {
System.out.println("singleton new instance");
}
}
public static BillPughSingleton getInstance() {
return BillPughSingletonHolder.INSTANCE;
}
//Adding 'synchronized' to it result I want.
public void addNum(String name) {
for(int i=0; i<10;i ++)
System.out.print(name+" ");
System.out.println(); // \n
}
}
Please let me know if I misunderstand 'Thread-safe'.
Thank you!

How can I space my triangle correctly?

I am trying to print out a Right Triangle that looks like this:
1
2 1
3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
11 10 9 8 7 6 5 4 3 2 1
The size of the triangle increases if the number in the method gets larger, which in this case is 11.
My code seems to only work up to 10 as after 10, my spacing is messed up.
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
10 9 8 7 6 5 4 3 2 1
11 10 9 8 7 6 5 4 3 2 1
12 11 10 9 8 7 6 5 4 3 2 1
13 12 11 10 9 8 7 6 5 4 3 2 1
I am trying to make it so that up to 99, the spacing is correct. What kind of edits should I do to my if statements or for loops in order to space it properly?
Code:
public class Patterns
{
public static void main(String[] args)
{
displayPattern(13);
//displayPattern(11,",");
}
public static void displayPattern(int n)
{
//print out n-1 spaces and the first number
//print n-2 spaces and the 2nd then first number
int counter = n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= counter; j++)
{
if (n > 10)
{
if (i == n)
{
System.out.print("");
}
else if (i <= 10)
{
System.out.print(" ");
}
else
{
System.out.print(" ");
}
}
else if (n <=10)
{
if (i>9)
{
System.out.print(" ");
}
else
{
System.out.print(" ");
}
}
}
System.out.print(i + " ");
int tempValue = i - 1;
while(tempValue>0)
{
System.out.print(tempValue);
if(tempValue>1)
{
System.out.print(" ");
}
tempValue--;
}
if(tempValue==0)
{
System.out.print("\n");
}
counter--;
}
}
}

Doubling a 2-dimensional matrix in Java [duplicate]

This question already has answers here:
Doubling a Matrix
(3 answers)
Closed 7 years ago.
I currently have a program that, when asked for an integer from the user, generates a square 2d matrix based on the input (i.e.,.: input of 2 results in a 2x2 grid).
The program then fills this matrix with random numbers 0-9, and then creates a new matrix that is double the size of the original (2x2 becomes 4x4, 3x3 to 6x6, etc.).
However, I cannot get the results to duplicate properly. I'm trying to get the matrix to duplicate in such a way that from a matrix such as this:
1 2 3
4 5 6
7 8 9
It would produce a matrix of:
1 1 2 2 3 3
1 1 2 2 3 3
4 4 5 5 6 6
4 4 5 5 6 6
7 7 8 8 9 9
7 7 8 8 9 9
Currently, I'm just using two for loops to generate this matrix, but it doesn't print out the correct results.
public static void main(String[] args) {
System.out.println("Enter the size of the matrix.");
Scanner keyboard = new Scanner(System.in);
Random random = new Random();
int n = keyboard.nextInt();
int[][] matrix = new int[n][n];
for (int x=0;x<n;x++)
{
for (int y=0;y<n;y++)
{
matrix[x][y] = random.nextInt(10);
}
}
System.out.println("The matrix is");
for (int x=0;x<matrix.length;x++)
{
for (int y=0;y<matrix.length;y++)
{
System.out.print(matrix[x][y]+" ");
}
System.out.println("");
}
int nDouble = n * 2;
int c = 1;
int[][] matrixDoubled = new int[nDouble][nDouble];
for (int y=0;y<matrix.length;y++)
{
for (int x=0;x<matrix.length;x++)
{
matrixDoubled[x][y] = matrix[x][y];
matrixDoubled[x+c][y] = matrix[x][y];
matrixDoubled[x][y+c] = matrix[x][y];
matrixDoubled[x+c][y+c] = matrix[x][y];
c = c + 1;
}
c = 1;
}
System.out.println("The doubled matrix is");
for (int x=0;x<matrixDoubled.length;x++)
{
for (int y=0;y<matrixDoubled.length;y++)
{
System.out.print(matrixDoubled[x][y]+" ");
}
System.out.println("");
}
}
}
The indices of the doubled matrix are wrong. They should be :
matrixDoubled[2*x][2*y] = matrix[x][y];
matrixDoubled[2*x+1][2*y] = matrix[x][y];
matrixDoubled[2*x][2*y+1] = matrix[x][y];
matrixDoubled[2*x+1][2*y+1] = matrix[x][y];
this way matrix[0][0] is mapped to positions [0][0],[1][0],[0][1]&[1][1] in the new matrix, matrix[0][1] is mapped to positions [0][2],[1][2],[0][3]&[1][3], and so on...
If thats the same problem as in this question that should do it:
for (int i = 0; i < matrixDoubled.length; i++)
for (int j = 0; j < matrixDoubled.length; j++)
matrixDoubled[i][j] = matrix[i/size][j/size];
Note: This code is surely not the best solution but a fast an easy one. It only works if both dimensions are the same size and it won't work if matrixDoubled is not exactly two times matrix. If it's always just to "double" a matrix it should work fine.
Output:
If you choose size 2 than it will output:
Enter the size of the matrix
2
The Matrix is
3 5
5 2
The matrixDoubled is
3 3 5 5
3 3 5 5
5 5 2 2
5 5 2 2
and for size 3 it would be for example
Enter the size of the matrix
3
The Matrix is
4 4 3
5 9 4
7 4 1
The matrixDoubled is
4 4 4 4 3 3
4 4 4 4 3 3
5 5 9 9 4 4
5 5 9 9 4 4
7 7 4 4 1 1
7 7 4 4 1 1
I hope this helps (:

Palindrome Program using Recursion

This is currently what I have for my Palindrome program for my computer science class. I have it pretty much working, except whenever a word is a palindrome, it is an infinite loop. I know I have to insert a number base case, but I do not how to do that...I'm really having trouble understanding recursion. Help is appreciated.
public class PalindromeTester
{
public static void main(String[] args)
{
Scanner scan = new Scanner (System.in);
String str, another = "y";
int left, right;
while (another.equalsIgnoreCase("y"))
{
System.out.println("Enter a potential palindrome:");
str = scan.next();
left = 0;
right = str.length() - 1;
tester(str, left, right);
System.out.println();
System.out.println("Test another palindrome (y/n)?");
another = scan.next();
}
}
public static void tester (String str, int left, int right)
{
Scanner scan = new Scanner (System.in);
while (str.charAt(left) == str.charAt(right) && left < right)
{
System.out.println(str);
tester( str, left + 1, right -1);
}
if (left < right)
{
System.out.println("That string is NOT a palindrome.");
}
else
{
System.out.println("That string IS a palindrome.");
}
}
}
You are using a while loop. With recursion, this is done implicitly.
You have to split the algorithm in small parts.
[] represents left, {} represents right.
[1] 2 3 4 5 6 7 8 9 0 9 8 7 6 5 4 3 2 {1} -->Level 0
1 [2] 3 4 5 6 7 8 9 0 9 8 7 6 5 4 3 {2} 1 -->Level 1
1 2 [3] 4 5 6 7 8 9 0 9 8 7 6 5 4 {3} 2 1 -->Level 2
1 2 3 [4] 5 6 7 8 9 0 9 8 7 6 5 {4} 3 2 1 -->Level 3
1 2 3 4 [5] 6 7 8 9 0 9 8 7 6 {5} 4 3 2 1 -->Level 4
1 2 3 4 5 [6] 7 8 9 0 9 8 7 {6} 5 4 3 2 1 -->Level 5
1 2 3 4 5 6 [7] 8 9 0 9 8 {7} 6 5 4 3 2 1 -->Level 6
1 2 3 4 5 6 7 [8] 9 0 9 {8} 7 6 5 4 3 2 1 -->Level 7
1 2 3 4 5 6 7 8 [9] 0 {9} 8 7 6 5 4 3 2 1 -->Level 8
1 2 3 4 5 6 7 8 9 {[0]} 9 8 7 6 5 4 3 2 1 -->Level 9
So, tester will continue until:
We've reached the middle of the word.
The word is not a palindrome
Example of case 2:
[1] 2 3 A 5 6 7 8 9 0 9 8 7 6 5 4 3 2 {1}
1 [2] 3 A 5 6 7 8 9 0 9 8 7 6 5 4 3 {2} 1
1 2 [3] A 5 6 7 8 9 0 9 8 7 6 5 4 {3} 2 1
1 2 3 [A] 5 6 7 8 9 0 9 8 7 6 5 {4} 3 2 1 --> !!!
I thought this method would be very helpful for the understanding of how is this recursion working
public static String positions(String word, int l, int r) {
char[] a = word.toCharArray();
String s = "";
// [letter] if left, {} if right, [{}] if both
for (int i = 0; i < a.length; i++) {
if (l == i && r == i) {
s += "{[" + a[i] + "]}";
} else if (l == i) {
s += "[" + a[i] + "]";
} else if (r == i) {
s += "{" + a[i] + "}";
} else {
s += a[i];
}
s+=" ";
}
return s;
}
And finally, the tester method.
public static boolean tester(String str, int left, int right) {
System.out.println(positions(str, left, right) +" tester(str, "+left +", "+right+")");
if (left>=right) // case 1
return true; // that's ok, we've reached the middle
// the middle was not reached yet.
// is the condition satisfied?
if (str.charAt(left) == str.charAt(right)) {
// yes. So, lets do it again, with the parameters changed
return tester(str, left + 1, right - 1);
}
//the condition was not satisfied. Let's get out of here.
else {
return false;
}
}
Some outputs:
Enter a potential palindrome:
1234567890987654321
[1] 2 3 4 5 6 7 8 9 0 9 8 7 6 5 4 3 2 {1} tester(str, 0, 18)
1 [2] 3 4 5 6 7 8 9 0 9 8 7 6 5 4 3 {2} 1 tester(str, 1, 17)
1 2 [3] 4 5 6 7 8 9 0 9 8 7 6 5 4 {3} 2 1 tester(str, 2, 16)
1 2 3 [4] 5 6 7 8 9 0 9 8 7 6 5 {4} 3 2 1 tester(str, 3, 15)
1 2 3 4 [5] 6 7 8 9 0 9 8 7 6 {5} 4 3 2 1 tester(str, 4, 14)
1 2 3 4 5 [6] 7 8 9 0 9 8 7 {6} 5 4 3 2 1 tester(str, 5, 13)
1 2 3 4 5 6 [7] 8 9 0 9 8 {7} 6 5 4 3 2 1 tester(str, 6, 12)
1 2 3 4 5 6 7 [8] 9 0 9 {8} 7 6 5 4 3 2 1 tester(str, 7, 11)
1 2 3 4 5 6 7 8 [9] 0 {9} 8 7 6 5 4 3 2 1 tester(str, 8, 10)
1 2 3 4 5 6 7 8 9 {[0]} 9 8 7 6 5 4 3 2 1 tester(str, 9, 9)
true
Test another palindrome (y/n)?
y
Enter a potential palindrome:
12345A678654321
[1] 2 3 4 5 A 6 7 8 6 5 4 3 2 {1} tester(str, 0, 14)
1 [2] 3 4 5 A 6 7 8 6 5 4 3 {2} 1 tester(str, 1, 13)
1 2 [3] 4 5 A 6 7 8 6 5 4 {3} 2 1 tester(str, 2, 12)
1 2 3 [4] 5 A 6 7 8 6 5 {4} 3 2 1 tester(str, 3, 11)
1 2 3 4 [5] A 6 7 8 6 {5} 4 3 2 1 tester(str, 4, 10)
1 2 3 4 5 [A] 6 7 8 {6} 5 4 3 2 1 tester(str, 5, 9)
false
Test another palindrome (y/n)?
In the main method,
System.out.println(tester(str, left, right));
In order to see the true/false output
Since your are using recursion (in its basic purposes mostly used to eliminate loops), isn't your while loop inside the tester() method supposed to be an if?
public static void tester (String str, int left, int right)
{
Scanner scan = new Scanner (System.in);
if (str.charAt(left) == str.charAt(right) && left < right)
{
System.out.println(str);
tester( str, left + 1, right -1);
}
else if (left < right)
{
System.out.println("That string is NOT a palindrome.");
}
else
{
System.out.println("That string IS a palindrome.");
}
}
I modified your tester() method and replaced your while with an if and moved your second if clause.
public static void tester(String str, int left, int right) {
if (str.charAt(left) == str.charAt(right) && left < right) {
tester(str, left + 1, right - 1);
} else {
if (left < right) {
System.out.println("That string is NOT a palindrome.");
} else {
System.out.println("That string IS a palindrome.");
}
}
}

Java algorithm to make a straight pyramid [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 8 years ago.
Improve this question
___________1
__________1 2 1
_________1 2 3 2 1
________1 2 3 4 3 2 1
______1 2 3 4 5 4 3 2 1
_____1 2 3 4 4 4 4 4 3 2 1
___1 2 3 3 3 3 3 3 3 3 3 2 1
__1 2 2 2 2 2 2 2 2 2 2 2 2 2 1
_1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
I would like to create this pyramid using java? Any suggestion?
This should do it:
public class Tower {
public static void main(String[] args) {
System.out.println(" 1 ");
System.out.println(" 1 2 1 ");
System.out.println(" 1 2 3 2 1 ");
System.out.println(" 1 2 3 4 3 2 1 ");
System.out.println(" 1 2 3 4 5 4 3 2 1 ");
System.out.println(" 1 2 3 4 4 4 4 4 3 2 1 ");
System.out.println(" 1 2 3 3 3 3 3 3 3 3 3 2 1 ");
System.out.println(" 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 ");
System.out.println(" 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ");
}
}
Try using a mono-spaced font like courier.
This will surve the purpose. You can change the number 5 to another number other than 5. eg. 1,2,3,.. , 6,8
public static void main(String[] args) {
List<String> list = new LinkedList<String>();
for(int i = 5; i > 0; i-- ){
wrapWithNumber(list, i);
}
for (String string : editListToBeInTriangleShape(list)) {
System.out.println(string);
};
}
/**
* Wrap the number strings in the llist with a perticular number.
* #param list list of Strings
* #param ba number which need to wrapp the list with.
*/
private void wrapWithNumber(List<String> list, final int ba) {
list.add(0, String.format("%d",ba));
for (int i = 1; i < list.size(); i++) {
String newformat = "%1$d " + list.get(i) + " %1$d";
list.remove(list.get(i));
list.add(i,String.format(newformat, ba));
}
String lastFormat = "%1$d";
for(int i = 0; i < 2 * list.size();i++){
lastFormat += " %1$d";
}
if(list.size() != 1) {
list.add(String.format(lastFormat, ba));
}
}
/**
* Arrage the Strings in the list in triangular manner.
* #param list list of Strings.
*/
private List<String> editListToBeInTriangleShape(final List<String> list) {
final List<String> returnList = new LinkedList<String>();
for (int i = list.size(); i > 0; i--) {
String s = list.get(list.size()-i);
int possition = list.size()*2 + s.length()/2;
returnList.add(String.format("%"+possition+"s", s));
}
return returnList;
}
out put of this :
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 4 4 4 4 3 2 1
1 2 3 3 3 3 3 3 3 3 3 2 1
1 2 2 2 2 2 2 2 2 2 2 2 2 2 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
I would suggest a series of for loops.

Categories