Compare commits
11 Commits
3ad67df338
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d54a107d4 | |||
| 9fc38b9b88 | |||
| 2c3c1f8f08 | |||
| da579fbfac | |||
| 4137cef6f9 | |||
| 1e405e982a | |||
| e3988e91b7 | |||
| 07b36d66d5 | |||
| 888f40d341 | |||
| 33a8ce77e4 | |||
| ed88c69cea |
@@ -7,7 +7,8 @@
|
|||||||
"shell": "npm run build && firebase functions:shell",
|
"shell": "npm run build && firebase functions:shell",
|
||||||
"start": "npm run shell",
|
"start": "npm run shell",
|
||||||
"deploy": "firebase deploy --only functions",
|
"deploy": "firebase deploy --only functions",
|
||||||
"logs": "firebase functions:log"
|
"logs": "firebase functions:log",
|
||||||
|
"debug-day17": "ts-node src/day17.ts"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16"
|
"node": "16"
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
"eslint-config-google": "^0.14.0",
|
"eslint-config-google": "^0.14.0",
|
||||||
"eslint-plugin-import": "^2.22.0",
|
"eslint-plugin-import": "^2.22.0",
|
||||||
"firebase-functions-test": "^0.2.0",
|
"firebase-functions-test": "^0.2.0",
|
||||||
|
"ts-node": "^10.4.0",
|
||||||
"typescript": "^3.8.0"
|
"typescript": "^3.8.0"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
|
|||||||
94
functions/src/Grid.ts
Normal file
94
functions/src/Grid.ts
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import Vector2 from "./vector2";
|
||||||
|
|
||||||
|
class Grid<T> {
|
||||||
|
|
||||||
|
data: T[];
|
||||||
|
outOfBoundsResult?: T;
|
||||||
|
maxX: number;
|
||||||
|
maxY: number;
|
||||||
|
|
||||||
|
constructor(data: T[], maxX: number, outOfBoundsResult: T | undefined = undefined) {
|
||||||
|
|
||||||
|
if (data.length % maxX !== 0) throw Error("Invalid grid data length, must be a multiple of the width");
|
||||||
|
|
||||||
|
this.data = data;
|
||||||
|
this.outOfBoundsResult = outOfBoundsResult;
|
||||||
|
this.maxX = maxX;
|
||||||
|
this.maxY = this.data.length / maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
at(x: number, y: number): T {
|
||||||
|
|
||||||
|
if (!this.isInBounds(x, y)) {
|
||||||
|
if (this.outOfBoundsResult) {
|
||||||
|
return this.outOfBoundsResult
|
||||||
|
} else {
|
||||||
|
throw Error(`Invalid coordinate: (${x}, ${y})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.data[this.index(x, y)];
|
||||||
|
}
|
||||||
|
|
||||||
|
setAt(x: number, y: number, value: T): void {
|
||||||
|
|
||||||
|
if (!this.isInBounds(x, y)) {
|
||||||
|
throw Error(`Invalid coordinate: (${x}, ${y})`);
|
||||||
|
}
|
||||||
|
this.data[this.index(x, y)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
allPositions(): Vector2[] {
|
||||||
|
const res =[];
|
||||||
|
for (let y = 0; y < this.maxY; y++) {
|
||||||
|
for (let x = 0; x < this.maxX; x++) {
|
||||||
|
res.push(new Vector2(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
isInBounds(x: number, y: number): boolean {
|
||||||
|
return x >= 0 && x < this.maxX && y >= 0 && y < this.maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
inBoundsNeighbors(x: number, y: number, includeDiagonal = false): Vector2[] {
|
||||||
|
|
||||||
|
const res = [
|
||||||
|
new Vector2(x + 1, y),
|
||||||
|
new Vector2(x - 1, y),
|
||||||
|
new Vector2(x, y + 1),
|
||||||
|
new Vector2(x, y - 1)
|
||||||
|
];
|
||||||
|
if (includeDiagonal) {
|
||||||
|
res.push(
|
||||||
|
new Vector2(x + 1, y + 1),
|
||||||
|
new Vector2(x + 1, y - 1),
|
||||||
|
new Vector2(x - 1, y + 1),
|
||||||
|
new Vector2(x - 1, y - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return res.filter(v => this.isInBounds(v.x, v.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pastes the given grid into this grid, with it's top left position at the given coordinate
|
||||||
|
*/
|
||||||
|
paste(grid: Grid<T>, posX: number, posY: number): void {
|
||||||
|
|
||||||
|
if (posX + grid.maxX > this.maxX || posY + grid.maxY > this.maxY) throw Error(`Can't paste grid at (${posX}, ${posY}), this grid is not big enough`);
|
||||||
|
|
||||||
|
for (let y = 0; y < grid.maxY; y++) {
|
||||||
|
for (let x = 0; x < grid.maxX; x++) {
|
||||||
|
this.setAt(posX + x, posY + y, grid.at(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index(x: number, y: number): number {
|
||||||
|
return x + y * this.maxX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Grid;
|
||||||
128
functions/src/day11.ts
Normal file
128
functions/src/day11.ts
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import Day from "./day";
|
||||||
|
|
||||||
|
class Day11 implements Day {
|
||||||
|
|
||||||
|
part1(input: string[]): number | string {
|
||||||
|
|
||||||
|
const grid = OctopusGrid.parse(input);
|
||||||
|
|
||||||
|
let flashTotal = 0;
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
flashTotal += grid.runStep();
|
||||||
|
}
|
||||||
|
return flashTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
part2(input: string[]): number | string {
|
||||||
|
const grid = OctopusGrid.parse(input);
|
||||||
|
|
||||||
|
let lastFlash = 0;
|
||||||
|
let step = 0;
|
||||||
|
while(lastFlash !== 100) {
|
||||||
|
lastFlash = grid.runStep();
|
||||||
|
step++;
|
||||||
|
}
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class OctopusGrid {
|
||||||
|
grid: number[];
|
||||||
|
maxX: number;
|
||||||
|
maxY: number;
|
||||||
|
|
||||||
|
constructor(grid: number[], width: number) {
|
||||||
|
|
||||||
|
this.grid = grid;
|
||||||
|
this.maxX = width;
|
||||||
|
this.maxY = grid.length / width;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static parse(input: string[]): OctopusGrid {
|
||||||
|
|
||||||
|
const grid = input.map(l => l.split("").map(s => parseInt(s)))
|
||||||
|
.reduce((a, b) => [...a, ...b])
|
||||||
|
const width = input[0].length;
|
||||||
|
|
||||||
|
return new OctopusGrid(grid, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
runStep(): number {
|
||||||
|
|
||||||
|
// First, the energy level of each octopus increases by 1.
|
||||||
|
this.grid = this.grid.map(o => o + 1);
|
||||||
|
|
||||||
|
// Then, any octopus with an energy level greater than 9 flashes. This increases the energy level of all adjacent
|
||||||
|
// octopuses by 1, including octopuses that are diagonally adjacent. If this causes an octopus to have an energy
|
||||||
|
// level greater than 9, it also flashes. This process continues as long as new octopuses keep having their energy
|
||||||
|
// level increased beyond 9. (An octopus can only flash at most once per step.)
|
||||||
|
const flashGrid = Array(this.grid.length).fill(false);
|
||||||
|
|
||||||
|
for (let y = 0; y < this.maxY; y++) {
|
||||||
|
for (let x = 0; x < this.maxX; x++) {
|
||||||
|
const i = this.index(x, y);
|
||||||
|
const cur = this.grid[i];
|
||||||
|
if (cur > 9 && !flashGrid[i]) {
|
||||||
|
this.flash(x, y, flashGrid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, any octopus that flashed during this step has its energy level set to 0, as it used all of its energy to flash.
|
||||||
|
for (let y = 0; y < this.maxY; y++) {
|
||||||
|
for (let x = 0; x < this.maxX; x++) {
|
||||||
|
const i = this.index(x, y);
|
||||||
|
if (flashGrid[i]) {
|
||||||
|
this.grid[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flashGrid.filter(f => f).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash(x: number, y: number, flashGrid: boolean[]) {
|
||||||
|
|
||||||
|
flashGrid[this.index(x, y)] = true;
|
||||||
|
|
||||||
|
// Charge and if needed flash all neighbors
|
||||||
|
for (let ny = y - 1; ny <= y + 1; ny++) {
|
||||||
|
for (let nx = x - 1; nx <= x + 1 ; nx++) {
|
||||||
|
this.chargeAndFlashIfNeeded(nx, ny, flashGrid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chargeAndFlashIfNeeded(x: number, y: number, flashGrid: boolean[]) {
|
||||||
|
// Short circuit for octopuses outside the grid
|
||||||
|
if (x < 0 || x >= this.maxX || y < 0 || y >= this.maxY) return;
|
||||||
|
|
||||||
|
const i = this.index(x, y);
|
||||||
|
this.grid[i] += 1;
|
||||||
|
if (this.grid[i] > 9 && !flashGrid[i]) {
|
||||||
|
this.flash(x, y, flashGrid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index(x: number, y: number): number {
|
||||||
|
return x + y * this.maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
|
||||||
|
const lines = [];
|
||||||
|
for (let y = 0; y < this.maxY; y++) {
|
||||||
|
let line = "";
|
||||||
|
for (let x = 0; x < this.maxX; x++) {
|
||||||
|
line += this.grid[this.index(x, y)];
|
||||||
|
}
|
||||||
|
lines.push(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Day11;
|
||||||
72
functions/src/day12.ts
Normal file
72
functions/src/day12.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import Day from "./day";
|
||||||
|
|
||||||
|
class Day12 implements Day {
|
||||||
|
|
||||||
|
part1(input: string[]): number | string {
|
||||||
|
|
||||||
|
const caves = this.parseInput(input);
|
||||||
|
return this.countPaths("start", caves, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
part2(input: string[]): number | string {
|
||||||
|
|
||||||
|
const caves = this.parseInput(input);
|
||||||
|
return this.countPaths("start", caves, [], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseInput(input: string[]) {
|
||||||
|
const caves = new Map<string, string[]>();
|
||||||
|
for (const line of input) {
|
||||||
|
const splitIndex = line.indexOf("-");
|
||||||
|
const from = line.substr(0, splitIndex);
|
||||||
|
const to = line.substr(splitIndex + 1);
|
||||||
|
|
||||||
|
this.addPath(from, to, caves);
|
||||||
|
this.addPath(to, from, caves);
|
||||||
|
}
|
||||||
|
return caves;
|
||||||
|
}
|
||||||
|
|
||||||
|
addPath(from: string, to: string, caves: Map<string, string[]>): void {
|
||||||
|
const existing = caves.get(from);
|
||||||
|
if (existing) {
|
||||||
|
existing.push(to);
|
||||||
|
} else {
|
||||||
|
caves.set(from, [to]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
countPaths(pos: string, caves: Map<string, string[]>, visited: string[], secondSmallVisitAllowed = false): number {
|
||||||
|
|
||||||
|
// If we reached the end, there is exactly one path
|
||||||
|
if (pos === "end") return 1;
|
||||||
|
|
||||||
|
const destinations = caves.get(pos);
|
||||||
|
if (!destinations) {
|
||||||
|
throw Error(`No paths from ${pos}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newVisited = [...visited];
|
||||||
|
if (this.isSmall(pos)) {
|
||||||
|
newVisited.push(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sum = 0;
|
||||||
|
for (const destination of destinations) {
|
||||||
|
if (!this.isSmall(destination) || !visited.includes(destination)) {
|
||||||
|
sum += this.countPaths(destination, caves, newVisited, secondSmallVisitAllowed)
|
||||||
|
} else if (secondSmallVisitAllowed && destination !== "start") {
|
||||||
|
sum += this.countPaths(destination, caves, newVisited, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
isSmall(cave: string): boolean {
|
||||||
|
return cave.toLowerCase() === cave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Day12;
|
||||||
100
functions/src/day13.ts
Normal file
100
functions/src/day13.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import Day from "./day";
|
||||||
|
import Vector2 from "./vector2";
|
||||||
|
|
||||||
|
class Day13 implements Day {
|
||||||
|
|
||||||
|
part1(input: string[]): number | string {
|
||||||
|
|
||||||
|
const {dots, folds} = this.parseInput(input);
|
||||||
|
|
||||||
|
const foldedDots = dots.map(d => folds[0].apply(d));
|
||||||
|
|
||||||
|
return new Set(foldedDots.map(d => d.key())).size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
part2(input: string[]): number | string {
|
||||||
|
|
||||||
|
const {dots, folds} = this.parseInput(input);
|
||||||
|
|
||||||
|
let foldedDots = [...dots];
|
||||||
|
for (const fold of folds) {
|
||||||
|
|
||||||
|
foldedDots = foldedDots.map(d => fold.apply(d));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.renderDots(dots);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private parseInput(input: string[]): { dots: Vector2[], folds: Fold[] } {
|
||||||
|
const dots = input.filter(s => s.trim() !== "" && !s.startsWith("fold"))
|
||||||
|
.map(s => Vector2.parse(s));
|
||||||
|
|
||||||
|
const folds = input.filter(s => s.startsWith("fold"))
|
||||||
|
.map(s => Fold.parseInstruction(s));
|
||||||
|
return {dots, folds};
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDots(dots: Vector2[]): string {
|
||||||
|
|
||||||
|
const minX = Math.min(...dots.map(d => d.x));
|
||||||
|
const maxX = Math.max(...dots.map(d => d.x));
|
||||||
|
const minY = Math.min(...dots.map(d => d.y));
|
||||||
|
const maxY = Math.max(...dots.map(d => d.y));
|
||||||
|
|
||||||
|
const lines = [];
|
||||||
|
for (let y = minY; y <= maxY; y++) {
|
||||||
|
let line = "";
|
||||||
|
for (let x = minX; x <= maxX; x++) {
|
||||||
|
line += dots.some(d => d.x === x && d.y === y) ? "#" : ".";
|
||||||
|
}
|
||||||
|
lines.push(line);
|
||||||
|
}
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Fold {
|
||||||
|
axis: "x" | "y";
|
||||||
|
foldPosition: number;
|
||||||
|
|
||||||
|
constructor(axis: "x" | "y", position: number) {
|
||||||
|
this.axis = axis;
|
||||||
|
this.foldPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
static parseInstruction(line: string): Fold {
|
||||||
|
if (line.startsWith("fold along y=")) {
|
||||||
|
return new Fold("y", parseInt(line.substr(13)));
|
||||||
|
} else if (line.startsWith("fold along x=")) {
|
||||||
|
return new Fold("x", parseInt(line.substr(13)));
|
||||||
|
} else {
|
||||||
|
throw Error(`Invalid fold instruction: "${line}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(pos: Vector2) {
|
||||||
|
|
||||||
|
if (this.axis === "y") {
|
||||||
|
|
||||||
|
return new Vector2(pos.x, this.foldAlong(pos.y));
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return new Vector2(this.foldAlong(pos.x), pos.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private foldAlong(pos: number): number {
|
||||||
|
|
||||||
|
if (pos < this.foldPosition) return pos;
|
||||||
|
if (pos === this.foldPosition) console.log("Excuse me WTF?");
|
||||||
|
|
||||||
|
const distanceToFold = pos - this.foldPosition - 1;
|
||||||
|
return this.foldPosition - distanceToFold - 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Day13;
|
||||||
151
functions/src/day14.ts
Normal file
151
functions/src/day14.ts
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import Day from "./day";
|
||||||
|
import Utils from "./utils";
|
||||||
|
|
||||||
|
type CharCounts = {[key: string]: bigint};
|
||||||
|
|
||||||
|
class Day14 implements Day {
|
||||||
|
|
||||||
|
part1(input: string[]): number | string {
|
||||||
|
|
||||||
|
const { orig, mapping } = Day14.parseInput(input);
|
||||||
|
|
||||||
|
let current = orig;
|
||||||
|
for (let step = 0; step < 10; step++) {
|
||||||
|
current = this.executeStep(current, mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
const counts: {[key: string]: number} = {};
|
||||||
|
for (const c of current) {
|
||||||
|
if (c in counts) {
|
||||||
|
counts[c]++;
|
||||||
|
} else {
|
||||||
|
counts[c] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return Math.max(...Object.values(counts)) - Math.min(...Object.values(counts));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseInput(input: string[]): { orig: string, mapping: Map<string, Map<string, string>>} {
|
||||||
|
const orig = input[0];
|
||||||
|
|
||||||
|
const mapping = new Map<string, Map<string, string>>();
|
||||||
|
for (const line of input.slice(2)) {
|
||||||
|
|
||||||
|
const splitIndex = line.indexOf("->");
|
||||||
|
const from = line.substr(0, splitIndex).trim();
|
||||||
|
const firstChar = from[0];
|
||||||
|
const secondChar = from[1];
|
||||||
|
const to = line.substr(splitIndex + 2).trim();
|
||||||
|
|
||||||
|
const existingMapping = mapping.get(firstChar);
|
||||||
|
if (existingMapping) {
|
||||||
|
existingMapping.set(secondChar, to);
|
||||||
|
} else {
|
||||||
|
mapping.set(firstChar, new Map<string, string>([[secondChar, to]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { orig, mapping };
|
||||||
|
}
|
||||||
|
|
||||||
|
private executeStep(orig: string, mapping: Map<string, Map<string, string>>): string {
|
||||||
|
|
||||||
|
let res = "";
|
||||||
|
for (let i = 0; i < orig.length - 1; i++) {
|
||||||
|
|
||||||
|
const char = orig[i];
|
||||||
|
res += char;
|
||||||
|
const firstCharMatch = mapping.get(char);
|
||||||
|
if (firstCharMatch) {
|
||||||
|
const secondChar = orig[i + 1];
|
||||||
|
const toAdd = firstCharMatch.get(secondChar);
|
||||||
|
if (toAdd) {
|
||||||
|
res += toAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add the last character as it's not included in the result
|
||||||
|
res += orig[orig.length - 1];
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
part2(input: string[]): number | string {
|
||||||
|
|
||||||
|
const { orig, mapping } = Day14.parseInput(input);
|
||||||
|
|
||||||
|
const counts: CharCounts = {};
|
||||||
|
const cache = new Map<string, CharCounts>();
|
||||||
|
for (let i = 0; i < orig.length - 1; i++) {
|
||||||
|
|
||||||
|
const firstChar = orig[i];
|
||||||
|
const secondChar = orig[i + 1];
|
||||||
|
|
||||||
|
this.addOne(firstChar, counts);
|
||||||
|
this.mergeIntoLeft(counts, this.calculateRecursive(firstChar, secondChar, mapping, 40, cache));
|
||||||
|
|
||||||
|
}
|
||||||
|
this.addOne(orig[orig.length - 1], counts);
|
||||||
|
|
||||||
|
return (Utils.bigMax(Object.values(counts)) - Utils.bigMin(Object.values(counts))).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount of added element of each type
|
||||||
|
*/
|
||||||
|
calculateRecursive(firstChar: string, secondChar: string, mappings: Map<string, Map<string, string>>, stepsLeft: number, cache: Map<string, CharCounts>): CharCounts {
|
||||||
|
|
||||||
|
if (stepsLeft === 0) return {};
|
||||||
|
|
||||||
|
const cacheKey = firstChar + secondChar + stepsLeft;
|
||||||
|
const cachedResult = cache.get(cacheKey);
|
||||||
|
if (cachedResult) return cachedResult;
|
||||||
|
|
||||||
|
const res = {};
|
||||||
|
|
||||||
|
const firstCharMatch = mappings.get(firstChar);
|
||||||
|
if (firstCharMatch) {
|
||||||
|
const toAdd = firstCharMatch.get(secondChar);
|
||||||
|
if (toAdd) {
|
||||||
|
this.addOne(toAdd, res);
|
||||||
|
this.mergeIntoLeft(res, this.calculateRecursive(firstChar, toAdd, mappings, stepsLeft - 1, cache));
|
||||||
|
this.mergeIntoLeft(res, this.calculateRecursive(toAdd, secondChar, mappings, stepsLeft - 1, cache));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.set(cacheKey, res);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeIntoLeft(left: CharCounts, right: CharCounts): void {
|
||||||
|
|
||||||
|
for (const rightKey in right) {
|
||||||
|
if (rightKey in left) {
|
||||||
|
left[rightKey] += right[rightKey];
|
||||||
|
} else {
|
||||||
|
left[rightKey] = right[rightKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addOne(char: string, counts: CharCounts): void {
|
||||||
|
|
||||||
|
if (char in counts) {
|
||||||
|
counts[char]++;
|
||||||
|
} else {
|
||||||
|
counts[char] = 1n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculateCounts(pair: string, mappings: Map<string, Map<string, string>>, cache: Map<string, Map<number, {[key: string]: bigint}>>): {[key: string]: bigint} {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Day14;
|
||||||
80
functions/src/day15.ts
Normal file
80
functions/src/day15.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import Day from "./day";
|
||||||
|
import Grid from "./Grid";
|
||||||
|
import Vector2 from "./vector2";
|
||||||
|
|
||||||
|
class Day15 implements Day {
|
||||||
|
|
||||||
|
part1(input: string[]): number | string {
|
||||||
|
|
||||||
|
return this.findLowestRiskScore(Day15.parseInput(input));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
part2(input: string[]): number | string {
|
||||||
|
|
||||||
|
const grid = Day15.parseInput(input);
|
||||||
|
|
||||||
|
const bigGrid = new Grid(Array((grid.maxX * 5) * (grid.maxY * 5)).fill(0), grid.maxX * 5, Number.MAX_SAFE_INTEGER);
|
||||||
|
|
||||||
|
for (let y = 0; y < 5; y++) {
|
||||||
|
for (let x = 0; x < 5; x++) {
|
||||||
|
const subGrid = new Grid(grid.data.map(c => c + x + y).map(c => c > 9 ? c % 9 : c), grid.maxX);
|
||||||
|
bigGrid.paste(subGrid, x * grid.maxX, y * grid.maxY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.findLowestRiskScore(bigGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private findLowestRiskScore(grid: Grid<number>): number {
|
||||||
|
|
||||||
|
const start = new Vector2(0, 0);
|
||||||
|
const destination = new Vector2(grid.maxX - 1, grid.maxY - 1);
|
||||||
|
|
||||||
|
const distances = new Grid(new Array(grid.data.length).fill(Number.MAX_SAFE_INTEGER), grid.maxX);
|
||||||
|
distances.setAt(start.x, start.y, 0);
|
||||||
|
|
||||||
|
const searchStack = [start];
|
||||||
|
|
||||||
|
while (searchStack.length > 0) {
|
||||||
|
|
||||||
|
// Simulate a priority queue on distance:
|
||||||
|
searchStack.sort((a, b) => distances.at(b.x, b.y) - distances.at(a.x, a.y));
|
||||||
|
|
||||||
|
const cur = searchStack.pop();
|
||||||
|
|
||||||
|
if (!cur) throw Error("???");
|
||||||
|
|
||||||
|
if (cur.x === destination.x && cur.y === destination.y) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const curDist = distances.at(cur.x, cur.y);
|
||||||
|
|
||||||
|
const neighbors = grid.inBoundsNeighbors(cur.x, cur.y);
|
||||||
|
|
||||||
|
|
||||||
|
for (const neighbor of neighbors) {
|
||||||
|
|
||||||
|
const newDist = curDist + grid.at(neighbor.x, neighbor.y);
|
||||||
|
if (newDist < distances.at(neighbor.x, neighbor.y)) {
|
||||||
|
distances.setAt(neighbor.x, neighbor.y, newDist);
|
||||||
|
searchStack.push(neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return distances.at(destination.x, destination.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseInput(input: string[]): Grid<number> {
|
||||||
|
|
||||||
|
return new Grid<number>(
|
||||||
|
input.flatMap(l => l.split("").map(n => parseInt(n))),
|
||||||
|
input[0].length, Number.MAX_SAFE_INTEGER);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Day15;
|
||||||
150
functions/src/day16.ts
Normal file
150
functions/src/day16.ts
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
import Day from "./day";
|
||||||
|
import Utils from "./utils";
|
||||||
|
|
||||||
|
class Day16 implements Day {
|
||||||
|
|
||||||
|
part1(input: string[]): number | string {
|
||||||
|
|
||||||
|
const packet = Packet.parse(input[0]);
|
||||||
|
|
||||||
|
return Day16.recursiveSumVersionNumbers(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
part2(input: string[]): number | string {
|
||||||
|
|
||||||
|
return Packet.parse(input[0]).calculateValue().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static recursiveSumVersionNumbers(packet: Packet): number {
|
||||||
|
|
||||||
|
if (typeof packet.content === "bigint") {
|
||||||
|
return packet.version;
|
||||||
|
} else {
|
||||||
|
return packet.version + Utils.sum(packet.content.map(sp => Day16.recursiveSumVersionNumbers(sp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Packet {
|
||||||
|
|
||||||
|
static readonly SUM_TYPE = 0
|
||||||
|
static readonly PROD_TYPE = 1;
|
||||||
|
static readonly MIN_TYPE = 2;
|
||||||
|
static readonly MAX_TYPE = 3;
|
||||||
|
static readonly LITERAL_TYPE = 4;
|
||||||
|
static readonly GT_TYPE = 5;
|
||||||
|
static readonly LT_TYPE = 6;
|
||||||
|
static readonly EQ_TYPE = 7;
|
||||||
|
|
||||||
|
static readonly VERSION_LENGTH = 3;
|
||||||
|
static readonly TYPE_LENGTH = 3;
|
||||||
|
static readonly LENGTH_TYPE_LENGTH = 1;
|
||||||
|
static readonly SUBPACKET_SIZE_LENGTH = 15;
|
||||||
|
static readonly SUBPACKET_COUNT_LENGTH = 11;
|
||||||
|
static readonly LITERAL_PART_LENGTH = 5;
|
||||||
|
|
||||||
|
version: number;
|
||||||
|
type: number;
|
||||||
|
|
||||||
|
content: Packet[] | bigint
|
||||||
|
binaryLength: number;
|
||||||
|
|
||||||
|
constructor(version: number, type: number, content: Packet[] | bigint, binaryLength: number) {
|
||||||
|
this.version = version;
|
||||||
|
this.type = type;
|
||||||
|
this.content = content;
|
||||||
|
this.binaryLength = binaryLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateValue(): bigint {
|
||||||
|
|
||||||
|
if (typeof this.content === "bigint") return this.content;
|
||||||
|
|
||||||
|
const subValues = this.content.map(c => c.calculateValue());
|
||||||
|
|
||||||
|
if (this.type === Packet.SUM_TYPE) {
|
||||||
|
return Utils.bigSum(subValues)
|
||||||
|
} else if (this.type === Packet.PROD_TYPE) {
|
||||||
|
return subValues.reduce((a, b) => a * b, 1n);
|
||||||
|
} else if (this.type === Packet.MIN_TYPE) {
|
||||||
|
return Utils.bigMin(subValues);
|
||||||
|
} else if (this.type === Packet.MAX_TYPE) {
|
||||||
|
return Utils.bigMax(subValues);
|
||||||
|
} else if (this.type === Packet.GT_TYPE) {
|
||||||
|
return subValues[0] > subValues[1] ? 1n : 0n;
|
||||||
|
} else if (this.type === Packet.LT_TYPE) {
|
||||||
|
return subValues[0] < subValues[1] ? 1n : 0n;
|
||||||
|
} else if (this.type === Packet.EQ_TYPE) {
|
||||||
|
return subValues[0] === subValues[1] ? 1n : 0n;
|
||||||
|
} else {
|
||||||
|
// Shouldn't happen
|
||||||
|
throw Error("Unsupported packet type: " + this.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static parse(input: string): Packet {
|
||||||
|
return this.parseBinaryInput(Packet.toBinary(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
static toBinary(input: string): string {
|
||||||
|
return input.split("").map(s => parseInt(s, 16).toString(2).padStart(4, "0")).join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
static parseBinaryInput(binaryInput: string, start = 0): Packet {
|
||||||
|
|
||||||
|
const version = parseInt(binaryInput.substr(start, Packet.VERSION_LENGTH), 2);
|
||||||
|
const type = parseInt(binaryInput.substr(start + Packet.VERSION_LENGTH, Packet.TYPE_LENGTH), 2);
|
||||||
|
|
||||||
|
const contentStart = start + Packet.VERSION_LENGTH + Packet.TYPE_LENGTH;
|
||||||
|
|
||||||
|
if (type === Packet.LITERAL_TYPE) {
|
||||||
|
// Literal value
|
||||||
|
let i = 0;
|
||||||
|
let binaryLiteral = "0b";
|
||||||
|
do {
|
||||||
|
binaryLiteral += binaryInput.substr(contentStart + (Packet.LITERAL_PART_LENGTH * i) + 1, Packet.LITERAL_PART_LENGTH - 1);
|
||||||
|
i++;
|
||||||
|
} while(binaryInput[contentStart + (Packet.LITERAL_PART_LENGTH * (i - 1))] === "1")
|
||||||
|
return new Packet(version, type, BigInt(binaryLiteral), Packet.VERSION_LENGTH + Packet.TYPE_LENGTH + (Packet.LITERAL_PART_LENGTH * i))
|
||||||
|
} else {
|
||||||
|
// Operator packets, so let's parse the subpackets:
|
||||||
|
const lengthType = binaryInput[contentStart];
|
||||||
|
|
||||||
|
if (lengthType === "0") {
|
||||||
|
const subpacketsLength = parseInt(binaryInput.substr(contentStart + Packet.LENGTH_TYPE_LENGTH, Packet.SUBPACKET_SIZE_LENGTH), 2);
|
||||||
|
|
||||||
|
const firstPacketStart = contentStart + Packet.LENGTH_TYPE_LENGTH + Packet.SUBPACKET_SIZE_LENGTH;
|
||||||
|
let curStart = firstPacketStart;
|
||||||
|
const subPackets = [];
|
||||||
|
while (curStart - firstPacketStart < subpacketsLength) {
|
||||||
|
const subPacket = this.parseBinaryInput(binaryInput, curStart);
|
||||||
|
curStart += subPacket.binaryLength;
|
||||||
|
subPackets.push(subPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Packet(version, type, subPackets, curStart - start);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const subpacketCount = parseInt(binaryInput.substr(contentStart + Packet.LENGTH_TYPE_LENGTH, Packet.SUBPACKET_COUNT_LENGTH), 2);
|
||||||
|
|
||||||
|
let curStart = contentStart + Packet.LENGTH_TYPE_LENGTH + Packet.SUBPACKET_COUNT_LENGTH;
|
||||||
|
const subPackets = [];
|
||||||
|
for (let i = 0; i < subpacketCount; i++) {
|
||||||
|
const subPacket = this.parseBinaryInput(binaryInput, curStart);
|
||||||
|
curStart += subPacket.binaryLength;
|
||||||
|
subPackets.push(subPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Packet(version, type, subPackets, curStart - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Day16;
|
||||||
|
|
||||||
199
functions/src/day17.ts
Normal file
199
functions/src/day17.ts
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
import Day from "./day";
|
||||||
|
|
||||||
|
class Day17 implements Day {
|
||||||
|
|
||||||
|
// steps = 3
|
||||||
|
// y = 1 -> 1 + 0 + -1 = 0
|
||||||
|
// y = 2 -> 2 + 1 + 0 = 3
|
||||||
|
// y = 3 -> 3 + 2 + 1 = 6
|
||||||
|
// y = 4 -> 4 + 3 + 2 = 9
|
||||||
|
// y = 5 -> 5 + 4 + 3 = 12
|
||||||
|
|
||||||
|
// steps = 4
|
||||||
|
// y = 1 -> -2
|
||||||
|
// y = 2 -> 2
|
||||||
|
// y = 3 -> 6
|
||||||
|
// y = 4 -> 10
|
||||||
|
|
||||||
|
// y = 0
|
||||||
|
// steps = 1 -> 0 = 0
|
||||||
|
// steps = 2 -> 0 - 1 = -1
|
||||||
|
// steps = 3 -> 0 - 1 - 2 = -3
|
||||||
|
// steps = 4 -> 0 - 1- 2 - 3= -6
|
||||||
|
// steps = 5 -> 0-1-2-3-4 = -10
|
||||||
|
// steps = 6 -> 0-1-2-3-4-5 = -15
|
||||||
|
|
||||||
|
part1(input: string[]): number | string {
|
||||||
|
|
||||||
|
const targetArea = TargetArea.parse(input[0]);
|
||||||
|
|
||||||
|
// Assuming v_y0 > 0, the maximum height the probe reaches is triangle(y).
|
||||||
|
// After reaching the top, the probe starts falling back down, taking "v_y0" steps to get back to a height of 0.
|
||||||
|
// After that it has a speed of v_y0 - 1.
|
||||||
|
|
||||||
|
// Note that the triangle value of x must be at least the minimal x of the target area, otherwise the probe won't
|
||||||
|
// reach the target area before it's velocity reaches zero:
|
||||||
|
const v_x0_min = Day17.triangleInvCeil(targetArea.minX);
|
||||||
|
// Calculate the x-position we reach after v_x0 steps:
|
||||||
|
const x_min = Day17.triangle(v_x0_min);
|
||||||
|
|
||||||
|
if (targetArea.isInX(x_min)) {
|
||||||
|
// We have an x-speed that reaches the target area in x_min steps and stays there (e.g. reaches velocity zero in the target area),
|
||||||
|
// so we can just find the biggest y that at some point ends up in the target area.
|
||||||
|
// We already know that the y speed when the "probe" comes down is:
|
||||||
|
// -v_y0 - 1
|
||||||
|
// So if we choose as starting y that is one higher than the minimal y value, we end up in the bottom of the target area, while
|
||||||
|
// reaching the maximum height:
|
||||||
|
const v_y0_max = Math.abs(targetArea.minY) - 1;
|
||||||
|
return Day17.triangle(v_y0_max);
|
||||||
|
} else {
|
||||||
|
throw Error("Unsupported target area, only a target area with an x values that is a triangle number is supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part2(input: string[]): number | string {
|
||||||
|
|
||||||
|
const targetArea = TargetArea.parse(input[0]);
|
||||||
|
|
||||||
|
const v_x0_min = Day17.triangleInvCeil(targetArea.minX);
|
||||||
|
const v_x0_max_static = Day17.triangleInvFloor(targetArea.maxX);
|
||||||
|
const maxYStepsBelowZero = Day17.triangleInvCeil(Math.abs(targetArea.minY));
|
||||||
|
|
||||||
|
let solutionCount = 0;
|
||||||
|
|
||||||
|
for (let v_x0 = v_x0_min; v_x0 <= targetArea.maxX; v_x0++) {
|
||||||
|
for (let v_y0 = targetArea.minY; v_y0 < Math.abs(targetArea.minY); v_y0++) {
|
||||||
|
|
||||||
|
// If v_x0 <= v_x0_max_static, we end up in a position where eventually all x-es fall in the valid range
|
||||||
|
// So in that case, we base the max steps on the y values.
|
||||||
|
const maxSteps = v_x0 <= v_x0_max_static
|
||||||
|
? (v_y0 < 0 ? maxYStepsBelowZero : 2 * v_y0 + 1 + maxYStepsBelowZero)
|
||||||
|
: v_x0_max_static;
|
||||||
|
|
||||||
|
for (let steps = 1; steps <= maxSteps; steps++) {
|
||||||
|
const xRangeResult = this.isInXAfterSteps(v_x0, steps, targetArea);
|
||||||
|
if (xRangeResult === RangeResult.TOO_HIGH) {
|
||||||
|
break;
|
||||||
|
} if (xRangeResult === RangeResult.YES) {
|
||||||
|
// Check what y values work for this x and step count:
|
||||||
|
const yRangeResult = this.isInYAfterSteps(v_y0, steps, targetArea);
|
||||||
|
if (yRangeResult === RangeResult.YES) {
|
||||||
|
// console.log(`${v_x0}, ${v_y0}`)
|
||||||
|
solutionCount++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return solutionCount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
isInXAfterSteps(v_x0: number, steps: number, targetArea: TargetArea): RangeResult {
|
||||||
|
|
||||||
|
if (steps >= v_x0) {
|
||||||
|
// reached final position, which is the triangle number of the initial speed:
|
||||||
|
return targetArea.isInX(Day17.triangle(v_x0));
|
||||||
|
} else {
|
||||||
|
// On our way to the final position:
|
||||||
|
const x = Day17.triangle(v_x0) - Day17.triangle(v_x0 - steps);
|
||||||
|
return targetArea.isInX(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
isInYAfterSteps(v_y0: number, steps: number, targetArea: TargetArea): RangeResult {
|
||||||
|
|
||||||
|
if (targetArea.maxY >= 0) throw Error("Only target area's below the starting point are supported")
|
||||||
|
|
||||||
|
if (v_y0 > 0) {
|
||||||
|
if (steps < 2 * v_y0) {
|
||||||
|
// We haven't gone below the
|
||||||
|
return RangeResult.TOO_HIGH;
|
||||||
|
} else {
|
||||||
|
// This is equivalent to firing with a negative y speed after v_y0 * 2 + 1 steps (so the steps left = steps - 2 * v_y0 - 1)
|
||||||
|
return this.isInYAfterSteps(-v_y0 - 1, steps - 2 * v_y0 - 1, targetArea);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Firing downward:
|
||||||
|
const y = - Day17.calcPositionAfterIncreasingVelocity(Math.abs(v_y0), steps);
|
||||||
|
return targetArea.isInY(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static calcPositionAfterIncreasingVelocity(v: number, steps: number): number {
|
||||||
|
if (v < 0) throw Error("Velocity must be positive");
|
||||||
|
|
||||||
|
return Day17.triangle(v - 1 + steps) - Day17.triangle(v - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static triangle(n: number): number {
|
||||||
|
return (n*(n + 1)) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static triangleInvCeil(x: number): number {
|
||||||
|
return Math.ceil(this.triangleInv(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
static triangleInvFloor(x: number): number {
|
||||||
|
return Math.floor(this.triangleInv(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
static triangleInv(x: number): number {
|
||||||
|
return (Math.sqrt(8 * x + 1) - 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RangeResult {
|
||||||
|
TOO_LOW = -1,
|
||||||
|
TOO_HIGH = 0,
|
||||||
|
YES = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class TargetArea {
|
||||||
|
|
||||||
|
minX: number;
|
||||||
|
maxX: number;
|
||||||
|
minY: number;
|
||||||
|
maxY: number;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(minX: number, maxX: number, minY: number, maxY: number) {
|
||||||
|
this.minX = minX;
|
||||||
|
this.maxX = maxX;
|
||||||
|
this.minY = minY;
|
||||||
|
this.maxY = maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static parse(input: string): TargetArea {
|
||||||
|
const regex = /^target area: x=(-?[0-9]+)\.\.(-?[0-9]+), y=(-?[0-9]+)..(-?[0-9]+)$/i;
|
||||||
|
const match = input.trim().match(regex);
|
||||||
|
|
||||||
|
if (!match || match.length < 5) {
|
||||||
|
throw Error("Invalid input: '" + input + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TargetArea(
|
||||||
|
parseInt(match[1]),
|
||||||
|
parseInt(match[2]),
|
||||||
|
parseInt(match[3]),
|
||||||
|
parseInt(match[4]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
isInX(x: number): RangeResult {
|
||||||
|
if (x < this.minX) return RangeResult.TOO_LOW;
|
||||||
|
else if (x > this.maxX) return RangeResult.TOO_HIGH;
|
||||||
|
else return RangeResult.YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
isInY(y: number): RangeResult {
|
||||||
|
if (y < this.minY) return RangeResult.TOO_LOW;
|
||||||
|
else if (y > this.maxY) return RangeResult.TOO_HIGH;
|
||||||
|
else return RangeResult.YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Day17;
|
||||||
@@ -12,6 +12,13 @@ import Day7 from "./day7";
|
|||||||
import Day8 from "./day8";
|
import Day8 from "./day8";
|
||||||
import Day9 from "./day9";
|
import Day9 from "./day9";
|
||||||
import Day10 from "./day10";
|
import Day10 from "./day10";
|
||||||
|
import Day11 from "./day11";
|
||||||
|
import Day12 from "./day12";
|
||||||
|
import Day13 from "./day13";
|
||||||
|
import Day14 from "./day14";
|
||||||
|
import Day15 from "./day15";
|
||||||
|
import Day16 from "./day16";
|
||||||
|
import Day17 from './day17';
|
||||||
|
|
||||||
|
|
||||||
// // Start writing Firebase Functions
|
// // Start writing Firebase Functions
|
||||||
@@ -38,6 +45,13 @@ export const day = {
|
|||||||
8: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day8(), request, response) }),
|
8: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day8(), request, response) }),
|
||||||
9: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day9(), request, response) }),
|
9: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day9(), request, response) }),
|
||||||
10: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day10(), request, response) }),
|
10: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day10(), request, response) }),
|
||||||
|
11: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day11(), request, response) }),
|
||||||
|
12: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day12(), request, response) }),
|
||||||
|
13: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day13(), request, response) }),
|
||||||
|
14: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day14(), request, response) }),
|
||||||
|
15: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day15(), request, response) }),
|
||||||
|
16: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day16(), request, response) }),
|
||||||
|
17: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day17(), request, response) }),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ class Utils {
|
|||||||
return values.reduce((a, b) => a + b);
|
return values.reduce((a, b) => a + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bigMax(values: bigint[]): bigint {
|
||||||
|
return values.reduce((a, b) => a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bigMin(values: bigint[]): bigint {
|
||||||
|
return values.reduce((a, b) => a < b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
static zeroes(length: number): number[] {
|
static zeroes(length: number): number[] {
|
||||||
|
|
||||||
const res = [];
|
const res = [];
|
||||||
|
|||||||
@@ -23,6 +23,18 @@
|
|||||||
chalk "^2.0.0"
|
chalk "^2.0.0"
|
||||||
js-tokens "^4.0.0"
|
js-tokens "^4.0.0"
|
||||||
|
|
||||||
|
"@cspotcode/source-map-consumer@0.8.0":
|
||||||
|
version "0.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
|
||||||
|
integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==
|
||||||
|
|
||||||
|
"@cspotcode/source-map-support@0.7.0":
|
||||||
|
version "0.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5"
|
||||||
|
integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==
|
||||||
|
dependencies:
|
||||||
|
"@cspotcode/source-map-consumer" "0.8.0"
|
||||||
|
|
||||||
"@eslint/eslintrc@^0.4.3":
|
"@eslint/eslintrc@^0.4.3":
|
||||||
version "0.4.3"
|
version "0.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||||
@@ -278,6 +290,26 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
||||||
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
|
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
|
||||||
|
|
||||||
|
"@tsconfig/node10@^1.0.7":
|
||||||
|
version "1.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
|
||||||
|
integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==
|
||||||
|
|
||||||
|
"@tsconfig/node12@^1.0.7":
|
||||||
|
version "1.0.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c"
|
||||||
|
integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==
|
||||||
|
|
||||||
|
"@tsconfig/node14@^1.0.0":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2"
|
||||||
|
integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==
|
||||||
|
|
||||||
|
"@tsconfig/node16@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
|
||||||
|
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
|
||||||
|
|
||||||
"@types/body-parser@*":
|
"@types/body-parser@*":
|
||||||
version "1.19.2"
|
version "1.19.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
|
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
|
||||||
@@ -474,11 +506,21 @@ acorn-jsx@^5.3.1:
|
|||||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||||
|
|
||||||
|
acorn-walk@^8.1.1:
|
||||||
|
version "8.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
||||||
|
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
||||||
|
|
||||||
acorn@^7.4.0:
|
acorn@^7.4.0:
|
||||||
version "7.4.1"
|
version "7.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||||
|
|
||||||
|
acorn@^8.4.1:
|
||||||
|
version "8.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895"
|
||||||
|
integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==
|
||||||
|
|
||||||
agent-base@6:
|
agent-base@6:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||||
@@ -530,6 +572,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^2.0.1"
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
|
arg@^4.1.0:
|
||||||
|
version "4.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||||
|
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||||
|
|
||||||
argparse@^1.0.7:
|
argparse@^1.0.7:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||||
@@ -745,6 +792,11 @@ cors@^2.8.5:
|
|||||||
object-assign "^4"
|
object-assign "^4"
|
||||||
vary "^1"
|
vary "^1"
|
||||||
|
|
||||||
|
create-require@^1.1.0:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||||
|
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||||
|
|
||||||
cross-spawn@^7.0.2:
|
cross-spawn@^7.0.2:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
@@ -814,6 +866,11 @@ dicer@^0.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
streamsearch "0.1.2"
|
streamsearch "0.1.2"
|
||||||
|
|
||||||
|
diff@^4.0.1:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||||
|
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||||
|
|
||||||
doctrine@^2.1.0:
|
doctrine@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
|
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
|
||||||
@@ -1903,6 +1960,11 @@ make-dir@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
semver "^6.0.0"
|
semver "^6.0.0"
|
||||||
|
|
||||||
|
make-error@^1.1.1:
|
||||||
|
version "1.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||||
|
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||||
|
|
||||||
media-typer@0.3.0:
|
media-typer@0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
@@ -2515,6 +2577,24 @@ tr46@~0.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||||
|
|
||||||
|
ts-node@^10.4.0:
|
||||||
|
version "10.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
|
||||||
|
integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==
|
||||||
|
dependencies:
|
||||||
|
"@cspotcode/source-map-support" "0.7.0"
|
||||||
|
"@tsconfig/node10" "^1.0.7"
|
||||||
|
"@tsconfig/node12" "^1.0.7"
|
||||||
|
"@tsconfig/node14" "^1.0.0"
|
||||||
|
"@tsconfig/node16" "^1.0.2"
|
||||||
|
acorn "^8.4.1"
|
||||||
|
acorn-walk "^8.1.1"
|
||||||
|
arg "^4.1.0"
|
||||||
|
create-require "^1.1.0"
|
||||||
|
diff "^4.0.1"
|
||||||
|
make-error "^1.1.1"
|
||||||
|
yn "3.1.1"
|
||||||
|
|
||||||
tsconfig-paths@^3.11.0:
|
tsconfig-paths@^3.11.0:
|
||||||
version "3.12.0"
|
version "3.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b"
|
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b"
|
||||||
@@ -2740,6 +2820,11 @@ yargs@^16.1.1:
|
|||||||
y18n "^5.0.5"
|
y18n "^5.0.5"
|
||||||
yargs-parser "^20.2.2"
|
yargs-parser "^20.2.2"
|
||||||
|
|
||||||
|
yn@3.1.1:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||||
|
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||||
|
|
||||||
yocto-queue@^0.1.0:
|
yocto-queue@^0.1.0:
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||||
|
|||||||
15
input/day/11-example.http
Normal file
15
input/day/11-example.http
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-11
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
5483143223
|
||||||
|
2745854711
|
||||||
|
5264556173
|
||||||
|
6141336146
|
||||||
|
6357385478
|
||||||
|
4167524645
|
||||||
|
2176841721
|
||||||
|
6882881134
|
||||||
|
4846848554
|
||||||
|
5283751526
|
||||||
|
|
||||||
|
###
|
||||||
15
input/day/11.http
Normal file
15
input/day/11.http
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-11
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
2524255331
|
||||||
|
1135625881
|
||||||
|
2838353863
|
||||||
|
1662312365
|
||||||
|
6847835825
|
||||||
|
2185684367
|
||||||
|
6874212831
|
||||||
|
5387247811
|
||||||
|
2255482875
|
||||||
|
8528557131
|
||||||
|
|
||||||
|
###
|
||||||
52
input/day/12-example.http
Normal file
52
input/day/12-example.http
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-12
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
start-A
|
||||||
|
start-b
|
||||||
|
A-c
|
||||||
|
A-b
|
||||||
|
b-d
|
||||||
|
A-end
|
||||||
|
b-end
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-12
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
dc-end
|
||||||
|
HN-start
|
||||||
|
start-kj
|
||||||
|
dc-start
|
||||||
|
dc-HN
|
||||||
|
LN-dc
|
||||||
|
HN-end
|
||||||
|
kj-sa
|
||||||
|
kj-HN
|
||||||
|
kj-dc
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-12
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
fs-end
|
||||||
|
he-DX
|
||||||
|
fs-he
|
||||||
|
start-DX
|
||||||
|
pj-DX
|
||||||
|
end-zg
|
||||||
|
zg-sl
|
||||||
|
zg-pj
|
||||||
|
pj-he
|
||||||
|
RW-he
|
||||||
|
fs-DX
|
||||||
|
pj-RW
|
||||||
|
zg-RW
|
||||||
|
start-pj
|
||||||
|
he-WI
|
||||||
|
zg-he
|
||||||
|
pj-fs
|
||||||
|
start-RW
|
||||||
|
|
||||||
|
###
|
||||||
30
input/day/12.http
Normal file
30
input/day/12.http
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-12
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
start-kc
|
||||||
|
pd-NV
|
||||||
|
start-zw
|
||||||
|
UI-pd
|
||||||
|
HK-end
|
||||||
|
UI-kc
|
||||||
|
pd-ih
|
||||||
|
ih-end
|
||||||
|
start-UI
|
||||||
|
kc-zw
|
||||||
|
end-ks
|
||||||
|
MF-mq
|
||||||
|
HK-zw
|
||||||
|
LF-ks
|
||||||
|
HK-kc
|
||||||
|
ih-HK
|
||||||
|
kc-pd
|
||||||
|
ks-pd
|
||||||
|
MF-pd
|
||||||
|
UI-zw
|
||||||
|
ih-NV
|
||||||
|
ks-HK
|
||||||
|
MF-kc
|
||||||
|
zw-NV
|
||||||
|
NV-ks
|
||||||
|
|
||||||
|
###
|
||||||
26
input/day/13-example.http
Normal file
26
input/day/13-example.http
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-13
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
6,10
|
||||||
|
0,14
|
||||||
|
9,10
|
||||||
|
0,3
|
||||||
|
10,4
|
||||||
|
4,11
|
||||||
|
6,0
|
||||||
|
6,12
|
||||||
|
4,1
|
||||||
|
0,13
|
||||||
|
10,12
|
||||||
|
3,4
|
||||||
|
3,0
|
||||||
|
8,4
|
||||||
|
1,10
|
||||||
|
2,14
|
||||||
|
8,10
|
||||||
|
9,0
|
||||||
|
|
||||||
|
fold along y=7
|
||||||
|
fold along x=5
|
||||||
|
|
||||||
|
###
|
||||||
1001
input/day/13.http
Normal file
1001
input/day/13.http
Normal file
File diff suppressed because it is too large
Load Diff
23
input/day/14-example.http
Normal file
23
input/day/14-example.http
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-14
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
NNCB
|
||||||
|
|
||||||
|
CH -> B
|
||||||
|
HH -> N
|
||||||
|
CB -> H
|
||||||
|
NH -> C
|
||||||
|
HB -> C
|
||||||
|
HC -> B
|
||||||
|
HN -> C
|
||||||
|
NN -> C
|
||||||
|
BH -> H
|
||||||
|
NC -> B
|
||||||
|
NB -> B
|
||||||
|
BN -> B
|
||||||
|
BB -> N
|
||||||
|
BC -> B
|
||||||
|
CC -> N
|
||||||
|
CN -> C
|
||||||
|
|
||||||
|
###
|
||||||
107
input/day/14.http
Normal file
107
input/day/14.http
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-14
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
CNBPHFBOPCSPKOFNHVKV
|
||||||
|
|
||||||
|
CS -> S
|
||||||
|
FB -> F
|
||||||
|
VK -> V
|
||||||
|
HO -> F
|
||||||
|
SO -> K
|
||||||
|
FK -> B
|
||||||
|
VS -> C
|
||||||
|
PS -> H
|
||||||
|
HH -> P
|
||||||
|
KH -> V
|
||||||
|
PV -> V
|
||||||
|
CB -> N
|
||||||
|
BB -> N
|
||||||
|
HB -> B
|
||||||
|
HV -> O
|
||||||
|
NC -> H
|
||||||
|
NF -> B
|
||||||
|
HP -> B
|
||||||
|
HK -> S
|
||||||
|
SF -> O
|
||||||
|
ON -> K
|
||||||
|
VN -> V
|
||||||
|
SB -> H
|
||||||
|
SK -> H
|
||||||
|
VH -> N
|
||||||
|
KN -> C
|
||||||
|
CC -> N
|
||||||
|
BF -> H
|
||||||
|
SN -> N
|
||||||
|
KP -> B
|
||||||
|
FO -> N
|
||||||
|
KO -> V
|
||||||
|
BP -> O
|
||||||
|
OK -> F
|
||||||
|
HC -> B
|
||||||
|
NH -> O
|
||||||
|
SP -> O
|
||||||
|
OO -> S
|
||||||
|
VC -> O
|
||||||
|
PC -> F
|
||||||
|
VB -> O
|
||||||
|
FF -> S
|
||||||
|
BS -> F
|
||||||
|
KS -> F
|
||||||
|
OV -> P
|
||||||
|
NB -> O
|
||||||
|
CF -> F
|
||||||
|
SS -> V
|
||||||
|
KV -> K
|
||||||
|
FP -> F
|
||||||
|
KC -> C
|
||||||
|
PF -> C
|
||||||
|
OS -> C
|
||||||
|
PN -> B
|
||||||
|
OP -> C
|
||||||
|
FN -> F
|
||||||
|
OF -> C
|
||||||
|
NP -> C
|
||||||
|
CK -> N
|
||||||
|
BN -> K
|
||||||
|
BO -> K
|
||||||
|
OH -> S
|
||||||
|
BH -> O
|
||||||
|
SH -> N
|
||||||
|
CH -> K
|
||||||
|
PO -> V
|
||||||
|
CN -> N
|
||||||
|
BV -> F
|
||||||
|
FV -> B
|
||||||
|
VP -> V
|
||||||
|
FS -> O
|
||||||
|
NV -> P
|
||||||
|
PH -> C
|
||||||
|
HN -> P
|
||||||
|
VV -> C
|
||||||
|
NK -> K
|
||||||
|
CO -> N
|
||||||
|
NS -> P
|
||||||
|
VO -> P
|
||||||
|
CP -> V
|
||||||
|
OC -> S
|
||||||
|
PK -> V
|
||||||
|
NN -> F
|
||||||
|
SC -> P
|
||||||
|
BK -> F
|
||||||
|
BC -> P
|
||||||
|
FH -> B
|
||||||
|
OB -> O
|
||||||
|
FC -> N
|
||||||
|
PB -> N
|
||||||
|
VF -> N
|
||||||
|
PP -> S
|
||||||
|
HS -> O
|
||||||
|
HF -> N
|
||||||
|
KK -> C
|
||||||
|
KB -> N
|
||||||
|
SV -> N
|
||||||
|
KF -> K
|
||||||
|
CV -> N
|
||||||
|
NO -> P
|
||||||
|
|
||||||
|
###
|
||||||
15
input/day/15-example.http
Normal file
15
input/day/15-example.http
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-15
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
1163751742
|
||||||
|
1381373672
|
||||||
|
2136511328
|
||||||
|
3694931569
|
||||||
|
7463417111
|
||||||
|
1319128137
|
||||||
|
1359912421
|
||||||
|
3125421639
|
||||||
|
1293138521
|
||||||
|
2311944581
|
||||||
|
|
||||||
|
###
|
||||||
105
input/day/15.http
Normal file
105
input/day/15.http
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-15
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
6763679391685199321216293379889971448824578974299594779321588588854917594121939988499223486918759869
|
||||||
|
2316279872424397812389627435928425571522864993268981993135231281632931912219714272492398841364337743
|
||||||
|
2611672912699479934143747711184533124498991233998359921827688713818629591848267212751251782193999574
|
||||||
|
6912169338419564193119921496213581987492424159798957517399336988989137775762957929689971478512677295
|
||||||
|
3932311559122894111729688681511182241159886994773792138139838569578133999317372937113824879568115791
|
||||||
|
8589559297931592498862929729979441917281114429312571991515483885553657942311696693187113914917719999
|
||||||
|
8215113889897867537369472795288394514311281463548681147471413974111467312128797923211571493578216618
|
||||||
|
8353591188598582985969267941199579989219858339399879528759128156699712595424919231926423577793888319
|
||||||
|
7968158785991328349741182178823359987435932199259784623665394822298984991599994974239363919518451979
|
||||||
|
4719769796126416122596629937853975319746131691284132121869728172317997172141428897895794796191812167
|
||||||
|
3715796581651751161784761598687561271125699522733481968514817818771137272533379148686393358399562697
|
||||||
|
8962557499696333687128936247423429275688421766599283984442229598921259494162139235897485497997417698
|
||||||
|
2182921896724715397151528121721594929388481339121986131936359796235664119251178868889159217485672977
|
||||||
|
2828391155451888689511271529962927197658791494698163842856727412981821697293253119184773912119989595
|
||||||
|
9199386341352517771926352819889757985144519361117599547314166929999995972716284565918358465675673988
|
||||||
|
8722511734918316438427142154119225846521916542121666685543317729394927826333442319376948819282625186
|
||||||
|
1477775698392989993392219356859976719258173183628158123159842811277192868899697572971451899974811444
|
||||||
|
8335153624471899974521698617192979799279846783499194279818499779819993698148766775278931949849681136
|
||||||
|
2269391966932443996719216591454851181957749968945583939554283869612267695171361752994867961193376666
|
||||||
|
9861712325484181139982862631919269143595262461191729137191664394921995697291311623719788971894557112
|
||||||
|
3112924177579979863258192877919454273941796893715949583554934558911631754244367342151872134159993285
|
||||||
|
2979941956219158611766883428493219185525886883611119191938587953596273121943489333147616528786997189
|
||||||
|
6911351423565397282381124199883475198396389555252699348494149975992869258195112131399297298977795897
|
||||||
|
9119199355931828419162999986929799583691289619982317919828137147697551391791243988459169917431599811
|
||||||
|
3848535265995589835498483569499111894179811797988524139731991816798915115719188982418358989615316197
|
||||||
|
9986394864159675512549196699791852181845314977319988969899439522116944611392429241976152135959496687
|
||||||
|
1761296827993117963817612129952997912232911828816999868511211229529681228381151777711719891779972859
|
||||||
|
9849862226991147961391718387156998929941716949984572288291485879679697217224997668438772548619172679
|
||||||
|
2896199355897526963449291963999361199143143424688187155899714182931423911884487471881515515658192867
|
||||||
|
8882999928819749128875119614594191789229917398195439659381686259712273461799994165868781999354911927
|
||||||
|
6293896891611311711917811764936777917992419746299291928141929236699957831472193155131929614221383779
|
||||||
|
1728911221599715849995857841992339722725816297697995975879639548179113113959417185128498668951991497
|
||||||
|
6389814779572888297744659943499321785461891927895956813219966863392927311261947592959791194244193985
|
||||||
|
4712939391449918111131972657951783573919121925419474446716964951423691926889216751829199971929971132
|
||||||
|
6699393113173611979749359993737683829563992223191989431431991486229753888571121391169999878623437521
|
||||||
|
1198142461644317844741991158835235118423789877114199729435917618739231152683794599876297129118987729
|
||||||
|
7111721965894267271711241998912592181993889216116948256156274679111482128896321191168811482813644926
|
||||||
|
1171113376212775991947216339497719768861872218996599392728399271322997169438555172469628987211141167
|
||||||
|
4971813199829153127388192731965829199759623126139328216651191296739154191919321549673351715616929225
|
||||||
|
8119853972258311171879982114156481797449119753397856132264122489141398797971999829792199497347937184
|
||||||
|
1561927699676538752366853298261467719967474391978893889187186993911227929965998393176697961138881969
|
||||||
|
3959543274866211216958741199781999369818266285521119327231111949788966823231813299914822949693166178
|
||||||
|
6854334615997742391438812963442348142383912111514912819499189236198343918618996193813217929982888331
|
||||||
|
8591288815988159958617116297298498195754511127153431788392191923719497543218299627991945622899279289
|
||||||
|
1198181911718723715273338822929941917461229991426187431333885549983141594522995949791148288364399931
|
||||||
|
9892771631174419697317439985991838611951224884481231136571449581393892332789397968799983813949946771
|
||||||
|
9691923978185936311116748722117898552719939491217617698689477616899284218259911527919573958121194566
|
||||||
|
1843959822758422286269513881221514742239331123871961146817735961867178733293667759597321611856364687
|
||||||
|
6977982858241122656318958728139689829747681724996991567112142583112379441312489192619155735979429668
|
||||||
|
6864883774995893992121211469519696127454667681591441917467229798514197759483539991821689423396931376
|
||||||
|
3192522673899612494271981219195459514965899598392186194369342687247433627873639189288865189581796451
|
||||||
|
6193892956996137113415685193111676238918282975948726168585412815746185395326782967392782846445773697
|
||||||
|
1188865911911546793619591679249496642955219194954776936299621427191849498935988721841952878212961283
|
||||||
|
8694399699295137671549998897263823738366959893492139427998171551895683249779412599116969296375488479
|
||||||
|
7877598934985997851215297123318237642987983729213129426654775659332934214699911779979746936272991192
|
||||||
|
4175196464729659417156311852378196911437496911391319497971434617443518159949999724995188783613191262
|
||||||
|
3762316191918893118954134928121247287121688294319514979584434758992189222213767189269961981712572193
|
||||||
|
9981882951928288197367958981851556961646895153776691782279112427148955797179663174911297574899971912
|
||||||
|
9895926311251443254199633719115569998677994839525436526347578387872641421492919519516711971912127392
|
||||||
|
9723333996192974279158728199716934988493621698998331467858916957375227137984979938714344915111827182
|
||||||
|
1489298994798826597544143761492942354121188712292616383251311951685245147566949991744458552776489586
|
||||||
|
3211451591643914838596299339712994772187111828984686683882184719386899356485897381553187228879431569
|
||||||
|
3259651629398171558779297578391789196514939231918933422179195617371647233469447869642991783645897982
|
||||||
|
2189951822939529117192393161419994119171944662568828111311499919463717394995779991162414161719332911
|
||||||
|
6899749988259797792429961362715358939636711635174199885892389153199229186421823334294179228734911269
|
||||||
|
1895185897772972825953599619294129599869824625386123522999289881519328792475665963443599326534417127
|
||||||
|
1422838395994495358964648891923798731481939992848921648929946289995168912914361941528948493335781149
|
||||||
|
1317917384867191387219277529343126299981599689294419264273884458618911827925925837774616338553561629
|
||||||
|
8982434966658784238385743322589831393888399172871716379119313128392163811311519839188471992219378467
|
||||||
|
5395261691648469592639393691332481954629942491921281189152991281859952918822165534198758892953939121
|
||||||
|
6329251216799321932117288219179141299519462991931239519193384798587198173781939892827679183111344218
|
||||||
|
3812529999729156619987867616929265585873977681595939647814448735791934148324446952891313111995972677
|
||||||
|
5282338992996313613159211993928283819929873988655191555399565229817638959377739269398838668781572226
|
||||||
|
4378531984893973581486991728926841115919613871448996179956749642471991995965911222685526627192999981
|
||||||
|
5982889739797551811388582535136873719759679761139313976924211474849296399512823999129477342278145322
|
||||||
|
1218281999719267672993931254981112865424986972187191477949981863168351999531146991641381242421214511
|
||||||
|
8911997846692872463596818916972951916181657731917916963182871214914196812971788959961183392597197251
|
||||||
|
4915117978531879932257171943259639189397181298918962191166572986181981965998337591167599159129997195
|
||||||
|
5161697792393852322887583417693725518643111468281969197221126116117739823199999132753611955461991483
|
||||||
|
6748848121519929146139951181494977716178656879667787982537212682114283552983879198195439947113885979
|
||||||
|
8162766788818429134853376715291665789982415877811787277133682815985779596453652213379733961271558178
|
||||||
|
7126616955919123997999947924157132389218111416139312121275578993825788959911541852194817157964691211
|
||||||
|
8145196921476116692616113197789995261996944598741116866263325522282139715958136659697393892119667448
|
||||||
|
9763151993822121312993191662941511916997145299292999193935168979452131598797394513569918623184664781
|
||||||
|
2292147194129589895647189423118915917258999813964921785795452817643488469847272158199168247483795532
|
||||||
|
8559629983984149491384859997366788978721291219851118825772145961874767133913997798554453199924989818
|
||||||
|
1182466299236599621536199516511164491992491155296741794213949818647429481999868811793169519371262165
|
||||||
|
4738281697798982828461677528585949457922936232449965278919419114997399511378492966791946451772819131
|
||||||
|
1757396912274429287116228948911154651917537842154149919872599997971951639199787486133851179929798555
|
||||||
|
1719739825171841761948755899899216798392923289899987521533913487812899954886369899998971639512215499
|
||||||
|
8791281434118421465514992618674529217949339778941898165388344994151819153515931268975815718393699133
|
||||||
|
5931698111196917992731929569985187236913914645973813563987549997719875759193672475788621993978779973
|
||||||
|
1884255199381966237561622788671247184371139285597612245451393421737133245891898958424829971676219425
|
||||||
|
2583899597668762774732855241679313519878428388682177491132991946939823251369684298843866186992234148
|
||||||
|
5571952912139441554944189828841898317272294283772779929696126131222992624995317231851888338393316119
|
||||||
|
8975999266148778637445788139847923481453515261188263961114697957477262989851194731696756118191947696
|
||||||
|
4382229563773717134612151111919923747618491994839882891451393414319819915995472618861242184413895712
|
||||||
|
2111697733928869231956532219642919971371939921939182129518341429926954783299694818222137624318218193
|
||||||
|
7918331918611351816139112921322828652131814891298482791235912154914156276127996537498197874799924122
|
||||||
|
7836996594939159837193584991869184956399715111271353229592112889346822858939489744779468277719668577
|
||||||
|
|
||||||
|
###
|
||||||
48
input/day/16-example.http
Normal file
48
input/day/16-example.http
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
D2FE28
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
38006F45291200
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
EE00D40C823060
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
8A004A801A8002F478
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
620080001611562C8802118E34
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
C0015000016115A2E0802F182340
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
A0016C880162017C3686B18A3D4780
|
||||||
|
|
||||||
|
###
|
||||||
7
input/day/16.http
Normal file
7
input/day/16.http
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-16
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
4054460802532B12FEE8B180213B19FA5AA77601C010E4EC2571A9EDFE356C7008E7B141898C1F4E50DA7438C011D005E4F6E727B738FC40180CB3ED802323A8C3FED8C4E8844297D88C578C26008E004373BCA6B1C1C99945423798025800D0CFF7DC199C9094E35980253FB50A00D4C401B87104A0C8002171CE31C41201062C01393AE2F5BCF7B6E969F3C553F2F0A10091F2D719C00CD0401A8FB1C6340803308A0947B30056803361006615C468E4200E47E8411D26697FC3F91740094E164DFA0453F46899015002A6E39F3B9802B800D04A24CC763EDBB4AFF923A96ED4BDC01F87329FA491E08180253A4DE0084C5B7F5B978CC410012F9CFA84C93900A5135BD739835F00540010F8BF1D22A0803706E0A47B3009A587E7D5E4D3A59B4C00E9567300AE791E0DCA3C4A32CDBDC4830056639D57C00D4C401C8791162380021108E26C6D991D10082549218CDC671479A97233D43993D70056663FAC630CB44D2E380592FB93C4F40CA7D1A60FE64348039CE0069E5F565697D59424B92AF246AC065DB01812805AD901552004FDB801E200738016403CC000DD2E0053801E600700091A801ED20065E60071801A800AEB00151316450014388010B86105E13980350423F447200436164688A4001E0488AC90FCDF31074929452E7612B151803A200EC398670E8401B82D04E31880390463446520040A44AA71C25653B6F2FE80124C9FF18EDFCA109275A140289CDF7B3AEEB0C954F4B5FC7CD2623E859726FB6E57DA499EA77B6B68E0401D996D9C4292A881803926FB26232A133598A118023400FA4ADADD5A97CEEC0D37696FC0E6009D002A937B459BDA3CC7FFD65200F2E531581AD80230326E11F52DFAEAAA11DCC01091D8BE0039B296AB9CE5B576130053001529BE38CDF1D22C100509298B9950020B309B3098C002F419100226DC
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
6
input/day/17-example.http
Normal file
6
input/day/17-example.http
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-17
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
target area: x=20..30, y=-10..-5
|
||||||
|
|
||||||
|
###
|
||||||
6
input/day/17.http
Normal file
6
input/day/17.http
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-17
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
target area: x=48..70, y=-189..-148
|
||||||
|
|
||||||
|
###
|
||||||
Reference in New Issue
Block a user