this post was submitted on 02 Dec 2024
41 points (97.7% liked)

Advent Of Code

885 readers
152 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 18 20 21 22
23 24 25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

Day 2: Red-Nosed Reports

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://blocks.programming.dev if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] [email protected] 2 points 2 days ago (1 children)

TypeScript

Solution

import { AdventOfCodeSolutionFunction } from "./solutions";


/**
 * this function evaluates the 
 * @param levels a list to check
 * @returns -1 if there is no errors, or the index of where there's an unsafe event
 */
export function EvaluateLineSafe(levels: Array<number>) {
    // this loop is the checking every number in the line
    let isIncreasing: boolean | null = null;
    for (let levelIndex = 1; levelIndex < levels.length; levelIndex++) {
        const prevLevel = levels[levelIndex - 1]; // previous
        const level = levels[levelIndex]; // current
        const diff = level - prevLevel; // difference
        const absDiff = Math.abs(diff); // absolute difference

        // check if increasing too much or not at all
        if (absDiff == 0 || absDiff > 3)
            return levelIndex; // go to the next report

        // set increasing if needed
        if (isIncreasing === null) {
            isIncreasing = diff > 0;
            continue; // compare the next numbers
        }

        //  check if increasing then decreasing 
        if (!(isIncreasing && diff > 0 || !isIncreasing && diff < 0))
            return levelIndex; // go to the next report
    }

    return -1;
}


export const solution_2: AdventOfCodeSolutionFunction = (input) => {
    const reports = input.split("\n");

    let safe = 0;
    let safe_damp = 0;

    // this loop is for every line
    main: for (let i = 0; i < reports.length; i++) {
        const report = reports[i].trim();
        if (!report)
            continue; // report is empty

        const levels = report.split(" ").map((v) => Number(v));

        const evaluation = EvaluateLineSafe(levels);
        if(evaluation == -1) {
            safe++;
            continue;
        }
        
        // search around where it failed
        for (let offset = evaluation - 2; offset <= evaluation + 2; offset++) {
            // delete an evaluation in accordance to the offset
            let newLevels = [...levels];
            newLevels.splice(offset, 1);
            const newEval = EvaluateLineSafe(newLevels);
            if(newEval == -1) {
                safe_damp++;
                continue main;
            }
        }
    }

    return `Part 1: ${safe} Part 2: ${safe + safe_damp}`;
}

God, I really wish my solutions weren't so convoluted. Also, this is an O(N^3) solution....

[โ€“] [email protected] 2 points 1 day ago (1 children)

I don't think your solution is O(N^3). Can you explain your reasoning?

[โ€“] [email protected] 1 points 1 day ago (1 children)
[โ€“] [email protected] 2 points 1 day ago (1 children)

It's not as simple as that. You can have 20 nested for loops with complexity of O(1) if all of them only ever finish one iteration.

Or you can have one for loop that iterates 2^N times.

[โ€“] [email protected] 1 points 1 day ago (2 children)

What do you think my complexity is?

I think it could be maybe O(n^2) because the other for loop which tries elements around the first error will only execute a constant of 5 times in the worst case? I'm unsure.

[โ€“] [email protected] 2 points 1 day ago

It's O(n).

If you look at each of the levels of all reports, you will access it a constant number of times: at most twice in each call to EvaluateLineSafe, and you will call EvaluateLineSafe at most six times for each report.

[โ€“] [email protected] 1 points 1 day ago

It really depends on what your parameter n is. If the only relevant size is the number of records (let's say that is n), then this solution takes time in O(n), because it loops over records only once at a time. This ignores the length of records by considering it constant.

If we also consider the maximum length of records (let's call it m), then your solution, and most others I've seen in this thread, has a time complexity in O(n * m^2) for part 2.