Question

So I spent a few hours today writing out logic, and turning it into code, but I'm completely stuck at this point, and I don't know what to do. I've only been programming in java for a few months now, so the entire "logical" mindset is still not quite there yet. Can anyone help me think through the logic of how to create a ulam spiral in java?

import java.util.Arrays;

public class GridMaker {
    private static int gridRow = 5; // R = length
    private static int gridCol = 5; // C = height
    private static int[][] grid = new int[gridRow][gridCol];
    private static int totalSteps = (gridRow * gridCol); // total blocks on the grid
    private static int location = 1; // location refers to the number in the box, ie. 1, 2, 3, etc.
    private static int rowLength = 1;

    public static void main(String[] args) {
        grid[Calc.findArrayCenter(gridRow)][Calc.findArrayCenter(gridRow)] = 1;
        rowBrowser();
        colBrowser();

    for (int r = 0; r < gridRow; r++){
        for (int c = 0; c < gridCol; c++){
            System.out.print(grid[r][c] + " ");
        }
        System.out.println("");
    }
}

public static void rowBrowser() {
    int rowCount = 1;
    int x = 1;
    int stepsInvolved = 2;

    if (x < stepsInvolved) {
        if (Calc.isOdd(rowCount) == true) {
            grid[Calc.findArrayCenter(gridRow)][Calc.findArrayCenter(gridCol) + x] = location + 1;
            stepsInvolved++;
        }
    }
    location++;
    x++;
}

private static void colBrowser() {

}
}

    public class Calc {
public static int findArrayCenter(int center) {
    int fcenter = 0;
    if (center % 2 != 0)
        fcenter = (int) ((center / 2));
    else
        fcenter = (center / 2);
    return fcenter;
}

public static boolean isOdd(int num) {
    boolean result = true;
    if (num % 2 == 0)
        result = false; // false = even, true = odd
    return result;
}
}

At this point, what do I need to do to finish creating the ulam spiral? What I'm working on now is have the array keep track of a position, run through each step across a row, then drop down and run through the steps in a column, after that add 1 to each counter and continue. Help? And sorry for the terrible formatting, this site doesn't really help that much when it comes to pasting code... :|

Était-ce utile?

La solution

You're not clear about what's wrong with your code; it would be better to be explicit about what behavior you want and what behavior you are observing and where specifically you are stuck in making them match.

However, I suggest that you start by working on printing a simply number spiral pattern. From the Wikipedia article on the Ulam spiral, the basic spiral looks like this:

number spiral

A little study of the spiral shows some interesting properties. Starting from the center (where "1" is printed), going down and to the right on the diagonal you see all the odd squares in sequence. (Each row save the last extends one past the square, to include (2k+1)2+1.) Likewise, going up and to the left on the diagonal you see all the numbers of the form (2k)2 + 1 (one plus the even squares). You can use these properties to calculate the bounds of each row of the spiral.

Suppose you want to print 2N+1 rows and columns of the spiral (in the figure, N=3). Let the center row be row 0, column 0, so row and column indices range from -N to +N (inclusive). It makes sense to imagine a (2N+1) × (2N+1) matrix of cells. Our job is to decide how to fill in this matrix.

At this point, there are a couple of ways to approach the problem. In one approach, you fill it in by deciding where each integer 1, 2, ..., etc. goes, starting with "1" going at cell (0, 0). The other approach is to decide, for each cell (c, r), what integer goes in it.

Let's take the latter approach. We can observe the following properties for row r:

r ≤ 0

  • the number on the main diagonal on row r is (2r)2+1. This is at coordinates (r, r) from the center.
  • there are 1-2r connected numbers in sequence on row r (recall that r <= 0), going left-to-right in descending order from cell (r, r) through cell (-r, r). (For example, for r=-1, the sequence is "5—4—3" at cells (-1, -1), (0, -1), (1, -1).)
  • there are 2N+1 numbers on every row, which leaves (N+r) numbers to the left and right of the connected sequence.
  • for each cell (c, r) on row r with c < r (≤ 0), the number is obtained by adding r-c to the number at cell (c, c) (which, from above, is (2c>2+1).
  • for each cell (c, r) on row r with c > -r, the number is obtained by adding c+r to the number at cell (c, c) (which, from the first rule below, is (2c+1)2).

r ≥ 0

  • the number on the main diagonal on row r is (2r+1)2.
  • for r < N, there are 2r+2 connected numbers in sequence on row r, in going left-to-right in ascending order from cell (-r, r) through cell (r, r+1). (For example, "7—8—9—10".) On the last row (r=N), there are only 2N+1 connected numbers, since that's where we truncate the spiral.
  • there are 2N+1 numbers on every row, which leaves (N-r) numbers to the left and (N-r-1) numbers to the right of the connected sequence.
  • for each cell (c, r) on row r with c < -r, the number is obtained by adding r-c to the number at cell (c, c).
  • for each cell (c, r) on row r with c > r+1, the number is obtained by adding c-r to the number at cell (c, c).

From these rules, you should be able to create an algorithm to print out a spiral for any N > 0. I haven't addressed the issue of vertical connections between cells, but you can apply a similar analysis to discover the rules for drawing them. For proper formatting, you should pick a fixed width for each cell (which, obviously, should be wide enough for the largest number, (2N+1)2).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top