I am trying to create a 3x3 matrix that has the numbers 1 to 9 generated at different locations each time you run the code. the method I came up with does not work and I can't find out why it doesn't work, so if anyone could point out the reason why it does not work it would be really really appreciated.
and if anyone knows how to solve this problem in any other way please let me know.
Here's the method I created:
public static int[][] randgen() {
Random rand = new Random();
int[][] a = new int[3][3];
int x;
for(int i = 0; i<a.length; i++) {
for (int j = 0; j < a.length; j++) {
a[i][j] = rand.nextInt(8) +1;
do {
x = 1;
for(int k = 0; k<i; k++) {
for(int l = 0; l<j; l++) {
if(a[k][l] == a[i][j]) {
x++;
}
}
}
if(x!=1) {
a[i][j] = rand.nextInt(8) +1;
}
} while (x!=1); //this while loop I'm using as a way to find duplicates and keep changing up the number until I reach an integer with no duplicates, and this is the part of the program that is failing and I can't understand why
}
}
}
I've tried creating a sorted algorithm and then making a function to shuffle some of the elements which also did not work.
The only thing that worked for me is creating an ArrayList and then printing it out in a way that it looks like an array
Another variation...
Populate the list with the numbers 1 to 9 but then pick a random spot from it to fill the next slot of your array. Each time you pick a random spot from the list you remove it.
Might look like:
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.Arrays;
class Main {
public static void main(String[] args) {
Random rand = new Random();
int[][] a = new int[3][3];
int counter = 1;
int totalSpots = a.length * a[0].length; // assumes RECTANGULAR array
List<Integer> numbers = new ArrayList<Integer>();
while (counter <= totalSpots) {
numbers.add(counter);
counter++;
}
for(int row = 0;row < a.length; row++) {
for(int col = 0; col < a[0].length; col++) {
int index = rand.nextInt(numbers.size());
a[row][col] = numbers.get(index);
numbers.remove(index);
}
}
for(int[] row : a) {
System.out.println(Arrays.toString(row));
}
}
}
Sample output:
[5, 3, 6]
[9, 4, 8]
[2, 7, 1]
If we change the size of the array:
int[][] a = new int[5][4];
It sill works:
[7, 3, 6, 11]
[19, 20, 1, 4]
[13, 12, 17, 2]
[5, 18, 9, 16]
[14, 15, 10, 8]
Related
I want to write a function that takes an 2d array and fills it with 1...n but counting the columns first instead of the rows:
input = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
the output should be: {{1, 5, 7, 8}, {2}, {3}, {4, 6}};
if i were to loop through rows and then colums i get:
private static void fill1(int[][] input) {
int count = 1;
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input[i].length; j++) {
input[i][j] = count;
count++;
}
}
}
How do I loop through colums first?
You can do this by first transposing your input, executing your fill1 code and then transposing the output again.
See this question for how to transpose a 2 dimensional array in Java: java multi-dimensional array transposing
If you were dealing with a regular 2d matrix, where all the rows had the same number of columns, the code would be a simple modification of the code for filling the matrix row-by-row:
private static void fill1(int[][] input) {
int count = 1;
for (int j = 0; j < input[0].length; j++) {
for (int i = 0; i < input.length; i++) {
input[i][j]= count;
count++;
}
}
}
The process is basically the same for a ragged 2d array, but with a couple added twists:
You need to do some extra work to figure out how many columns there could be (i.e., the maximum row length)
You need to be prepared for the case when there's no cell at a given row/column position.
The following modification of the previous code addresses these issues:
private static void fill1(int[][] input) {
int maxCols = input[0].length;
for (int i = 1; i < input.length; ++i) {
if (input[i].length > maxCols) {
maxCols = input[i].length;
}
}
int count = 1;
for (int j = 0; j < maxCols; j++) {
for (int i = 0; i < input.length; i++) {
if (j < input[i].length) {
input[i][j]= count;
count++;
}
}
}
}
To iterate first over the columns of a jagged 2d array to fill it, you have to know the maximum number of columns beforehand, but if you don't know that, you can iterate to the Integer.MAX_VALUE and check at each step if the columns are still present or not:
int[][] arr = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
int count = 1;
for (int col = 0; col < Integer.MAX_VALUE; col++) {
boolean max = true;
for (int row = 0; row < arr.length; row++) {
if (col < arr[row].length) {
arr[row][col] = count;
count++;
max = false;
}
}
if (max) break;
}
for (int[] row : arr) {
System.out.println(Arrays.toString(row));
}
Output:
[1, 5, 7, 8]
[2]
[3]
[4, 6]
See also: How do you rotate an array 90 degrees without using a storage array?
To populate a 2d array first by columns, you can use two nested streams. In case of a jagged 2d array, when you don't know beforehand the number of the columns in each row, in an outer stream you can traverse while the columns are still present.
/**
* #param arr array that should be populated.
* #return maximum row length, i.e. columns count.
*/
private static long populate(int[][] arr) {
AtomicInteger counter = new AtomicInteger(1);
return IntStream
// traverse through the array columns
.iterate(0, i -> i + 1)
// process the array rows where
// this column is present
.mapToLong(i -> Arrays.stream(arr)
// filter those rows where
// this column is present
.filter(row -> row.length > i)
// assign a value to the element and increase the counter
.peek(row -> row[i] = counter.getAndIncrement())
// count of rows where this column is present
.count())
// while the columns are still present
.takeWhile(i -> i > 0)
// max columns count
.count();
}
public static void main(String[] args) {
int[][] arr = {{0, 0, 0, 0, 0, 0}, {0, 0}, {0}, {0, 0, 0}};
System.out.println("Max columns count: " + populate(arr));
System.out.println(Arrays.deepToString(arr));
}
Output:
Max columns count: 6
[[1, 5, 8, 10, 11, 12], [2, 6], [3], [4, 7, 9]]
See also: How to create a new List from merging 3 ArrayLists in round robin style?
I think I am missing something fundamental here about Java, I am not sure why my code below do not work, my steps:
the input is a 2x2 matrix,
copy the original matrix,
loop through rows then column,
assign original matrix's column values to the rows of the transpose matrix.
static void transpose(int[][] matrix) {
int[][] temp = matrix.clone();
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
matrix[i][j] = temp[j][i];
}
}
}
The problem is use the function clone() because that will create a new matrix sharing only row arrays.
Using the same code style, that works:
int[][] temp = new int[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
temp[i][j] = matrix[j][i];
}
}
Note that, as temp is an empty matrix, the comparsion will be temp = matrix.
So this works for a simple 2x2 matrix, but if you need other dimensions, instead of
int[][] temp = new int[2][2];
Use
int[][] temp = new int[matrix[0].length][matrix.length];
By the way, update the reference memory of the matrix is not a good practice. I think your method should return temp matrix.
An entire update, a better method could be this one. Is almost the same you have but it can accept diferent lengths.
public static int[][] transpose(int [][] matrix){
int[][] temp = new int[matrix[0].length][matrix.length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
temp[j][i] = matrix[i][j];
}
}
return temp;
}
You can use IntStream instead of for loop:
public static void main(String[] args) {
int[][] m1 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
int[][] m2 = transpose(m1);
Arrays.stream(m2).map(Arrays::toString).forEach(System.out::println);
// [1, 4, 7]
// [2, 5, 8]
// [3, 6, 9]
}
static int[][] transpose(int[][] matrix) {
return IntStream.range(0, matrix.length).mapToObj(i ->
IntStream.range(0, matrix[i].length).map(j ->
matrix[j][i]).toArray())
.toArray(int[][]::new);
}
So I am completely stumped. I need to create a multi-dimensional array n×n and have it be filled in a particular way. I have been able to create the 2d array per n×n but have no idea how to fill it. Below I have included the task worded exactly as given to me:
Given the number n, not greater than 100. Create the matrix of size n×n and fill it by the following rule. Numbers 0 should be stored on the primary diagonal. The two diagonals, adjacent to the primary one, should contain numbers 1. The next two diagonals - numbers 2, etc.
Sample Input 1:
5
Sample Output 1:
0 1 2 3 4
1 0 1 2 3
2 1 0 1 2
3 2 1 0 1
4 3 2 1 0
Here is my code so far. Any direction would be GREAT!!
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] array = new int[n][n];
for (int i = 0; i < array.length; i++) {
System.out.println(Arrays.toString(array[i]));
}
}
}
import java.util.Arrays;
import java.util.Scanner;
public class FillTheMatrixByTheNumbers {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.close();
int[][] matrix = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = Math.abs(j - i);
}
}
for (int i = 0; i < n; i++) {
String str = Arrays.toString(matrix[i]);
str = str.replace("[", "")
.replace(",", "")
.replace("]", "");
System.out.println(str);
}
}
}
Here's how I would approach your problem:
I would use nested for loops, one to iterate over the rows, and one to iterate over the columns. In my example, i is iterating over rows, and j is iterating over columns. Now that I know I'm hitting each cell of the matrix once and only once, I just have to figure out a way to calculate the cell's value from i and j. In this case, the cell's value is the column number minus the row number, or j - i, except there's no negatives, which can easily be solved with an absolute value (Math.abs(int)). Below is how I would do it:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] array = new int[n][n];
for (int i = 0; i < n; i++) { //iterate over rows
for (int j = 0; j < n; j++) { //iterate over columns
array[i][j] = Math.abs(j - i); //calculate cell's value
}
}
for (int i = 0; i < n; i++) {
System.out.println(Arrays.toString(array[i]));
}
}
}
import java.util.Scanner;
class Main {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] array = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
array[i][j] = Math.abs(j - i);
System.out.print(array[i][j] + " ");
}
System.out.println("");
}
}
}
You can subtract a column index from a row index or vice versa and take abs value from a result. This way you get a cell value:
int n = 5;
int[][] arr = IntStream.range(0, n)
.mapToObj(i -> IntStream.range(0, n)
.map(j -> Math.abs(i - j))
.toArray())
.toArray(int[][]::new);
// output
Arrays.stream(arr).map(Arrays::toString).forEach(System.out::println);
[0, 1, 2, 3, 4]
[1, 0, 1, 2, 3]
[2, 1, 0, 1, 2]
[3, 2, 1, 0, 1]
[4, 3, 2, 1, 0]
How would one go about filling in an array so that, for example, if you had the following array.
int[] arr = new int[5];
arr[0] = 1;
arr[1] = 3;
arr[2] = 7;
arr[3] = 2;
arr[4] = -4;
so it would look like
arr = {1, 3, 7, 2, -4};
and you would pass it into your method to get a result of
arr = {1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4};
so that you essentially are filling in the numeric gaps. I'd like to make this under the assumption that I don't know how long the array passed in is going to be to make it a more universal method.
my current method looks like such right now...
public static void fillArray(int[] numbers){
int length = numbers.length;
for(int i = 0; i < numbers.length - 1; i ++){
if(numbers[i] <= numbers[i + 1]){
length += numbers[i + 1] - numbers[i];
}else if(numbers[i + 1] < numbers[i]){
length += numbers[i + 1] - numbers[i];
}
}
}
I have length to determine the size of my new array. I think it should work but I'm always down for some input and advice.
Looks like homework, providing algorithm only:
Navigate through the elements of the current array.
Get the distance (absolute difference) between the elements in the array.
Summarize the distances.
Create a new array whose length would be the sum of the distances.
Fill the new array using the elements of the first array and filling the gaps.
Return the array.
Like Luiggi Mendoza said, looks like HW, so here's another algorithm:
insert the first element into a list of integers.
loop on the rest of the elements.
for each two array elements X[i-1], X[i], insert the missing integers to the list
after the loop - use guava to turn the List to array.
This works. just check for array size < 2 for safety.
public static void main(String[] args) {
int[] arr = {1, 3, 7, 2, -4};
Integer[] result = fillArray(arr);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
}
private static Integer[] fillArray(int[] arr) {
List<Integer> list = new ArrayList<Integer>();
list.add(arr[0]);
for (int i = 1; i < arr.length; i++) {
int prevItem = arr[i-1];
int gap = arr[i] - prevItem;
if(gap > 0){
fillGap(list, prevItem, gap, 1);
} else if(gap < 0){
fillGap(list, prevItem, gap, -1);
}
}
return list.toArray(new Integer[0]);
}
private static void fillGap(List<Integer> list, int start, int gap, int delta) {
int next = start+delta;
for (int j = 0; j < Math.abs(gap); j++) {
list.add(next);
next = next+delta;
}
}
Try
import java.util.ArrayList;
import java.util.List;
public class ArrayGap {
public static void main(String[] args) {
int[] arr = {1, 3, 7, 2, -4};
int high, low;
List<Integer> out = new ArrayList<Integer>();
for(int i=0; i<arr.length - 1; i++){
high = arr[i];
if(arr[i] < arr[i+1]){
for(int j=arr[i]; j<arr[i+1]; j++){
out.add(j);
}
} else {
for(int j=arr[i]; j>=arr[i+1]; j--){
out.add(j);
}
}
}
System.out.println(out);
}
}
The program below generates 10 pairs of random numbers of a certain size and stores them in an ArrayList named test -
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
public class randomGenerate
{
static ArrayList<String> tcase=new ArrayList<String>();
static ArrayList<int[]> test=new ArrayList<int[]>();
public static void main(String args[])
{
tcase.add("1");
tcase.add("2");
tcase.add("3");
tcase.add("4");
tcase.add("5");
tcase.add("6");
randomSelection(10,2);
for(int i=0;i<test.size();i++)
{
System.out.println(Arrays.toString(test.get(i)));
}
}
static int randomNo(int max,int min)
{
Random obj = new Random();
int n = max - min + 1;
int i = obj.nextInt(n);
int randomNum = min + i;
return randomNum;
}
static void randomSelection(int limit, int pairSize)
{
int max = Integer.parseInt(Collections.max(tcase));
int min = Integer.parseInt(Collections.min(tcase));
System.out.println(max+" "+min);
int ar[]=new int[pairSize];
for(int i = 0;i < limit;i++)
{
for(int j = 0;j < pairSize;j++)
{
ar[j]=randomNo(max,min);
System.out.print(ar[j]);
}
test.add(ar);
System.out.println();
}
}
}
My problem is that while printing the contents of the arrayList "test" only the last value is displayed. Why is it not displaying all the values.
output - (for example)
23
65
45
63
12
23
52
52
16
12
[1, 2]
[1, 2]
[1, 2]
[1, 2]
[1, 2]
[1, 2]
[1, 2]
[1, 2]
[1, 2]
[1, 2]
You're always modifying and adding the same array to the list at each iteration.
Think of a situation like this :
You need to create a new array at each iteration :
for(int i = 0;i < limit;i++){
int ar[]=new int[pairSize]; //create a new one at each iteration
for(int j = 0;j < pairSize;j++){
ar[j]=randomNo(max,min);
System.out.print(ar[j]);
}
test.add(ar);
System.out.println();
}
The problem is that you are adding the array ar to the ArrayList test each iteration in randomSelection(), so when you modify ar in the next iteration, you are modifying it inside the ArrayList, to solve this try:
Way 1:
Create a new array each iteration
int ar[];
for (int i = 0; i < limit; i++) {
ar = new int[pairSize]; // Initialize inside 'for'
for (int j = 0; j < pairSize; j++) {
ar[j] = randomNo(max, min);
System.out.print(ar[j]);
}
test.add(ar);
}
Way 2:
Create a copy of the array ar and add it to test:
int ar[] = new int[pairSize];
for (int i = 0; i < limit; i++) {
for (int j = 0; j < pairSize; j++) {
ar[j] = randomNo(max, min);
System.out.print(ar[j]);
}
test.add(ar.clone()); // Create a copy
}