Merge branch '2022-08'
This commit is contained in:
commit
cb4d586ca1
@ -5,3 +5,4 @@ sample
|
|||||||
input
|
input
|
||||||
*.t
|
*.t
|
||||||
*.pm
|
*.pm
|
||||||
|
*.ejs
|
||||||
|
89
2022/08/part1.js
Normal file
89
2022/08/part1.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
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 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)
|
||||||
|
.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),
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
while (positions.length) {
|
||||||
|
const pos = positions.shift();
|
||||||
|
pos.position.add(pos.inc);
|
||||||
|
|
||||||
|
if (outOfBound(size)(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");
|
||||||
|
|
||||||
|
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,
|
||||||
|
R.flatten,
|
||||||
|
R.countBy(R.identity)
|
||||||
|
);
|
40
2022/08/part2.js
Normal file
40
2022/08/part2.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import * as R from "remeda";
|
||||||
|
import Victor from "@a-robu/victor";
|
||||||
|
|
||||||
|
import { outOfBound } from "./part1";
|
||||||
|
|
||||||
|
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) =>
|
||||||
|
[
|
||||||
|
[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 va = visibilityAround(forest);
|
||||||
|
return forest.map((l, x) => l.map((_, y) => va(x, y)));
|
||||||
|
},
|
||||||
|
R.flatten,
|
||||||
|
R.maxBy(R.identity)
|
||||||
|
);
|
5
2022/08/sample
Normal file
5
2022/08/sample
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
30373
|
||||||
|
25512
|
||||||
|
65332
|
||||||
|
33549
|
||||||
|
35390
|
25
2022/08/test.js
Normal file
25
2022/08/test.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { test, expect, describe } from "vitest";
|
||||||
|
|
||||||
|
import { expectSolution } from "../01/main.js";
|
||||||
|
import part1, { sample, puzzleInput } 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("sample", () => {
|
||||||
|
expect(part2(sample)).toBe(8);
|
||||||
|
});
|
||||||
|
test("solution", () => {
|
||||||
|
const solution = part2(puzzleInput);
|
||||||
|
expect(solution).toBeGreaterThan(160);
|
||||||
|
expectSolution(solution).toEqual(496650);
|
||||||
|
});
|
||||||
|
});
|
@ -1 +0,0 @@
|
|||||||
import * as R from "remeda";
|
|
@ -1 +0,0 @@
|
|||||||
import * as R from "remeda";
|
|
@ -6,6 +6,8 @@ vars:
|
|||||||
YEAR: 2022
|
YEAR: 2022
|
||||||
DAY:
|
DAY:
|
||||||
sh: date '+%d' | perl -pe's/^0//'
|
sh: date '+%d' | perl -pe's/^0//'
|
||||||
|
DAY_FORMATTED:
|
||||||
|
sh: date '+%d'
|
||||||
GREETING: Hello, World!
|
GREETING: Hello, World!
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
@ -25,6 +27,10 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- firefox https://adventofcode.com/{{.YEAR}}/day/{{.DAY}}
|
- 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:
|
default:
|
||||||
cmds:
|
cmds:
|
||||||
- echo "{{.GREETING}}"
|
- echo "{{.GREETING}}"
|
||||||
|
15
_templates/day/new/hello.ejs.t
Normal file
15
_templates/day/new/hello.ejs.t
Normal file
@ -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)
|
||||||
|
|
||||||
|
|
16
_templates/day/new/part1.ejs
Normal file
16
_templates/day/new/part1.ejs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
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 = () => {};
|
7
_templates/day/new/part2.ejs
Normal file
7
_templates/day/new/part2.ejs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
to: 2022/<%= day %>/part2.js
|
||||||
|
---
|
||||||
|
import * as R from "remeda";
|
||||||
|
|
||||||
|
|
||||||
|
export default = () => {};
|
7
_templates/day/new/prompt.js
Normal file
7
_templates/day/new/prompt.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'day',
|
||||||
|
message: "advent day?"
|
||||||
|
}
|
||||||
|
]
|
@ -1,17 +1,20 @@
|
|||||||
|
---
|
||||||
|
to: 2022/<%= day %>/test.js
|
||||||
|
---
|
||||||
import { test, expect, describe } from "vitest";
|
import { test, expect, describe } from "vitest";
|
||||||
|
|
||||||
import { expectSolution } from "../01/main.js";
|
import { expectSolution } from "../01/main.js";
|
||||||
import { solutionPart1, puzzleInput } from "./part1.js";
|
import part1, { sample, puzzleInput } from "./part1.js";
|
||||||
import { solutionPart2 } from "./part2.js";
|
import part2 from "./part2.js";
|
||||||
|
|
||||||
describe("part 1", () => {
|
describe("part 1", () => {
|
||||||
test.todo("solution", () => {
|
test.todo("solution", () => {
|
||||||
expectSolution(solutionPart1(puzzleInput)).toEqual("TODO");
|
expectSolution(part1(puzzleInput)).toEqual("TODO");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("part 2", () => {
|
describe("part 2", () => {
|
||||||
test.todo("solution", () => {
|
test.todo("solution", () => {
|
||||||
expectSolution(solutionPart2(puzzleInput)).toEqual("TODO");
|
expectSolution(part2(puzzleInput)).toEqual("TODO");
|
||||||
});
|
});
|
||||||
});
|
});
|
5
_templates/generator/help/index.ejs.t
Normal file
5
_templates/generator/help/index.ejs.t
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
message: |
|
||||||
|
hygen {bold generator new} --name [NAME] --action [ACTION]
|
||||||
|
hygen {bold generator with-prompt} --name [NAME] --action [ACTION]
|
||||||
|
---
|
18
_templates/generator/new/hello.ejs.t
Normal file
18
_templates/generator/new/hello.ejs.t
Normal file
@ -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)
|
||||||
|
|
||||||
|
|
18
_templates/generator/with-prompt/hello.ejs.t
Normal file
18
_templates/generator/with-prompt/hello.ejs.t
Normal file
@ -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)
|
||||||
|
|
||||||
|
|
14
_templates/generator/with-prompt/prompt.ejs.t
Normal file
14
_templates/generator/with-prompt/prompt.ejs.t
Normal file
@ -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?"
|
||||||
|
}
|
||||||
|
]
|
4
_templates/init/repo/new-repo.ejs.t
Normal file
4
_templates/init/repo/new-repo.ejs.t
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
setup: <%= name %>
|
||||||
|
force: true # this is because mostly, people init into existing folders is safe
|
||||||
|
---
|
@ -10,8 +10,10 @@
|
|||||||
"author": "Yanick Champoux <yanick@babyl.ca> (http://techblog.babyl.ca/)",
|
"author": "Yanick Champoux <yanick@babyl.ca> (http://techblog.babyl.ca/)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@a-robu/victor": "^2.2.2",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"fs-extra": "^11.1.0",
|
"fs-extra": "^11.1.0",
|
||||||
|
"memoizerific": "^1.11.3",
|
||||||
"prettier": "^2.8.0",
|
"prettier": "^2.8.0",
|
||||||
"remeda": "^1.3.0",
|
"remeda": "^1.3.0",
|
||||||
"vitest": "^0.25.3"
|
"vitest": "^0.25.3"
|
||||||
|
Loading…
Reference in New Issue
Block a user