lots of exercises in java... from https://github.com/exercism/java

RectangleCounter.java 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import static java.util.Arrays.copyOfRange;
  2. import static java.util.Arrays.stream;
  3. final class RectangleCounter {
  4. int countRectangles(final String[] rawGrid) {
  5. final int nRows = rawGrid.length;
  6. if (nRows == 0) return 0;
  7. final int nCols = rawGrid[0].length();
  8. if (nCols == 0) return 0;
  9. return new Grid(nRows, nCols, rawGrid).countRectangles();
  10. }
  11. private static final class Grid {
  12. private enum Tile {
  13. CORNER,
  14. HORIZONTAL_WALL,
  15. VERTICAL_WALL,
  16. SPACE;
  17. private static Tile fromChar(final char rawGridTile) {
  18. switch (rawGridTile) {
  19. case '+': return CORNER;
  20. case '-': return HORIZONTAL_WALL;
  21. case '|': return VERTICAL_WALL;
  22. case ' ': return SPACE;
  23. default: throw new IllegalStateException("Grid tile " + rawGridTile + " not recognized.");
  24. }
  25. }
  26. private boolean isHorizontalConnector() {
  27. return this == CORNER || this == HORIZONTAL_WALL;
  28. }
  29. private boolean isVerticalConnector() {
  30. return this == CORNER || this == VERTICAL_WALL;
  31. }
  32. }
  33. private int nRows, nCols;
  34. private final Tile[][] tiles;
  35. private Grid(final int nRows, final int nCols, final String[] rawGrid) {
  36. this.nRows = nRows;
  37. this.nCols = nCols;
  38. this.tiles = new Tile[nRows][nCols];
  39. for (int nRow = 0; nRow < nRows; nRow++) {
  40. for (int nCol = 0; nCol < nCols; nCol++) {
  41. tiles[nRow][nCol] = Tile.fromChar(rawGrid[nRow].charAt(nCol));
  42. }
  43. }
  44. }
  45. private int countRectangles() {
  46. int result = 0;
  47. for (int topRow = 0; topRow < nRows - 1; topRow++) {
  48. for (int leftCol = 0; leftCol < nCols - 1; leftCol++) {
  49. // Only check rectangles that lie below/to the right of our current coordinate:
  50. for (int bottomRow = topRow + 1; bottomRow < nRows; bottomRow++) {
  51. for (int rightCol = leftCol + 1; rightCol < nCols; rightCol++) {
  52. if (formsRectangle(topRow, bottomRow, leftCol, rightCol)) {
  53. result++;
  54. }
  55. }
  56. }
  57. }
  58. }
  59. return result;
  60. }
  61. private boolean formsRectangle(
  62. final int topRow,
  63. final int bottomRow,
  64. final int leftCol,
  65. final int rightCol) {
  66. return tiles[topRow][leftCol].equals(Tile.CORNER)
  67. && tiles[topRow][rightCol].equals(Tile.CORNER)
  68. && tiles[bottomRow][leftCol].equals(Tile.CORNER)
  69. && tiles[bottomRow][rightCol].equals(Tile.CORNER)
  70. && isHorizontalLineSegment(topRow, leftCol, rightCol)
  71. && isHorizontalLineSegment(bottomRow, leftCol, rightCol)
  72. && isVerticalLineSegment(leftCol, topRow, bottomRow)
  73. && isVerticalLineSegment(rightCol, topRow, bottomRow);
  74. }
  75. private boolean isHorizontalLineSegment(final int row, final int leftCol, final int rightCol) {
  76. return stream(copyOfRange(getRow(row), leftCol, rightCol))
  77. .allMatch(Tile::isHorizontalConnector);
  78. }
  79. private boolean isVerticalLineSegment(final int col, final int topRow, final int bottomRow) {
  80. return stream(copyOfRange(getCol(col), topRow, bottomRow))
  81. .allMatch(Tile::isVerticalConnector);
  82. }
  83. private Tile[] getRow(final int number) {
  84. return tiles[number];
  85. }
  86. private Tile[] getCol(final int number) {
  87. final Tile[] result = new Tile[nRows];
  88. for (int nRow = 0; nRow < nRows; nRow++) {
  89. result[nRow] = tiles[nRow][number];
  90. }
  91. return result;
  92. }
  93. }
  94. }