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

RectangleCounter.java 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 Entry {
  13. CORNER,
  14. HLINE,
  15. VLINE,
  16. SPACE;
  17. private static Entry fromChar(final char rawGridEntry) {
  18. switch (rawGridEntry) {
  19. case '+': return CORNER;
  20. case '-': return HLINE;
  21. case '|': return VLINE;
  22. case ' ': return SPACE;
  23. default: throw new IllegalStateException("Grid entry " + rawGridEntry + " not recognized.");
  24. }
  25. }
  26. }
  27. private int nRows, nCols;
  28. private final Entry[][] entries;
  29. private Grid(final int nRows, final int nCols, final String[] rawGrid) {
  30. this.nRows = nRows;
  31. this.nCols = nCols;
  32. this.entries = new Entry[nRows][nCols];
  33. for (int nRow = 0; nRow < nRows; nRow++) {
  34. for (int nCol = 0; nCol < nCols; nCol++) {
  35. entries[nRow][nCol] = Entry.fromChar(rawGrid[nRow].charAt(nCol));
  36. }
  37. }
  38. }
  39. private int countRectangles() {
  40. int result = 0;
  41. for (int topRow = 0; topRow < nRows - 1; topRow++) {
  42. for (int leftCol = 0; leftCol < nCols - 1; leftCol++) {
  43. // Only check rectangles that lie below/to the right of our current coordinate:
  44. for (int bottomRow = topRow + 1; bottomRow < nRows; bottomRow++) {
  45. for (int rightCol = leftCol + 1; rightCol < nCols; rightCol++) {
  46. if (formsRectangle(topRow, bottomRow, leftCol, rightCol)) {
  47. result++;
  48. }
  49. }
  50. }
  51. }
  52. }
  53. return result;
  54. }
  55. private boolean formsRectangle(
  56. final int topRow,
  57. final int bottomRow,
  58. final int leftCol,
  59. final int rightCol) {
  60. return entries[topRow][leftCol].equals(Entry.CORNER)
  61. && entries[topRow][rightCol].equals(Entry.CORNER)
  62. && entries[bottomRow][leftCol].equals(Entry.CORNER)
  63. && entries[bottomRow][rightCol].equals(Entry.CORNER)
  64. && isHorizontalLineSegment(topRow, leftCol, rightCol)
  65. && isHorizontalLineSegment(bottomRow, leftCol, rightCol)
  66. && isVerticalLineSegment(leftCol, topRow, bottomRow)
  67. && isVerticalLineSegment(rightCol, topRow, bottomRow);
  68. }
  69. private boolean isHorizontalLineSegment(final int row, final int leftCol, final int rightCol) {
  70. return stream(copyOfRange(getRow(row), leftCol, rightCol))
  71. .allMatch(entry -> entry.equals(Entry.HLINE) || entry.equals(Entry.CORNER));
  72. }
  73. private boolean isVerticalLineSegment(final int col, final int topRow, final int bottomRow) {
  74. return stream(copyOfRange(getCol(col), topRow, bottomRow))
  75. .allMatch(entry -> entry.equals(Entry.VLINE) || entry.equals(Entry.CORNER));
  76. }
  77. private Entry[] getRow(final int number) {
  78. return entries[number];
  79. }
  80. private Entry[] getCol(final int number) {
  81. final Entry[] result = new Entry[nRows];
  82. for (int nRow = 0; nRow < nRows; nRow++) {
  83. result[nRow] = entries[nRow][number];
  84. }
  85. return result;
  86. }
  87. }
  88. }