Day 8: Resonant Collinearity
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
You are viewing a single thread.
View all comments 1 point
TypeScript
I was a little confuzzled with this one, but I managed to get it. :) Happy to know that I managed to reuse more of my code from previous days. I should write something to handle Vectors. It was sad to write my own basic, non-reusable thing.
Solution
import { AdventOfCodeSolutionFunction } from "./solutions";
// imported code:
export const check_coords = (grid: Array<Array<any>>, x: number, y: number) => {
return y >= grid.length ||
y < 0 ||
x >= grid[y].length ||
x < 0
}
export const makeGridFromMultilineString =
(input: string) => input.split("\n").map(st => st.trim()).map(v => v.split(""));
export const MakeEmptyGenericArray = <T>(length: number, fn: (index: number) => T) => {
const newArray = [];
let i = 0;
while (i++ < length)
newArray.push(fn(i));
return newArray;
}
export const MakeEmptyArray = (length: number) => MakeEmptyGenericArray(length, () => 0);
export const MakeEmpty2DArray = (x: number, y: number) => MakeEmptyArray(y).map(() => MakeEmptyArray(x));
// solution code
type v2 = [x: number, y: number];
const Sub = (x1: number, y1: number, x2: number, y2: number): v2 => {
return [x1 - x2, y1 - y2];
}
const Add = (x1: number, y1: number, x2: number, y2: number): v2 => {
return [x1 + x2, y1 + y2];
}
export const solution_8: AdventOfCodeSolutionFunction = (input) => {
const grid = makeGridFromMultilineString(input);
const nodes = new Map<string, Array<v2>>();
const nodeKinds: Array<string> = [];
const singleAntinodeLocations = MakeEmpty2DArray(grid.length, grid[0].length);
const resonantAntinodeLocations = MakeEmpty2DArray(grid.length, grid[0].length);
// find all the nodes
grid.forEach((row, y) => row.forEach((item, x) => {
if (item == ".")
return;
if (nodes.has(item))
nodes.get(item)!.push([x, y]);
else {
nodes.set(item, [[x, y]]);
nodeKinds.push(item);
}
}));
nodeKinds.forEach((nodeKind) => {
const nodesOfKind = nodes.get(nodeKind)!;
for (let bunn = 0; bunn < nodesOfKind.length; bunn++) {
const first = nodesOfKind[bunn];
for (let tort = bunn + 1; tort < nodesOfKind.length; tort++) {
// find antinode
const second = nodesOfKind[tort];
const diff = Sub(...first, ...second);
const [x1, y1] = Add(...first, ...diff);
const [x2, y2] = Sub(...second, ...diff);
if(!check_coords(singleAntinodeLocations, x1, y1)) singleAntinodeLocations[y1][x1]++;
if(!check_coords(singleAntinodeLocations, x2, y2)) singleAntinodeLocations[y2][x2]++;
// find all resonances
// starting
resonantAntinodeLocations[first[1]][first[0]]++;
resonantAntinodeLocations[second[1]][second[0]]++;
// go forward
let newFirst = [x1, y1] as v2;
while(!check_coords(resonantAntinodeLocations, ...newFirst)) {
let [x, y] = newFirst;
resonantAntinodeLocations[y][x]++;
newFirst = Add(...newFirst, ...diff);
}
// go back
newFirst = [x2, y2] as v2;
while(!check_coords(resonantAntinodeLocations, ...newFirst)) {
let [x, y] = newFirst;
resonantAntinodeLocations[y][x]++;
newFirst = Sub(...newFirst, ...diff);
}
}
}
});
const antinodeCount = (prev: number, curr: Array<number>) => prev + curr.reduce((prev, curr) => prev + (curr > 0 ? 1 : 0), 0);
const part_1 = singleAntinodeLocations.reduce<number>(antinodeCount, 0);
const part_2 = resonantAntinodeLocations.reduce<number>(antinodeCount, 0);
return {
part_1, //390
part_2, //1246
}
}
Loops on loops on loops on loops…