diff --git a/2022/08/part1.js b/2022/08/part1.js index b1b0c13..c8f6654 100644 --- a/2022/08/part1.js +++ b/2022/08/part1.js @@ -10,6 +10,12 @@ const readInput = (...args) => .filter((x) => x) .map((l) => l.split("").map((x) => parseInt(x))); +export const outOfBound = (size) => (pos) => { + if (Math.min(pos.x, pos.y) < 0) return true; + if (Math.max(pos.x, pos.y) >= size) return true; + return false; +}; + export function generateVisibilityGrid(forest) { const size = forest.length; const visibility = Array(size) @@ -47,17 +53,11 @@ export function generateVisibilityGrid(forest) { })) ); - const outOfBound = (pos) => { - if (Math.min(pos.x, pos.y) < 0) return true; - if (Math.max(pos.x, pos.y) >= size) return true; - return false; - }; - while (positions.length) { const pos = positions.shift(); pos.position.add(pos.inc); - if (outOfBound(pos.position)) continue; + if (outOfBound(size)(pos.position)) continue; if (forest[pos.position.x][pos.position.y] > pos.height) { visibility[pos.position.x][pos.position.y] = true; @@ -73,7 +73,7 @@ export function generateVisibilityGrid(forest) { export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); -function printMap(forest) { +export function printMap(forest) { forest.forEach((line) => console.log(line.join(" "))); return forest; } diff --git a/2022/08/part2.js b/2022/08/part2.js index 10fc179..53b599e 100644 --- a/2022/08/part2.js +++ b/2022/08/part2.js @@ -1,4 +1,50 @@ import * as R from "remeda"; +import memo from "memoizerific"; +import Victor from "@a-robu/victor"; +import { printMap, outOfBound } from "./part1"; -export default () => {}; +const V = (...args) => new Victor(...args); + +function visibility(forest, x, y, dx, dy) { + const pos = V(x, y); + const inc = V(dx, dy); + + let vis = 0; + + while (true) { + pos.add(inc); + if (outOfBound(forest.length)(pos)) return vis; + + if (forest[x][y] <= forest[pos.x][pos.y]) return 1 + vis; + vis++; + } +} + +const visibilityAround = (forest) => (x, y) => { + return [ + [0, 1], + [0, -1], + [1, 0], + [-1, 0], + ] + .map((d) => visibility(forest, x, y, ...d)) + .reduce((a, b) => a * b); +}; + +export default R.createPipe( + (forest) => { + const viz = Array(forest.length) + .fill(null) + .map(() => Array(forest.length).fill(0)); + + for (const x of R.range(0, forest.length)) { + for (const y of R.range(0, forest.length)) { + viz[x][y] = visibilityAround(forest)(x, y); + } + } + return viz; + }, + R.flatten, + R.maxBy(R.identity) +); diff --git a/2022/08/puzzle.md b/2022/08/puzzle.md index 45a66ba..3cbf273 100644 --- a/2022/08/puzzle.md +++ b/2022/08/puzzle.md @@ -1,9 +1,8 @@ -\--- Day 8: Treetop Tree House --- ----------- +## \--- Day 8: Treetop Tree House --- The expedition comes across a peculiar patch of tall trees all planted carefully in a grid. The Elves explain that a previous expedition planted these trees as a reforestation effort. Now, they're curious if this would be a good location for a [tree house](https://en.wikipedia.org/wiki/Tree_house). -First, determine whether there is enough tree cover here to keep a tree house *hidden*. To do this, you need to count the number of trees that are *visible from outside the grid* when looking directly along a row or column. +First, determine whether there is enough tree cover here to keep a tree house _hidden_. To do this, you need to count the number of trees that are _visible from outside the grid_ when looking directly along a row or column. The Elves have already launched a [quadcopter](https://en.wikipedia.org/wiki/Quadcopter) to generate a map with the height of each tree (your puzzle input). For example: @@ -18,24 +17,24 @@ The Elves have already launched a [quadcopter](https://en.wikipedia.org/wiki/Qua Each tree is represented as a single digit whose value is its height, where `0` is the shortest and `9` is the tallest. -A tree is *visible* if all of the other trees between it and an edge of the grid are *shorter* than it. Only consider trees in the same row or column; that is, only look up, down, left, or right from any given tree. +A tree is _visible_ if all of the other trees between it and an edge of the grid are _shorter_ than it. Only consider trees in the same row or column; that is, only look up, down, left, or right from any given tree. -All of the trees around the edge of the grid are *visible* - since they are already on the edge, there are no trees to block the view. In this example, that only leaves the *interior nine trees* to consider: +All of the trees around the edge of the grid are _visible_ - since they are already on the edge, there are no trees to block the view. In this example, that only leaves the _interior nine trees_ to consider: -* The top-left `5` is *visible* from the left and top. (It isn't visible from the right or bottom since other trees of height `5` are in the way.) -* The top-middle `5` is *visible* from the top and right. -* The top-right `1` is not visible from any direction; for it to be visible, there would need to only be trees of height *0* between it and an edge. -* The left-middle `5` is *visible*, but only from the right. -* The center `3` is not visible from any direction; for it to be visible, there would need to be only trees of at most height `2` between it and an edge. -* The right-middle `3` is *visible* from the right. -* In the bottom row, the middle `5` is *visible*, but the `3` and `4` are not. +- The top-left `5` is _visible_ from the left and top. (It isn't visible from the right or bottom since other trees of height `5` are in the way.) +- The top-middle `5` is _visible_ from the top and right. +- The top-right `1` is not visible from any direction; for it to be visible, there would need to only be trees of height _0_ between it and an edge. +- The left-middle `5` is _visible_, but only from the right. +- The center `3` is not visible from any direction; for it to be visible, there would need to be only trees of at most height `2` between it and an edge. +- The right-middle `3` is _visible_ from the right. +- In the bottom row, the middle `5` is _visible_, but the `3` and `4` are not. With 16 trees visible on the edge and another 5 visible in the interior, a total of `*21*` trees are visible in this arrangement. -Consider your map; *how many trees are visible from outside the grid?* +Consider your map; _how many trees are visible from outside the grid?_ To begin, [get your puzzle input](8/input). Answer: -You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=%22Treetop+Tree+House%22+%2D+Day+8+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F8&related=ericwastl&hashtags=AdventOfCode) [Mastodon](javascript:void(0);)] this puzzle. \ No newline at end of file +You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=%22Treetop+Tree+House%22+%2D+Day+8+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F8&related=ericwastl&hashtags=AdventOfCode) [Mastodon]()] this puzzle. diff --git a/2022/08/test.js b/2022/08/test.js index f1b2b98..37e84b4 100644 --- a/2022/08/test.js +++ b/2022/08/test.js @@ -1,21 +1,25 @@ import { test, expect, describe } from "vitest"; import { expectSolution } from "../01/main.js"; -import part1, { sample, puzzleInput, generateVisibilityGrid } from "./part1.js"; +import part1, { sample, puzzleInput } from "./part1.js"; import part2 from "./part2.js"; describe("part 1", () => { - test( "sample", () => { - expect( part1(sample) ).toBe(21); - - }); + test("sample", () => { + expect(part1(sample)).toBe(21); + }); test("solution", () => { expectSolution(part1(puzzleInput)).toEqual(1703); }); }); describe("part 2", () => { - test.todo("solution", () => { - expectSolution(part2(puzzleInput)).toEqual("TODO"); + test("sample", () => { + expect(part2(sample)).toBe(8); + }); + test("solution", () => { + const solution = part2(puzzleInput); + expect(solution).toBeGreaterThan(160); + expectSolution(solution).toEqual(496650); }); });