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

  • Rin@lemm.ee
    link
    fedilink
    arrow-up
    1
    ·
    1 month ago

    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…