Advent of Code 2022: Day 8

После седьмого дня – решение восьмого было, в некотором роде, отдыхом. Хотя “усладой для глаз” его точно не назовёшь – вид оно имеет весьма портяночный.

Когда-то развлекался – делал “крестики-нолики” с полем свободного размера. И для среднего уровня сложности позиция следующего хода компьютера вычислялась сканированием этого самого поля.

Не то, чтобы это всё пригодилось мне в задаче восьмого дня. Но с тех пор, помучившись с отладкой, я крепко запомнил необходимость тщательной проверки границ массивов. Благодаря чему поймал 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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *