После седьмого дня — решение восьмого было, в некотором роде, отдыхом. Хотя «усладой для глаз» его точно не назовёшь — вид оно имеет весьма портяночный.
Когда-то развлекался — делал «крестики-нолики» с полем свободного размера. И для среднего уровня сложности позиция следующего хода компьютера вычислялась сканированием этого самого поля.
Не то, чтобы это всё пригодилось мне в задаче восьмого дня. Но с тех пор, помучившись с отладкой, я крепко запомнил необходимость тщательной проверки границ массивов. Благодаря чему поймал ArrayIndexOutOfBoundsException
лишь единожды ¯\_(ツ)_/¯.
static void day8(String puzzleInputUri) throws IOException, InterruptedException {
int[][] forest = client.send(
request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()
).body()
.map(line -> line.chars().map(cCode -> cCode - '0').toArray())
.toArray(int[][]::new);
int mapHeight = forest.length;
int mapWidth = forest[0].length;
AtomicInteger visibilityCount = new AtomicInteger(mapWidth * mapHeight);
TreeSet<Integer> scenicScores = new TreeSet<>();
for (int j = 1; j < mapHeight - 1; j++) { //j down
for (int i = 1; i < mapWidth - 1; i++) { //i ->
List<Boolean> visibilities = new ArrayList<>();
int scenicScore = 1;
//look left
for (int k = i - 1; k >= 0; k--) {
if (forest[j][k] >= forest[j][i]) {
visibilities.add(false);
scenicScore *= (i - k);
break;
} else if (k == 0) {
visibilities.add(true);
scenicScore *= i;
}
}
//look right
for (int k = i + 1; k < mapWidth; k++) {
if (forest[j][k] >= forest[j][i]) {
visibilities.add(false);
scenicScore *= (k - i);
break;
} else if (k == mapWidth - 1) {
visibilities.add(true);
scenicScore *= (mapWidth - 1) - i;
}
}
//look top
for (int k = j - 1; k >= 0; k--) {
if (forest[k][i] >= forest[j][i]) {
visibilities.add(false);
scenicScore *= (j - k);
break;
} else if (k == 0) {
visibilities.add(true);
scenicScore *= j;
}
}
//look bottom
for (int k = j + 1; k < mapHeight; k++) {
if (forest[k][i] >= forest[j][i]) {
visibilities.add(false);
scenicScore *= (k - j);
break;
} else if (k == (mapHeight - 1)) {
visibilities.add(true);
scenicScore *= (mapHeight - 1) - j;
}
}
visibilities.stream().reduce(Boolean::logicalOr).ifPresent(isVisible -> {
if (!isVisible) visibilityCount.decrementAndGet();
});
scenicScores.add(scenicScore);
}
}
System.out.println(visibilityCount);
System.out.println(scenicScores.last());
}
Исходные данные: https://adventofcode.com/2022/day/8/input