2

[SOLVED]

The title of this question is vague but hopefully this will clear things up.

Basically, what I am looking for is a solution to rotating this set of data. This data is set up in a specific way.

Here is an example of how the input and output would look like:

Input:

3
987
654
321

Output:

123
456
789

The '3' represents the number of columns and rows that will be used. If you input the number '4', you will be allowed to input 4 sets of 4 integers.

Input:

4
4567
3456
2345
1234

Output:

1234
2345
3456
4567

The goal is to find a way to rotate the data only if needed. You have to make sure the smallest corner number is at the top left. For example, for the code above, you rotated it so 1 is at the top left.

The problem I have is that I don't know how to rotate the data. I am only able to rotate the corners but not the sides. This is what my code does so far:

  • take the input of each line and turn them into strings
  • split those strings into separate characters
  • store those characters in an array

I just do not know how to compare those characters and in the end rotate the data.

Any help would be appreciated! Any questions will be answered.

A detailed description of the problem is here(problem J4). This is just a challenge I assigned myself for practice for next year's contest, so giving me the answer won't "spoil" the question, but actually help me learn.

Here is my code so far:

import java.util.Scanner;

public class Main {

public static void main(String[] args) {
    Scanner kb = new Scanner(System.in);

    int max = kb.nextInt();
    int maxSqrt = (max * max);

    int num[] = new int[max];
    String num_string[] = new String[max];
    char num_char[] = new char[maxSqrt];

    int counter = 0;
    int counter_char = 0;


    for (counter = 0; counter < max; counter++) {
        num[counter] = kb.nextInt();
    }

    for (counter = 0; counter < max; counter++) {
        num_string[counter] = Integer.toString(num[counter]);
    }

    int varPos = 0, rowPos = 0, charPos = 0, i = 0;

    for (counter = 0; counter < maxSqrt; counter++) {
        num_char[varPos] = num_string[rowPos].charAt(charPos);
        i++;

        if (i == max) {
            rowPos++;
            i = 0;
        }

        varPos++;

        if (charPos == (max - 1)) {
            charPos = 0;
        } else {
            charPos++;
        }
    }

    //


    for(int a = 0 ; a < max ; a++){

        for(int b = 0 ; b < max ; b++)
        {
            num_char[counter_char] = num_string[a].charAt(b);
            counter_char++;
        }
    }
//here is where the code should rotate the data





}

}

UmWut
  • 49
  • 1
  • 5
  • What have you tried, and what exatly is the problem with it? – jonrsharpe Nov 01 '18 at 22:40
  • @jonrsharpe I tried a variety of for loops but I can't seem to find a way to rotate the sides correctly. I can rotate the corners so that the smallest number is at the top left but I can't seem to rotate the numbers between the corners, if that makes sense – UmWut Nov 01 '18 at 22:42
  • This is a simpler problem if you treat this as a 1d array mapped to a 2d array. You could think of the squares like rotating a series of rings - like concentric circles. Each ring has a circumference. 1, 8, 12 - the count of the outer times as you go up being the difference of squares that'd fit the circle, 1, 3, 5. Then you know where in the 1d array each circle begins. You only need rotate that subsection - rotating one of the rings. Should do what you want. – cyborg Nov 01 '18 at 23:11
  • @cyborg I understand what you are getting to. I was and still am more confused about the syntax than the logic behind it. Thanks for the answer, it did give me an idea on how I can reform my code! – UmWut Nov 01 '18 at 23:19

1 Answers1

8

This is a standard 90 degree clockwise rotation for a 2D array.

I have provided the solution below, but first a few comments.

You said that you're doing this:

  1. take the input of each line and turn them into strings
  2. split those strings into separate characters
  3. store those characters in an array

Firstly youre essentially turning a int matrix into a character matrix. I do not think you need to do this, since even if you do want to compare values, you can use the ints provided.

Secondly, there is no need to compare any 2 data elements in the matrix, since the rotation does not depend on any value.

Here is an adapted solution for java, originally written in C# by Nick Berardi on this question

private int[][] rotateClockWise(int[][] matrix) {
 int size = matrix.length;
 int[][] ret = new int[size][size];

 for (int i = 0; i < size; ++i) 
  for (int j = 0; j < size; ++j) 
   ret[i][j] = matrix[size - j - 1][i]; //***

 return ret;
}

If you wanted to do a counterCW rotation, replace the starred line with

ret[i][j] = matrix[j][size - i - 1]
Profilüfter
  • 81
  • 2
  • 12
PhaseRush
  • 340
  • 4
  • 10
  • Ah I see. I didn't even know there was such thing as a 2d array – UmWut Nov 01 '18 at 23:06
  • A 2-D array is an array of arrays. Consider a rectangular digital image - it has rows and columns. You can represent the data in this image in 2 ways - row major or column major. (deleted explanation because I dont think I do as good of a job as I would like. Refer to the many resources online to help you understand) – PhaseRush Nov 03 '18 at 18:35
  • 1
    How to solve this problem if you are asked to do the task in-place with O(1) additional memory? Tried a lot, unable to do it that way. It's one of the questions that gets asked in interviews. – VC2019 Jun 24 '21 at 20:41