Public
Edited
Dec 8, 2022
Insert cell
Insert cell
Insert cell
parse = input => input.split('\n').map( r => r.split('').map( n => parseInt(n) ) )
Insert cell
parse(testInput)
Insert cell
treesNorth = ( grid, x, y ) => {
const trees = [];
for ( let i = y - 1; i >= 0; i-- ) trees.push( grid[i][x] );
return trees;
}
Insert cell
treesSouth = ( grid, x, y ) => {
const height = grid.length;
const trees = [];
for ( let i = y + 1; i < height; i++ ) trees.push( grid[i][x] );
return trees;
}
Insert cell
treesEast = ( grid, x, y ) => {
const width = grid[0].length;
const trees = [];
for ( let i = x + 1; i < width; i++ ) trees.push( grid[y][i] );
return trees;
}
Insert cell
treesWest = ( grid, x, y ) => {
const trees = [];
for ( let i = x - 1; i >= 0; i-- ) trees.push( grid[y][i] );
return trees;
}
Insert cell
treesNorth(parse(testInput), 2, 2)
Insert cell
treesNorth(parse(testInput), 0, 0)
Insert cell
treesWest(parse(testInput), 2, 1)
Insert cell
isHidden = ( height ) => ( otherTree ) => otherTree >= height;
Insert cell
isVisible = (grid, x, y) => {
const height = grid[y][x];
// Could do an edge check here to speed things up, but it would probably be faster to do 4 passes through the whole grid and count the visible trees that way
const treeIsHidden = isHidden(height);
return [
treesNorth(grid, x, y).some(treeIsHidden),
treesSouth(grid, x, y).some(treeIsHidden),
treesEast(grid, x, y).some(treeIsHidden),
treesWest(grid, x, y).some(treeIsHidden)
].some((v) => !v);
}
Insert cell
isVisible(parse(testInput), 2, 2)
Insert cell
isVisible(parse(testInput), 2, 1)
Insert cell
part1 = input => {
const grid = parse(input);
let count = 0;
for ( let i = 0; i < grid.length; i++ ) {
for ( let j = 0; j < grid[i].length; j++ ) {
if ( isVisible(grid, j, i ) ) count++;
}
}
return count;
}
Insert cell
part1(testInput)
Insert cell
Insert cell
part1(input)
Insert cell
visibleTrees = (trees, height) => {
if (trees[0] >= height) return [trees[0]];
const visible = [];
for (let i = 0; i < trees.length; i++) {
if (trees[i] < height) {
visible.push(trees[i]);
} else if (trees[i] >= height) {
visible.push(trees[i]);
break;
} else {
break;
}
}
return visible;
}
Insert cell
testGrid = parse(testInput)
Insert cell
testGrid[3][2]
Insert cell
visibleTrees(treesNorth(testGrid, 2, 3), 5)
Insert cell
visibleTrees(treesWest(testGrid, 2, 3), 5)
Insert cell
visibleTrees(treesEast(testGrid, 2, 3), 5)
Insert cell
visibleTrees(treesSouth(testGrid, 2, 3), 5)
Insert cell
scenicScore = (grid, x, y) => {
const height = grid[y][x];
return (
visibleTrees(treesNorth(grid, x, y), height).length *
visibleTrees(treesEast(grid, x, y), height).length *
visibleTrees(treesSouth(grid, x, y), height).length *
visibleTrees(treesWest(grid, x, y), height).length
);
}
Insert cell
scenicScore(parse(testInput),2,1)
Insert cell
scenicScore(parse(testInput), 2, 3)
Insert cell
part2 = (input) => {
const grid = parse(input);
let best = 0;
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[i].length; j++) {
const score = scenicScore(grid, j, i);
if (score > best) best = score;
}
}
return best;
}
Insert cell
part2(testInput)
Insert cell
part2(input)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more