Skip to main content
added 2 characters in body
Source Link
public class SnailMatrix {
    
    private final int[][] data;
    
    private SnailMatrix(int n) {
        this.data = new int[n][n];
    }
    
    public static SnailMatrix ofSize(int n) {
        var matrix = new SnailMatrix(n);
        var initializer = new MatrixInitializer(matrix);
        
        initialize(initializer);
        
        return matrix;
    }
    
    private static void initialize(MatrixInitializer initializer) {
        int value = 1;
        
        while (initializer.hasNext()) {
            initializer.set(value++);
            initializer.next();
        }
    }
    
    public int size() {
        return data.length;
    }
    
    public int get(final int x, final int y) {
        return data[y][x];
    }
    
    private void set(final int x, final int y, final int value) {
        data[y][x] = value;
    }
    
    // ...

    private static class MatrixInitializer {
        private static final int[][] DIRECTIONS =
            new int[][]{
                {1, 0}, {0, 1}, {-1, 0}, {0, -1}
            };
        private final SnailMatrix matrix;
        private int direction = 0;
        publicprivate int x;
        publicprivate int y;
        
        public MatrixInitializer(SnailMatrix matrix) {
            this.matrix = matrix;
        }
        
        public void set(int value) {
            matrix.set(x, y, value);
        }
        
        public boolean hasNext() {
            return  isValid(x, y)
                && !isInitialized();
        }
        
        private boolean isValid(int x, int y) {
            return x >= 0 && x < matrix.size()
                && y >= 0 && y < matrix.size();
        }
        
        private boolean isInitialized() {
            return isInitialized(x, y);
        }
        
        private boolean isInitialized(int x, int y) {
            return matrix.get(x, y) != 0;
        }
        
        private void next() {
            checkDirection();
            x += xDelta();
            y += yDelta();
        }
        
        private void checkDirection() {
            int nextX = x + xDelta();
            int nextY = y + yDelta();
            if (!isValid(nextX, nextY) || isInitialized(nextX, nextY)) {
                changeDirection();
            }
        }
        
        public int xDelta() {
            return DIRECTIONS[direction][0];
        }
        
        public int yDelta() {
            return DIRECTIONS[direction][1];
        }
        
        private void changeDirection() {
            direction = (direction + 1) % DIRECTIONS.length;
        }
    }
}
public class SnailMatrix {
    
    private final int[][] data;
    
    private SnailMatrix(int n) {
        this.data = new int[n][n];
    }
    
    public static SnailMatrix ofSize(int n) {
        var matrix = new SnailMatrix(n);
        var initializer = new MatrixInitializer(matrix);
        
        initialize(initializer);
        
        return matrix;
    }
    
    private static void initialize(MatrixInitializer initializer) {
        int value = 1;
        
        while (initializer.hasNext()) {
            initializer.set(value++);
            initializer.next();
        }
    }
    
    public int size() {
        return data.length;
    }
    
    public int get(final int x, final int y) {
        return data[y][x];
    }
    
    private void set(final int x, final int y, final int value) {
        data[y][x] = value;
    }
    
    // ...

    private static class MatrixInitializer {
        private static final int[][] DIRECTIONS =
            new int[][]{
                {1, 0}, {0, 1}, {-1, 0}, {0, -1}
            };
        private final SnailMatrix matrix;
        private int direction = 0;
        public int x;
        public int y;
        
        public MatrixInitializer(SnailMatrix matrix) {
            this.matrix = matrix;
        }
        
        public void set(int value) {
            matrix.set(x, y, value);
        }
        
        public boolean hasNext() {
            return  isValid(x, y)
                && !isInitialized();
        }
        
        private boolean isValid(int x, int y) {
            return x >= 0 && x < matrix.size()
                && y >= 0 && y < matrix.size();
        }
        
        private boolean isInitialized() {
            return isInitialized(x, y);
        }
        
        private boolean isInitialized(int x, int y) {
            return matrix.get(x, y) != 0;
        }
        
        private void next() {
            checkDirection();
            x += xDelta();
            y += yDelta();
        }
        
        private void checkDirection() {
            int nextX = x + xDelta();
            int nextY = y + yDelta();
            if (!isValid(nextX, nextY) || isInitialized(nextX, nextY)) {
                changeDirection();
            }
        }
        
        public int xDelta() {
            return DIRECTIONS[direction][0];
        }
        
        public int yDelta() {
            return DIRECTIONS[direction][1];
        }
        
        private void changeDirection() {
            direction = (direction + 1) % DIRECTIONS.length;
        }
    }
}
public class SnailMatrix {
    
    private final int[][] data;
    
    private SnailMatrix(int n) {
        this.data = new int[n][n];
    }
    
    public static SnailMatrix ofSize(int n) {
        var matrix = new SnailMatrix(n);
        var initializer = new MatrixInitializer(matrix);
        
        initialize(initializer);
        
        return matrix;
    }
    
    private static void initialize(MatrixInitializer initializer) {
        int value = 1;
        
        while (initializer.hasNext()) {
            initializer.set(value++);
            initializer.next();
        }
    }
    
    public int size() {
        return data.length;
    }
    
    public int get(final int x, final int y) {
        return data[y][x];
    }
    
    private void set(final int x, final int y, final int value) {
        data[y][x] = value;
    }
    
    // ...

    private static class MatrixInitializer {
        private static final int[][] DIRECTIONS =
            new int[][]{
                {1, 0}, {0, 1}, {-1, 0}, {0, -1}
            };
        private final SnailMatrix matrix;
        private int direction = 0;
        private int x;
        private int y;
        
        public MatrixInitializer(SnailMatrix matrix) {
            this.matrix = matrix;
        }
        
        public void set(int value) {
            matrix.set(x, y, value);
        }
        
        public boolean hasNext() {
            return  isValid(x, y)
                && !isInitialized();
        }
        
        private boolean isValid(int x, int y) {
            return x >= 0 && x < matrix.size()
                && y >= 0 && y < matrix.size();
        }
        
        private boolean isInitialized() {
            return isInitialized(x, y);
        }
        
        private boolean isInitialized(int x, int y) {
            return matrix.get(x, y) != 0;
        }
        
        private void next() {
            checkDirection();
            x += xDelta();
            y += yDelta();
        }
        
        private void checkDirection() {
            int nextX = x + xDelta();
            int nextY = y + yDelta();
            if (!isValid(nextX, nextY) || isInitialized(nextX, nextY)) {
                changeDirection();
            }
        }
        
        public int xDelta() {
            return DIRECTIONS[direction][0];
        }
        
        public int yDelta() {
            return DIRECTIONS[direction][1];
        }
        
        private void changeDirection() {
            direction = (direction + 1) % DIRECTIONS.length;
        }
    }
}
added 4 characters in body
Source Link
coderodde
  • 32.1k
  • 15
  • 78
  • 205

3 is a "magic number", it should be deltas.length - 1 instead.

3 is a "magic number", it should be deltas.length instead.

3 is a "magic number", it should be deltas.length - 1 instead.

added 958 characters in body
Source Link

Would it be nicenicer from the reader's perspective to see something like this:

And on the inside, xDelta() and yDelta() can perfectly well operate with an array of integers int[][] instead of IntPair[].

Your SnailMatrixGenerator class has a lot of knowledge about SnailMatrix, since it knows how to traverse it. Meanwhile, the noun Generator in its name suggests that it should be responsible for instantiation of SnailMatrix, basically matrix factory. But there's nothing intricate (for nowat least for now) in obtaining the instance of SnailMatrix to warrant the existence of a factory.

Populating the matrix is a different concerndifferent concern, and the matrix factory should not dial with it.

Based on the responsibility of this class, it makes sense to call it Initializer.

To populate the matrix, Initializer features the functionality for populating the matrix in the form the following methods:

Here's how it might be implemented (deltas transformed into static field int[][] DIRECTIONS and deltaIndex became direction):

Method name moveCursorToNextLocation can be shortened to moveCursor and still be informative. And when this method is being placed inside the class, solely task with traversal name next is sufficient to communicate its purpose.

Would it be nice from the reader's perspective to see something like this:

And on the inside xDelta and yDelta can perfectly well operate with an array of integers int[][] instead of IntPair[].

Your SnailMatrixGenerator class has a lot of knowledge about SnailMatrix, since it knows how to traverse it. Meanwhile, the noun Generator in its name suggests that it should be responsible for instantiation of SnailMatrix, basically matrix factory. But there's nothing intricate (for now) in obtaining the instance of SnailMatrix to warrant the existence of a factory.

Populating the matrix is a different concern, and matrix factory should not dial with it.

Based on the responsibility of this class it makes sense to call it Initializer.

Initializer features the functionality for populating the matrix in the form the following methods:

Method name moveCursorToNextLocation can be shortened to moveCursor and still be informative. And when this method is placed inside the class

Would it be nicer from the reader's perspective to see something like this:

And on the inside, xDelta() and yDelta() can perfectly well operate with an array of integers int[][] instead of IntPair[].

Your SnailMatrixGenerator class has a lot of knowledge about SnailMatrix, since it knows how to traverse it. Meanwhile, the noun Generator in its name suggests that it should be responsible for instantiation of SnailMatrix, basically matrix factory. But there's nothing intricate (at least for now) in obtaining the instance of SnailMatrix to warrant the existence of a factory.

Populating the matrix is a different concern, and the matrix factory should not dial with it.

Based on the responsibility of this class, it makes sense to call it Initializer.

To populate the matrix, Initializer features the following methods:

Here's how it might be implemented (deltas transformed into static field int[][] DIRECTIONS and deltaIndex became direction):

Method name moveCursorToNextLocation can be shortened to moveCursor and still be informative. And when this method is being placed inside the class, solely task with traversal name next is sufficient to communicate its purpose.

added 958 characters in body
Source Link
Loading
Source Link
Loading