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 (:
Related
I'm currently making a latin square that starts with a user-set number but for simplicity's sake I'll exclude Scanner code.
public static void main(String[] args){
int first = 2; // starting integer on square
int order = 4; //max integer
String space = new String(" ");
for (int row = 0; row < order; row++)
{
for (int column = 0; column < order; column++)
{
for (int shift = 0; shift < order; shift++)
{
int square = ((column+(first-1)) % order + 1); //this makes a basic square with no shifting
int latin = square+shift; //this is where my code becomes a mess
System.out.print(latin + space);
}
System.out.println();
}
}
}
}
Which prints out:
2 3 4 5
3 4 5 6
4 5 6 7
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
1 2 3 4
It's so close, considering the fact that it does start with my pre-determined first digit and it's printing only 4 integers.
The problem I'm running into is the fact that it's going further than my order integer and that it's printing double the rows.
Any idea what I can do to fix this?
For reference, this is what I want it to print:
2 3 4 1
3 4 1 2
4 1 2 3
1 2 3 4
It seems that the innermost loop for (int shift...) is redundant and it causes duplication of the output, the latin value should be calculated using row parameter:
public static void main(String args[]) {
int first = 2; // starting integer on square
int order = 4; //max integer
String space = " ";
for (int row = 0; row < order; row++) {
for (int column = 0; column < order; column++) {
int latin = (row + column + first - 1) % order + 1;
System.out.print(latin + space);
}
System.out.println();
}
}
Output:
2 3 4 1
3 4 1 2
4 1 2 3
1 2 3 4
Question:
Can the algorithm posted below be adjusted to use the same array (which represents a 2D matrix) for a clockwise rotation instead of using a second array and still remain at O(n) complexity?
Code:
import java.util.Random;
public class MatrixRotation {
public static void main(String[] args) {
int dimension = 5;
int[] array = generate(dimension);
print(array, dimension);
int[] clockwise = clockwise(array, dimension);
print(clockwise, dimension);
}
//Generate a matrix with random values
private static int[] generate(int dimension) {
Random rand = new Random();
int[] array = new int[dimension * dimension];
for(int i = 0; i < array.length; i++) {
array[i] = rand.nextInt(10);
}
return array;
}
//Rotates the matrix clockwise by calculating where the value's position should be after the rotation
private static int[] clockwise(int[] array, int dimension) {
int[] rotated = new int[array.length];
int baseCount = dimension;
for(int i = 0; i < array.length; i++) {
int remainder = i % dimension;
if(remainder == 0)
baseCount--;
int position = baseCount + (dimension * remainder);
//I suspect I can do some kinda swapping functionality here but am stumped
rotated[position] = array[i];
}
return rotated;
}
//Used to display the matrix
private static void print(int[] array, int dimension) {
for(int i = 0; i < array.length; i++) {
if(i % dimension == 0)
System.out.println();
System.out.print(array[i] + " ");
}
System.out.println();
}
}
Sample Output:
1 7 4 1 4
2 3 5 2 9
4 3 9 3 1
5 8 7 5 6
3 3 7 2 5
3 5 4 2 1
3 8 3 3 7
7 7 9 5 4
2 5 3 2 1
5 6 1 9 4
Background:
I was reading a question the other day about matrix rotations represented in a 1D array and decided to take swing at it. I managed to successfully create a rotation algorithm by calculating the next position of the value after the rotation. Currently I'm trying to determine if there's a way to keep it as O(n) while reducing the space used by keeping it inside the same array. Any thoughts on how to achieve this?
I found a working solution! I wasn't able to determine how to make it work with the posted algorithm, but once I started designing it from scratch with rotation swapping from the start I found a solution in the same complexity (essentially). I designed it with the idea of working from the outside to the inside via "onion layers" by finding the corners of each layer and then rotating them and their relative directional adjacent. Something like:
↓ ↓ ↓
5 5 8 2 1 ← 7 5 8 2 5 7 2 8 2 5
9 4 8 2 3 9 4 8 2 3 ← 9 4 8 2 5
6 3 7 5 4 6 3 7 5 4 → 6 3 7 5 4 ← Ect...
2 6 4 2 7 → 2 6 4 2 7 5 6 4 2 7
→ 7 0 7 5 5 5 0 7 5 1 5 0 7 3 1
↑ ↑ ↑
For each layer.
Code:
private static int[] clockwise2(int[] array, int dimension) {
int layers = dimension / 2; //Total layers of the onion
//Loop through the layers
for (int i = 0; i < layers; i++) {
int layerWidth = dimension - 2 * i; //Current layer width
int topStart = i + dimension * i; //Top left corner
int rightStart = topStart + (layerWidth - 1); //Top right corner
int bottomStart = (array.length - 1) - topStart; //Bottom right corner
int leftStart = bottomStart - (layerWidth - 1); //Bottom left corner
//Loop values in current layer
for (int j = 0; j < layerWidth - 1; j++) {
int topIndex = topStart + j; //Move right
int rightIndex = rightStart + dimension * j; //Move down
int bottomIndex = bottomStart - j; //Move left
int leftIndex = leftStart - dimension * j; //Move up
//Swap the values in a circular direction
int temp = array[topIndex];
array[topIndex] = array[leftIndex];
array[leftIndex] = array[bottomIndex];
array[bottomIndex] = array[rightIndex];
array[rightIndex] = temp;
}
}
return array;
}
I need an explanation of how the output prints 9(S), 7(S), 5(S) and 3(S).
10 > 3 is correct and goes to y 1 <= 2 which is correct so 2 x 10 - 2 = 18 but the output prints 9. I don't understand the logic here. Why does it print 9(s) instead of 18(s)?
public class Q2{
public static void main(String args[]) {
int x,y;
for(x= 10; x > 3; x = x - 2) {
for(y = 1; y <= 2 * x - 2; y = y + 2)
System.out.print("S");
System.out.print("\n");
}
}
}
Its correct Y <= 18 , but you are incrementing Y by 2, so it gets printed 9 times.
To understand, write down on a piece of paper what the values of your variables will be.
First, write down the values of x:
x: 10 8 6 4
Next, write down the calculated upper boundary value for y, i.e. the result of expression 2 * x - 2:
x : 10 8 6 4
yMax: 18 14 10 6
Last, write down the values of y:
x : 10 8 6 4
yMax: 18 14 10 6
y : 1 1 1 1
3 3 3 3
5 5 5 5
7 7 7
9 9 9
11 11
13 13
15
17
Finally, count the number of y values for each x value, i.e. the number of times S is printed:
x : 10 8 6 4
count: 9 7 5 3
Then realize that the code would have been much easier to understand if it had just been written like this:
for (int count = 9; count >= 3; count -= 2) {
for (int i = 0; i < count; i++) {
System.out.println("S");
}
}
Of course, that wouldn't have taught you what they were trying to teach you, which is:
Conclusion: If you don't understand what the code is doing, follow the logic step by step, and write down what it is doing.
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.
I wrote simple code on random permutation between 1 to 10 using ArrayList. How can I make ArrayList in my file SmartPermutationGenerator to print the result by size of 10 in a console to get output as below:
I don't want this output:
Random arrays using Smart Force:
8 4 8 1 8 4 10 8 4 1 7 8 4 1 10 5 8 4 1 10 7 2 8 4 1 10 7 5 9 8 4 1 10 7 5 2 6 8 4 1 10 7 5 2 9 3 8 4 1 10 7 5 2 9 6
I want this output instead:
Random arrays using Smart Force:
8 4 8 1 8 4 10 8 4 1
7 8 4 1 10 5 8 4 1 10
7 2 8 4 1 10 7 5 9 8
4 1 10 7 5 2 6 8 4 1
10 7 5 2 9 3 8 4 1 10
7 5 2 9 6
Should limit the solution using arraylist only, don't want to use recursion.
This is my file SmartPermutationGenerator
import java.util.ArrayList;
import java.util.Random;
public class SmartPermutationGenerator
{
private int size;
private Random rand = new Random();
public SmartPermutationGenerator()
{
this.size = 10;
}
public ArrayList nextPermutation()
{
ArrayList<Integer> unused = new ArrayList<Integer>();
for (int i = 0; i < size; i++) // loop for element in array
{
unused.add(i + 1);
}
ArrayList<Integer> perm = new ArrayList<Integer>();
for (int k = 0; k < size; k++) //loop for random number between 1 to 10
{
int pos = rand.nextInt(unused.size());
perm.add(unused.get(pos));
unused.remove(pos);
System.out.print(perm.get(k) + " ");
for (int j = 0; j < k; j++)
{
System.out.print(perm.get(j) + " "); //loop for permutation 10 times
//System.out.println();
}
}
return perm;
}
}
This is my file BrutePermutationGenerator
import java.util.Random;
public class BrutePermutationGenerator
{
private int[] num = new int[10];
public int[] nextPermutation()
{
Random rand = new Random();
for (int j = 0; j < 10; j++)//loop for permutation 10 times
{
for (int i = 0; i < 10; i++)//loop for random number between 1 to 10
{
int low = 1;
int high = 10;
int range = high - low + 1;
int r = rand.nextInt(range);
num[i] = num[r];
num[r] = i;
}
for (int i = 0; i < 10; i++)// loop for element in array
{
System.out.print(num[i] + 1 + " ");
}
System.out.println();
}
return num;
}
}
This is my main file PermutationGeneratorViewer
public class PermutationGeneratorViewer
{
public static void main(String[] args)
{
BrutePermutationGenerator brute = new BrutePermutationGenerator();
SmartPermutationGenerator smart = new SmartPermutationGenerator();
System.out.println("\n" + "Random arrays using Brute Force: ");
brute.nextPermutation();
System.out.println("\n" + "Random arrays using Smart Force: ");
smart.nextPermutation();
}
}
You can use the modulus operator (%) in the printing loops to see if the index is a multiple of ten. If it is, print a newline.
Something like this would work:
for(...){
System.out.print(...);
if(count%10==0 && count!=0){ // if the index of the number is a multiple of 10 but not the first number
System.out.println(); // print a newline to separate rows
}
}
This will add a newline after the 10th, 20th, 30th, etc. numbers.
Another excellent solution is to create function for permutation to be repeated in file SmartPermutationGenerator as below:
public ArrayList<Integer> getRandomPermutation()
{
ArrayList<Integer> unused = new ArrayList<>();
.
.
.
}
public void nextPermutation()
{
for(int i = 0; i < size; i++) //loop for permutation 10 times
{
for(Integer item : getRandomPermutation())
{
System.out.print(item + " ");
}
System.out.println();
}
}
Solution credited to Mr.Soleh Abd Wahab.