From f4bc47bc236a997e3a6787f0933e5f1096ac8f93 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 8 Dec 2022 10:15:42 -0500 Subject: [PATCH 1/7] hygen --- 2022/template/part1.js | 1 - 2022/template/part2.js | 1 - Taskfile.yaml | 6 ++++++ _templates/day/new/hello.ejs.t | 15 +++++++++++++++ _templates/day/new/part1.ejs | 6 ++++++ _templates/day/new/part2.ejs | 7 +++++++ _templates/day/new/prompt.js | 7 +++++++ .../test.js => _templates/day/new/test.ejs | 11 +++++++---- _templates/generator/help/index.ejs.t | 5 +++++ _templates/generator/new/hello.ejs.t | 18 ++++++++++++++++++ _templates/generator/with-prompt/hello.ejs.t | 18 ++++++++++++++++++ _templates/generator/with-prompt/prompt.ejs.t | 14 ++++++++++++++ _templates/init/repo/new-repo.ejs.t | 4 ++++ 13 files changed, 107 insertions(+), 6 deletions(-) delete mode 100644 2022/template/part1.js delete mode 100644 2022/template/part2.js create mode 100644 _templates/day/new/hello.ejs.t create mode 100644 _templates/day/new/part1.ejs create mode 100644 _templates/day/new/part2.ejs create mode 100644 _templates/day/new/prompt.js rename 2022/template/test.js => _templates/day/new/test.ejs (50%) create mode 100644 _templates/generator/help/index.ejs.t create mode 100644 _templates/generator/new/hello.ejs.t create mode 100644 _templates/generator/with-prompt/hello.ejs.t create mode 100644 _templates/generator/with-prompt/prompt.ejs.t create mode 100644 _templates/init/repo/new-repo.ejs.t diff --git a/2022/template/part1.js b/2022/template/part1.js deleted file mode 100644 index b509eb0..0000000 --- a/2022/template/part1.js +++ /dev/null @@ -1 +0,0 @@ -import * as R from "remeda"; diff --git a/2022/template/part2.js b/2022/template/part2.js deleted file mode 100644 index b509eb0..0000000 --- a/2022/template/part2.js +++ /dev/null @@ -1 +0,0 @@ -import * as R from "remeda"; diff --git a/Taskfile.yaml b/Taskfile.yaml index af75c42..eaa296d 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -6,6 +6,8 @@ vars: YEAR: 2022 DAY: sh: date '+%d' | perl -pe's/^0//' + DAY_FORMATTED: + sh: date '+%d' GREETING: Hello, World! tasks: @@ -25,6 +27,10 @@ tasks: cmds: - firefox https://adventofcode.com/{{.YEAR}}/day/{{.DAY}} + download: + cmds: + - aoc download -d {{.DAY}} -o -p 2022/{{.DAY_FORMATTED}}/puzzle.md -i 2022/{{.DAY_FORMATTED}}/input + default: cmds: - echo "{{.GREETING}}" diff --git a/_templates/day/new/hello.ejs.t b/_templates/day/new/hello.ejs.t new file mode 100644 index 0000000..095a04e --- /dev/null +++ b/_templates/day/new/hello.ejs.t @@ -0,0 +1,15 @@ +--- +to: app/hello.js +--- +const hello = ``` +Hello! +This is your first hygen template. + +Learn what it can do here: + +https://github.com/jondot/hygen +``` + +console.log(hello) + + diff --git a/_templates/day/new/part1.ejs b/_templates/day/new/part1.ejs new file mode 100644 index 0000000..97460f5 --- /dev/null +++ b/_templates/day/new/part1.ejs @@ -0,0 +1,6 @@ +--- +to: 2022/<%= day %>/part1.js +--- +import * as R from "remeda"; + +export default = () => {}; diff --git a/_templates/day/new/part2.ejs b/_templates/day/new/part2.ejs new file mode 100644 index 0000000..e59c761 --- /dev/null +++ b/_templates/day/new/part2.ejs @@ -0,0 +1,7 @@ +--- +to: 2022/<%= day %>/part2.js +--- +import * as R from "remeda"; + + +export default = () => {}; diff --git a/_templates/day/new/prompt.js b/_templates/day/new/prompt.js new file mode 100644 index 0000000..bfff832 --- /dev/null +++ b/_templates/day/new/prompt.js @@ -0,0 +1,7 @@ +module.exports = [ + { + type: 'input', + name: 'day', + message: "advent day?" + } +] diff --git a/2022/template/test.js b/_templates/day/new/test.ejs similarity index 50% rename from 2022/template/test.js rename to _templates/day/new/test.ejs index 07ae1e1..f82ac18 100644 --- a/2022/template/test.js +++ b/_templates/day/new/test.ejs @@ -1,17 +1,20 @@ +--- +to: 2022/<%= day %>/test.js +--- import { test, expect, describe } from "vitest"; import { expectSolution } from "../01/main.js"; -import { solutionPart1, puzzleInput } from "./part1.js"; -import { solutionPart2 } from "./part2.js"; +import part1, { sample, puzzleInput } from "./part1.js"; +import part2 from "./part2.js"; describe("part 1", () => { test.todo("solution", () => { - expectSolution(solutionPart1(puzzleInput)).toEqual("TODO"); + expectSolution(part1(puzzleInput)).toEqual("TODO"); }); }); describe("part 2", () => { test.todo("solution", () => { - expectSolution(solutionPart2(puzzleInput)).toEqual("TODO"); + expectSolution(part2(puzzleInput)).toEqual("TODO"); }); }); diff --git a/_templates/generator/help/index.ejs.t b/_templates/generator/help/index.ejs.t new file mode 100644 index 0000000..90a29af --- /dev/null +++ b/_templates/generator/help/index.ejs.t @@ -0,0 +1,5 @@ +--- +message: | + hygen {bold generator new} --name [NAME] --action [ACTION] + hygen {bold generator with-prompt} --name [NAME] --action [ACTION] +--- \ No newline at end of file diff --git a/_templates/generator/new/hello.ejs.t b/_templates/generator/new/hello.ejs.t new file mode 100644 index 0000000..5680d96 --- /dev/null +++ b/_templates/generator/new/hello.ejs.t @@ -0,0 +1,18 @@ +--- +to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t +--- +--- +to: app/hello.js +--- +const hello = ``` +Hello! +This is your first hygen template. + +Learn what it can do here: + +https://github.com/jondot/hygen +``` + +console.log(hello) + + diff --git a/_templates/generator/with-prompt/hello.ejs.t b/_templates/generator/with-prompt/hello.ejs.t new file mode 100644 index 0000000..ba6abc5 --- /dev/null +++ b/_templates/generator/with-prompt/hello.ejs.t @@ -0,0 +1,18 @@ +--- +to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t +--- +--- +to: app/hello.js +--- +const hello = ``` +Hello! +This is your first prompt based hygen template. + +Learn what it can do here: + +https://github.com/jondot/hygen +``` + +console.log(hello) + + diff --git a/_templates/generator/with-prompt/prompt.ejs.t b/_templates/generator/with-prompt/prompt.ejs.t new file mode 100644 index 0000000..76ea532 --- /dev/null +++ b/_templates/generator/with-prompt/prompt.ejs.t @@ -0,0 +1,14 @@ +--- +to: _templates/<%= name %>/<%= action || 'new' %>/prompt.js +--- + +// see types of prompts: +// https://github.com/enquirer/enquirer/tree/master/examples +// +module.exports = [ + { + type: 'input', + name: 'message', + message: "What's your message?" + } +] diff --git a/_templates/init/repo/new-repo.ejs.t b/_templates/init/repo/new-repo.ejs.t new file mode 100644 index 0000000..08e7cff --- /dev/null +++ b/_templates/init/repo/new-repo.ejs.t @@ -0,0 +1,4 @@ +--- +setup: <%= name %> +force: true # this is because mostly, people init into existing folders is safe +--- From ff4203a58fe6e69f334af77c07260b23a41946ef Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 8 Dec 2022 11:15:24 -0500 Subject: [PATCH 2/7] part 1 --- 2022/08/part1.js | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 2022/08/part2.js | 4 +++ 2022/08/sample | 5 +++ 2022/08/test.js | 21 ++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 2022/08/part1.js create mode 100644 2022/08/part2.js create mode 100644 2022/08/sample create mode 100644 2022/08/test.js diff --git a/2022/08/part1.js b/2022/08/part1.js new file mode 100644 index 0000000..5d9cffd --- /dev/null +++ b/2022/08/part1.js @@ -0,0 +1,87 @@ +import * as R from "remeda"; +import { readFile } from "../05/part1.js"; +import Victor from '@a-robu/victor'; + +const V = (...args) => new Victor(...args); + +const readInput = (...args) => + readFile(...args) + .split("\n") + .filter((x) => x) + .map( l => l.split('').map( x => parseInt(x) ) ); + +export function generateVisibilityGrid(forest) { + const size = forest.length; + const visibility = Array(size).fill(null).map( + () => Array(size).fill(false) + ); + + // top + const positions = R.range(size)(0).map( x => ({ + height: -1, + position: V(x,-1), + inc: V(0,1), + }) ); + + // bottom + positions.push( +...R.range(size)(0).map( x => ({ + height: -1, + position: V(x,size), + inc: V(0,-1), + }) ) + ); + + positions.push( +...R.range(size)(0).map( x => ({ + height: -1, + position: V(-1,x), + inc: V(1,0), + }) ) + ); + positions.push( +...R.range(size)(0).map( x => ({ + height: -1, + position: V(size,x), + inc: V(-1,0), + }) ) + ); + + 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( forest[pos.position.x][pos.position.y] > pos.height ) { + visibility[pos.position.x][pos.position.y] = true; + pos.height = forest[pos.position.x][pos.position.y]; + } + + positions.push(pos); + } + + return visibility; +} + +export const puzzleInput = readInput(import.meta.url, "input"); +export const sample = readInput(import.meta.url, "sample"); + +function printMap( forest ) { + forest.forEach( line => console.log(line.join(' ')) ); + return forest; +} + +export default R.createPipe( + printMap, + generateVisibilityGrid, + printMap, + R.flatten, + R.countBy(R.identity) +); diff --git a/2022/08/part2.js b/2022/08/part2.js new file mode 100644 index 0000000..10fc179 --- /dev/null +++ b/2022/08/part2.js @@ -0,0 +1,4 @@ +import * as R from "remeda"; + + +export default () => {}; diff --git a/2022/08/sample b/2022/08/sample new file mode 100644 index 0000000..16d6fbd --- /dev/null +++ b/2022/08/sample @@ -0,0 +1,5 @@ +30373 +25512 +65332 +33549 +35390 diff --git a/2022/08/test.js b/2022/08/test.js new file mode 100644 index 0000000..f1b2b98 --- /dev/null +++ b/2022/08/test.js @@ -0,0 +1,21 @@ +import { test, expect, describe } from "vitest"; + +import { expectSolution } from "../01/main.js"; +import part1, { sample, puzzleInput, generateVisibilityGrid } from "./part1.js"; +import part2 from "./part2.js"; + +describe("part 1", () => { + 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"); + }); +}); From 94fc825a0bba7f5f9737908cdfba40db8b3ee911 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 8 Dec 2022 11:18:50 -0500 Subject: [PATCH 3/7] prettier --- 2022/08/part1.js | 120 +++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/2022/08/part1.js b/2022/08/part1.js index 5d9cffd..3c7377f 100644 --- a/2022/08/part1.js +++ b/2022/08/part1.js @@ -1,6 +1,6 @@ import * as R from "remeda"; import { readFile } from "../05/part1.js"; -import Victor from '@a-robu/victor'; +import Victor from "@a-robu/victor"; const V = (...args) => new Victor(...args); @@ -8,80 +8,80 @@ const readInput = (...args) => readFile(...args) .split("\n") .filter((x) => x) - .map( l => l.split('').map( x => parseInt(x) ) ); + .map((l) => l.split("").map((x) => parseInt(x))); export function generateVisibilityGrid(forest) { - const size = forest.length; - const visibility = Array(size).fill(null).map( - () => Array(size).fill(false) - ); + const size = forest.length; + const visibility = Array(size) + .fill(null) + .map(() => Array(size).fill(false)); - // top - const positions = R.range(size)(0).map( x => ({ - height: -1, - position: V(x,-1), - inc: V(0,1), - }) ); + // top + const positions = R.range(size)(0).map((x) => ({ + height: -1, + position: V(x, -1), + inc: V(0, 1), + })); - // bottom - positions.push( -...R.range(size)(0).map( x => ({ - height: -1, - position: V(x,size), - inc: V(0,-1), - }) ) - ); + // bottom + positions.push( + ...R.range(size)(0).map((x) => ({ + height: -1, + position: V(x, size), + inc: V(0, -1), + })) + ); - positions.push( -...R.range(size)(0).map( x => ({ - height: -1, - position: V(-1,x), - inc: V(1,0), - }) ) - ); - positions.push( -...R.range(size)(0).map( x => ({ - height: -1, - position: V(size,x), - inc: V(-1,0), - }) ) - ); + positions.push( + ...R.range(size)(0).map((x) => ({ + height: -1, + position: V(-1, x), + inc: V(1, 0), + })) + ); + positions.push( + ...R.range(size)(0).map((x) => ({ + height: -1, + position: V(size, x), + inc: V(-1, 0), + })) + ); - 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; + 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 (forest[pos.position.x][pos.position.y] > pos.height) { + visibility[pos.position.x][pos.position.y] = true; + pos.height = forest[pos.position.x][pos.position.y]; } - while( positions.length ) { - const pos = positions.shift(); - pos.position.add( pos.inc ); + positions.push(pos); + } - if( outOfBound( pos.position ) ) continue; - - if( forest[pos.position.x][pos.position.y] > pos.height ) { - visibility[pos.position.x][pos.position.y] = true; - pos.height = forest[pos.position.x][pos.position.y]; - } - - positions.push(pos); - } - - return visibility; + return visibility; } export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); -function printMap( forest ) { - forest.forEach( line => console.log(line.join(' ')) ); - return forest; +function printMap(forest) { + forest.forEach((line) => console.log(line.join(" "))); + return forest; } export default R.createPipe( - printMap, - generateVisibilityGrid, - printMap, - R.flatten, - R.countBy(R.identity) + printMap, + generateVisibilityGrid, + printMap, + R.flatten, + R.countBy(R.identity) ); From 8959352c9bf33f331d94ec33d4de363d483a126c Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 8 Dec 2022 11:19:09 -0500 Subject: [PATCH 4/7] remove maps --- 2022/08/part1.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/2022/08/part1.js b/2022/08/part1.js index 3c7377f..b1b0c13 100644 --- a/2022/08/part1.js +++ b/2022/08/part1.js @@ -79,9 +79,7 @@ function printMap(forest) { } export default R.createPipe( - printMap, generateVisibilityGrid, - printMap, R.flatten, R.countBy(R.identity) ); From 6bcdb14d266364888803896a06f9c8cf489a69c8 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 8 Dec 2022 16:19:44 -0500 Subject: [PATCH 5/7] prettier --- 2022/08/part1.js | 16 ++++++++-------- 2022/08/part2.js | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2022/08/test.js | 18 +++++++++++------- 3 files changed, 66 insertions(+), 16 deletions(-) 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/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); }); }); From e38aec3c6951666dad8354c0d7fd1ee14601ec4a Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 8 Dec 2022 16:20:07 -0500 Subject: [PATCH 6/7] add dependency --- _templates/day/new/part1.ejs | 10 ++++++++++ package.json | 2 ++ 2 files changed, 12 insertions(+) diff --git a/_templates/day/new/part1.ejs b/_templates/day/new/part1.ejs index 97460f5..14531b0 100644 --- a/_templates/day/new/part1.ejs +++ b/_templates/day/new/part1.ejs @@ -3,4 +3,14 @@ to: 2022/<%= day %>/part1.js --- import * as R from "remeda"; +import { readFile } from "../05/part1.js"; + +const readInput = (...args) => + readFile(...args) + .split("\n") + .filter((x) => x); + +export const puzzleInput = readInput(import.meta.url, "input"); +export const sample = readInput(import.meta.url, "sample"); + export default = () => {}; diff --git a/package.json b/package.json index c1baac4..232dcb9 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "author": "Yanick Champoux (http://techblog.babyl.ca/)", "license": "ISC", "dependencies": { + "@a-robu/victor": "^2.2.2", "debug": "^4.3.4", "fs-extra": "^11.1.0", + "memoizerific": "^1.11.3", "prettier": "^2.8.0", "remeda": "^1.3.0", "vitest": "^0.25.3" From 03a0bc78364cabf2d7791530ed1aa1ed53336a55 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 8 Dec 2022 16:27:32 -0500 Subject: [PATCH 7/7] prettier --- 2022/08/part1.js | 12 ++++++++---- 2022/08/part2.js | 20 +++++--------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/2022/08/part1.js b/2022/08/part1.js index c8f6654..34dd036 100644 --- a/2022/08/part1.js +++ b/2022/08/part1.js @@ -73,10 +73,14 @@ export function generateVisibilityGrid(forest) { export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); -export function printMap(forest) { - forest.forEach((line) => console.log(line.join(" "))); - return forest; -} +export const passthru = (func) => (arg) => { + func(arg); + return arg; +}; + +export const printMap = passthru((forest) => + forest.forEach((line) => console.log(line.join(" "))) +); export default R.createPipe( generateVisibilityGrid, diff --git a/2022/08/part2.js b/2022/08/part2.js index 53b599e..061879c 100644 --- a/2022/08/part2.js +++ b/2022/08/part2.js @@ -1,8 +1,7 @@ import * as R from "remeda"; -import memo from "memoizerific"; import Victor from "@a-robu/victor"; -import { printMap, outOfBound } from "./part1"; +import { outOfBound } from "./part1"; const V = (...args) => new Victor(...args); @@ -21,8 +20,8 @@ function visibility(forest, x, y, dx, dy) { } } -const visibilityAround = (forest) => (x, y) => { - return [ +const visibilityAround = (forest) => (x, y) => + [ [0, 1], [0, -1], [1, 0], @@ -30,20 +29,11 @@ const visibilityAround = (forest) => (x, y) => { ] .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; + const va = visibilityAround(forest); + return forest.map((l, x) => l.map((_, y) => va(x, y))); }, R.flatten, R.maxBy(R.identity)