My issue is the following:
I have a 2D array of size n x m, entered on a single line. On the next n lines there are m number of elements, that fill the array. So far so good.
There is a pawn on the field that always starts at the only 0 on the field (assuming there is always one 0).
It can move up and down, right and left. It always moves to the neighbouring cell with most coins and at each move collects 1 coin (=> empties the visited cell by 1). The pawn does this until there are only 0s around it and it can collect nothing anymore. I need to find the sum of all coins collected.
Here is a representation of first steps in Paint:
Coin Collection first steps:
Sample input:
4 3, 3 2 4, 2 0 3, 1 1 5, 2 2 5 -> output: 22
Here is my code so far:
I have some unfinished work with the targetCell (I still wonder how to get its coordinates dynamically in a loop, so that each cell with a larger value than the previous turns to a targetCell.) Also I'm stuck with using the directions I just created. Any hints would be useful for me to further develop the task.
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] my_array = input.split(" ");
int[] array = Arrays.stream(my_array).mapToInt(Integer::parseInt).toArray();
int n = array[0]; // rows of matrix
int m = array[1]; // cols of matrix
int[][] matrix = new int[n][m];
for (int i = 0; i < n; i++) {
String line = scanner.nextLine();
String[] numbers = line.split(" ");
matrix[i] = new int[m];
for (int j = 0; j < m; j++) {
matrix[i][j] = Integer.parseInt(numbers[j]);
}
}
int startPoint = 0;
int currentRow = 0;
int currentCol = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0) {
startPoint = matrix[i][j];
currentRow = i;
currentCol = j;
}
}
}
int target1 = 0;
int target2 = 0;
int targetCell = 0;
target1 = Math.max(matrix[currentRow - 1][currentCol], matrix[currentRow + 1][currentCol]);
target2 = Math.max(matrix[currentRow][currentCol - 1], matrix[currentRow][currentCol + 1]);
targetCell = Math.max(target1, target2);
System.out.println(targetCell);
int hDirection = 1;
if (targetCol < currentCol) {
hDirection = -1;
}
int vDirection = 1;
if (targetRow < currentRow) {
vDirection = -1;
}
}
}
}
(Can't comment so will use an answer for now. Sorry)
My first thought would be to keep a global variable for the run so that when a coin is collected, it is added to its current value; similar to how you would keep score in games like Tetris. That's assuming I've read it right.
So something like:
private static int current_score = 0; //Assuming no use of objects so using static
Couldn't understand the sample input in this example. If you could give a three turn scenario of what the final score would be, I could give you better insight.
Related
A brief explanation: With the code below it will make a randomly generated Square and some code below would make sure that it was a Magic Square, in which the sum of the elements in each row, column, and the two diagonals are the same value.
My teacher said at maximum it should take three minutes to generate a magic square. So all I ask is there anything that can be done to improve or fix this code, please?
import java.util.ArrayList;
import java.util.Random;
class Main {
public static void main(String[] args) {
int size = 9;
int N = 3;
boolean result = true;
ArrayList<Integer> list = new ArrayList<Integer>(size);
int[][] mat = new int[N][N];
while (result) {
for (int i = 1; i <= size; i++) {
list.add(i);
}
Random rand = new Random();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int index = rand.nextInt(list.size());
System.out.print(list.remove(index)+" ");
}
System.out.println();
}
System.out.println();
// Checking process
// sumd1 and sumd2 are the sum of the two diagonals
int sumd1 = 0, sumd2 = 0;
for (int i = 0; i < N; i++) {
// (i, i) is the diagonal from top-left -> bottom-right
// (i, N - i - 1) is the diagonal from top-right -> bottom-left
sumd1 += mat[i][i];
sumd2 += mat[i][N - 1 - i];
}
// if the two diagonal sums are unequal then it is not a magic square
if (sumd1 != sumd2)
result = false;
// calculating sums of Rows and columns and checking if they are equal to each other,as well as equal to diagonal sum or not
for (int i = 0; i < N; i++) {
int rowSum = 0, colSum = 0;
for (int j = 0; j < N; j++) {
rowSum += mat[i][j];
colSum += mat[j][i];
}
if (rowSum != colSum || colSum != sumd1)
result=false;
}
result = true;
}
}
}
Trying with random numbers to coincidentally find a solution is deadly slow.
If you have the numbers 1 to 9, its entire sum 1+2+3+...+8+9 is 9*(1+9)/2 = 45.
As you have 3 rows and 3 colums, a row and column must sum upto 45/3 = 15.
Now that should restrict the number of possibilities.
So you must build in some intelligence in the code. Avoid random numbers as they do not even guarantee you'll find a solution in hundred years.
If you already treated recursion, that would be the easiest way to try all possibly valid combinations.
If you already treated Set, a BitSet maybe might be useful for a row, column or diagonal.
If you find it hard to code walking through all possibilities, you might hold the 2 dimensional matrix in a 1 dimensional array int[N*N], and have N (rows) + N (columns) + 2 (diagonals) arrays of N indices.
And of course I will not spoil your fun and satisfaction finding a smart solution.
Work it out on paper first.
My goal for this program is to create a 2D-array ratings whose size is specified by the first two arguments from the command line. args[0] would represent the number of rows r and arg[1] would represent the number of columns c. The next arguments that follow would all be used to fill in the array. So if the command-line argument was 3 2 5 2 3 3 4 1. I would hope that the array would be 3 rows by 2 columns. The value 5 would be in ratings[0][0], the value 2 would be in ratings[0][1], the value 3 would be in ratings[1][0], etc. After that, I want to compute the sum of each column. So column 0 would be 12 and column 1 would be 6 in this scenario.
public static void main(String[] args) {
int r = Integer.parseInt(args[0]);
int c = Integer.parseInt(args[1]);
int[][] ratings = new int[r][c];
int z = 2;
int y = 3;
int x = 0;
int counting = 0;
int sum = 0;
for (int rows = 0; rows < ratings.length; rows++ ) {
for (int column = 0; column < ratings[c].length; column++){
ratings[rows][column] = Integer.parseInt(args[z]);
sum += ratings[rows][column];
z++;
}
System.out.println(sum);
sum = 0;
}
//System.out.println(movieRating);
}
This is my attempt at summing the columns but this right now just sums 5 and 2, 3 and 3, 4 and 1. I want the columns not the rows to be summed but do not know how to fix it. Thank you
You seem to be adding the values to the 2D array correctly. What you're missing is an additional nested loop to print out the column totals:
for (int i = 0; i < ratings[c].length; i++) {
int colSum = 0;
for (int j = 0; j < ratings.length; j++) {
colSum += ratings[j][i];
}
System.out.println(colSum);
}
Add that where you currently have that //System.out.println(movieRating); line. Since you were adding the numbers to the array row-wise, you need to flip the for loops to be able to sum the columns.
Things you did right
You correctly initialized the ratings 2D-array with the values given on the command line. Let me re-write this below without your attempt at computing the columns' sum. Note that I renamed the variables so that the indices used in the for loop are single letter variable.
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
argIndex++;
}
}
}
Thing you didn't get right
The ratings array is filled row by row. In the code you posted, you compute in variable sum the sum of the elements inserted in the same row. This is the reason why it doesn't print the results you expected.
To compute the sum of each columns, I would recommend you create a new array in which to store this result. Integrating it with the code above:
public static void main(String[] args) {
int rows = Integer.parseInt(args[0]);
int columns = Integer.parseInt(args[1]);
int[][] ratings = new int[rows][columns];
int[] columnSums = new int[columns];
int argIndex = 2;
for (int r = 0; r < ratings.length; r++ ) {
for (int c = 0; column < ratings[r].length; c++){
ratings[r][c] = Integer.parseInt(args[argIndex]);
columnSums[c] += ratings[r][c];
argIndex++;
}
}
// array columnSums contains your results
}
I have changed your original code with a simpler version.
Let me know if you have problems understanding the solution.
public static void main(String[] args)
{
int row = Integer.parseInt(args[0]);
int col = Integer.parseInt(args[1]);
int arrayLength = row * col; // use a single dimension array, for simplicity
int[] ratings = new int[arrayLength]; // the array size is based on the rows and columns
// add data to the 'ratings' array
// This is not actually needed because the conversion can be done directly when the columns are summed up
for(int i = 0; i < arrayLength; i++)
{
ratings[i] = Integer.parseInt(args[i + 2]);
}
// sum up the columns using the % operator
int[] result = new int[col];
for(int i = 0; i < arrayLength; i++)
{
result[i % col] += ratings[i];
}
// print result
for(int i = 0; i < result.length; i++)
{
System.out.println(String.format("Movie %d rating is %d", i, result[i]));
}
}
PS: you are missing the validation around the String to int conversion and checks around the correctness of the user input
I was trying to do a 2D array program to demonstrate a TRANSPOSE but I am getting error .. here is my code.
import java.util.Scanner;
/* To demonstrate TRANSPOSE USING 2-D array */
public class Array_2ddd {
public static void main(String args[]) {
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[9][9];
int myArray2[][] = new int[9][9];
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.println("Enter array from 1 to 9");
myArray1[i][j] = s1.nextInt();
System.out.print("your array is" + myArray2[i][j]);
}
}
// Transposing now...
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.print("Your array is as follow" + myArray2[i][j]);
}
}
}
}
EDIT: My error during runtime (Solved)
EDIT 2: Solved
EDIT 3: The loop is in infinity ..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity..
There are several errors in your code, also it is recommend that the dimensions of the array is to be declared as a final int, so your code works for all matrix sizes and that debugging is easier. In your original code, the errors are:
At the input step, you are printing one element of myArray[2] before you perform the transpose. That means, you are getting your array is0.
In the section commented "After transposing", you are outputting your array wrong. Namely, for each entry, you call System.out.print("Your array is as follow" + myArray2[i][j]);, and that you forgot to add a new line after each row (when inner loop is finished).
"..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity.." There are 81 entries for the 9-by-9 case and you did not output which i,j index to be applied. You probably mistaken an infinite loop with a long but terminating loop.
Your transpose step is good.
Here is a refined version of your code which allows you to input array (in reading order, or more technically, row-major order), create a transposed array. You can copy and compare your current code with this code directly to test it.
public static void main(String args[]) {
final int m = 9; // Rows
final int n = 9; // Columns
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[m][n]; // Original array, m rows n cols
int myArray2[][] = new int[n][m]; // Transposed array, n rows m cols
// Input
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
// Should be only prompt.
// Improved to show which entry will be affected.
System.out.printf("[%d][%d]" + "Enter array from 1 to 9\n", i, j);
myArray1[i][j] = s1.nextInt();
}
}
// Transposing now (watch for the ordering of m, n in loops)...
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing, output
System.out.print("Your array is:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
System.out.print(myArray1[i][j] + " ");
}
System.out.println(); // New line after row is finished
}
System.out.print("Your transposed array is:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
System.out.print(myArray2[i][j] + " ");
}
System.out.println();
}
s1.close();
}
For an array with three rows (m = 3) and four columns (n = 4), I inputted the numbers from 0 to 9, and then 0, 1, 2. As expected, the output should be:
Your array is:
0 1 2 3
4 5 6 7
8 9 0 1
Your transposed array is:
0 4 8
1 5 9
2 6 0
3 7 1
You define your matrix as 9x9
int myArray1[][] = new int[9][9];
But actually you want to insert 10x10 items:
for (i = 0; i <= 9; i++)
{
for (j = 0; j <= 9; j++)
So either:
Redefine your arrays to store 10x10 items
int myArray1[][] = new int[10][10];
Only read and store 9x9 items in your defined array
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++)
You haven't close your first outer for loop i.e in line 17 and change your array size to 10,as you wanted take 10 input (for 0 to 9 = 10 values).
Please dont let the length of this post scare you! Okay so here is the prompt I am currently working on:
"Write a class named BucketSort containing a method called sort that:
a) Place each value of the one-dimensional array into a row of the bucket array, based on the value’s “ones” (rightmost) digit. For example, 97 is placed in row 7, 3 is placed in row 3 an 100 is placed in row 0. This procedure is called a distribution pass.
b) Loop through the bucket array row by row, and copy the values back to the original array. This procedure is called a gathering pass. The new order of the preceding values in the one-dimensional array is 100, 3 and 97.
c) Repeat this process for each subsequent digit position (tens, hundreds, thousands, etc.) On the second (tens digit) pass, 100 is placed in row 0, 3 is placed in row 0 (because 3 has no tens digit) and 97 is placed in row 9. After the gathering pass, the order of the values in the one-dimensional array is 100, 3 and 97. On the third (hundreds digit) pass, 100 is placed in row 1, 3 is placed in row 0 and 97 is placed in row 0 (after the 3) After this last gathering pass, the original array is in sorted order. being sorted.
This sorting technique provides better performance than a bubble sort,but requires much more memory—the bubble sort requires space for only one additional element of data. This comparison is an example of the space/time trade-off: The bucket sort uses more memory than the bubble sort, but performs better. This version of the bucket sort requires copying all the data back to the original array on each pass. Another possibility is to create a second two-dimensional bucket array and repeatedly swap the data between the two bucket arrays. The two-dimensional array of buckets is 10 times the length of the integer array"
A bit of a mouth full I know. Below is my code thus far, but I can't figure out why it will not print in the correct order and I think it is time for fresh eyes. Any ideas are appreciated, thanks!
import java.util.Arrays;
public class BucketSort_main {
public static void main(String[] args)
{
int[] numbers = new int [5];
int[] tnumbers = new int [500];
int [][] bucket = new int [10][numbers.length];
int [] a = new int [10];
int count = 0;
int divisor = 1;
int cnt = 1;
boolean moreDigits = true;
for (int s = 0; s < 10; s++)
{
a[s] = 0;
}
for (int b = 0; b < numbers.length; b++)
{
numbers [b] = (int)(Math.random()*2000);
tnumbers [b] = numbers [b];
}
int[] tmpSort = new int[10];
while (moreDigits)
{
moreDigits = false;
for (int i = 0; i < tmpSort.length; i++)
{
tmpSort[i]= -1; // hint hint
}
for (int i = 0; i < numbers.length; i++)
{
int tmp = tnumbers[i] / divisor;
if (tmp/10 != 0)
{
moreDigits = true;
}
int digit = tmp % 10;
tmpSort[digit] = tnumbers[i]; // hint hint
System.out.println("Number["+i+"], Digit "+cnt+" is "+digit + ". Full number = " + tnumbers[i]);
bucket [digit][a[digit]] = tnumbers[i];
System.out.println ("Digit " + digit + " going to slot " + a[digit] + ". " + bucket[digit][a[digit]]);
System.out.println (" ");
a[digit]++;
}
cnt++;
divisor *= 10;
for (int x = 0; x < 10; x++)
{
a [x] = 0;
for (int y = 0; y < numbers.length; y++)
{
if (bucket[x][y] != 0)
{
tnumbers [y] = 0;
tnumbers [y] = bucket[x][y];
bucket[x][y] = 0;
}
}
}
}
for (int o = 0; o < numbers.length; o++)
{
System.out.println (tnumbers[o]);
}
}
}
The Problem is here:
for (int x = 0; x < 10; x++)
{
a [x] = 0;
for (int y = 0; y < numbers.length; y++)
{
if (bucket[x][y] != 0)
{
tnumbers [y] = 0;
tnumbers [y] = bucket[x][y];
bucket[x][y] = 0;
}
}
}
You are using the same y to get values from the bucket and assign values to tnumbers. So, when you loop through y the second time you are starting over again at tnumbers[0], tnumbers[1], etc...
Fix this issue and your code works fine.
Can anyone explain the output of this code? I have been hitting my head really hard to understand, but I just don't get it.
public static void main(String ars[]) {
int responses[] = {1,2,4,4};
int freq[] = new int[5];
for(int answer = 1; answer < responses.length; answer++) {
++freq[responses[answer]];
}
for (int rating = 1; rating < freq.length; rating++)
System.out.printf("%6d%10d\n", rating, freq[rating]);
}
Output
1 0
2 1
3 0
4 2
In first loop ++freq[responses[answer]]; means :
responses[answer] get the value from response array index.
Freq[value] check & get the value from Filter array index.
++Freq[value] add value 1 to Freq[value].
I've tried to simply things a bit so you can see what is going on:
int responses[] = new int[4];
responses[0] = 1;
responses[1] = 2;
responses[2] = 4;
responses[3] = 4;
int freq[] = new int[5];
for(int answer = 1; answer < 4; answer++)
{
int x = responses[answer];
freq[x] = freq[x] + 1;
}
for (int rating = 1; rating < 5; rating++)
{
//Print 6 spaces and then the rating variable
//Print 10 spaces then the integer at freq[rating]
System.out.printf("%6d%10d\n", rating, freq[rating]);
}
I would look up the ++ prefix & postfix.