/r/adventofcode

Photograph via snooOG

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.

🎄 Advent of Code 🎄

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.


Rules + More Info in

our community wiki


BEFORE YOU POST
If your post is even tangentially related to a daily puzzle, use our
STANDARDIZED POST TITLE FORMAT

Solution Megathreads

December 2024

Su M T W R F Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Previous years:
2023 | 2022 | 2021 | 2020 | 2019 | 2018 | 2017 | 2016 | 2015

Quick Search by Flair

Because you're lazy and we like making things easy for you. Except AoC.

Are you enjoying AoC?

Code should be fun, because otherwise it's just a job. If you'd like to support Advent of Code, please share it with all your friends, even the ones that are just learning to code! AoC is a fun, non-threatening way to work at your own pace to figure out how to apply problem-solving first, then work within a language's constraints.

If you really want to show your appreciation, donations are always appreciated. Any instances of currency will go to, in no particular order:

  • Server maintenance (hosting, bandwidth, etc.)
  • Bribes to Santa
  • Beer and sushi
  • Paper bags for /u/topaz2078 to breathe into so he doesn't hyperventilate onto another plane of (non-)existence

Support AoC

Thank you very much, and enjoy your month of code!

/r/adventofcode

131,403 Subscribers

9

Is F# the unsung hero of Advent of Code?

So, I’ve been diving into Advent of Code this year using F# (because why not, right?). I swear, F# feels like the language equivalent of a Swiss Army knife—compact, expressive, and surprisingly fun once you get past its functional quirks. But I’m starting to wonder: why doesn’t F# get more love when it comes to solving these puzzles? I get that it’s not as mainstream as Python or JavaScript, but with its pattern matching, immutability, and conciseness, I feel like it could be the secret weapon that nobody talks about.

Has anyone else given it a shot? Are there hidden gems in F# that make it the perfect language for AoC, or am I just romanticizing the functional side of things too much?

19 Comments
2025/02/02
16:56 UTC

4

[2024 Day16#1] [Common Lisp] - Works for examples, but not for input. Ideas?

So I've been stuck on Day 16 for a few days now. (I know I'm a little late to the party.) I went for the straightforward Dijikstra implementation of a breadth-first-search using a priority queue based on the total cost of a path, as well as a set of visited nodes so that we only visit each node once. Each node is uniquely identified by its position and direction. A node's neighbors are the square directly in front of it, as well as the same square but rotated 90 degrees clockwise or counter-clockwise. As soon as a path is found that reaches the end, we return it.

My solution works for the two examples.

I'm able to find a path for the problem input, but I'm getting the wrong cost.

I don't know what I'm doing wrong or where to look. I've printed out the path it takes and it looks like a reasonably short path (follows the edge of the map, doesn't backtrack).

My code is in this gist

Any help, or hints, or ideas of what I could try would be appreciated.

11 Comments
2025/02/01
22:43 UTC

3

[2024 Day 7] Example for Part 2: 7290: 6 8 6 15 can be made true using 6 * 8 || 6 * 15?

I don't understand the example that is given.

4 Comments
2025/02/01
18:50 UTC

5

[2023 Day 17][TypeScript] Solution too slow even by ditching steps and always turning

It's been taking me quite a few days to figure out a working solution and optimize it. I've got it down from 5 minutes to 10 seconds for part 1, but since some people were able to reach less-than-a-second solutions, there must be something wrong with mine.

My solution uses the standard Dijkstra's algorithm, with a min binary heap for the queue, full of nodes assigned to Infinity. The graph is pre-built before running the algorithm, it takes 300 ms. I didn't account for steps when building the graph, choosing to take a turn on each of the nodes. That seems to be the most efficient approach as described by many posts, since it has the fewest nodes possible. It did reduce the runtime by 97% afterall, from when I was accounting for steps.

I would be very grateful if someone was able to give me more suggestions, spot an issue, or maybe assure me this is as good as it gets. Here's the binary heap code. I'm sorry for asking about such an old challenge and for how many comments and redundant code there is, it's because I'm trying to get it to work before polishing.

import { BinaryHeap } from "#root/utils/biheap.js";
import { sum } from "#root/utils/arrayx.js";

type Graph = {
    nodes: string[];
    edges: Map<string, Map<string, number>>;
};

export function solve(map: Input): Solution {
    const grid = map.split("\n").map(line => line.split("").map(Number));

    const part1 = pathfindBasicCrucibles(grid);
    const part2 = 0;

    return { part1, part2 };
}

function pathfindBasicCrucibles(grid: number[][]): number {
    const width = grid[0].length;
    const height = grid.length;
    const targets = [
        `${width - 1},${height - 1},up`,
        `${width - 1},${height - 1},down`,
        `${width - 1},${height - 1},left`,
        `${width - 1},${height - 1},right`,
    ];

    const start = Date.now()
    const graph = buildBasicCauldronGraph(grid);
    const { distance } = dijkstra(graph, "0,0,null", targets.includes.bind(targets));
    const targetsHeatloss = targets.map(t => distance.get(t) ?? Infinity);

    return Math.min(...targetsHeatloss);
}

function buildBasicCauldronGraph(grid: number[][]): Graph {
    const width = grid[0].length;
    const height = grid.length;

    const edges = new Map<string, Map<string, number>>();
    const nodes = [];

    // Set a starting point
    const start = "0,0,null"
    nodes.push(start);
    edges.set(start, new Map());
    edges.get(start)!.set("0,1,down", grid[1][0]);
    edges.get(start)!.set("0,2,down", grid[1][0] + grid[2][0]);
    edges.get(start)!.set("0,3,down", grid[1][0] + grid[2][0] + grid[3][0]);
    edges.get(start)!.set("1,0,right", grid[0][1]);
    edges.get(start)!.set("2,0,right", grid[0][1] + grid[0][2]);
    edges.get(start)!.set("3,0,right", grid[0][1] + grid[0][2] + grid[0][3]);

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const states = [
                `${x},${y},up`,
                `${x},${y},down`,
                `${x},${y},left`,
                `${x},${y},right`,
            ];

            nodes.push(...states);
            states.forEach(state => edges.set(state, new Map()));
        }
    }

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            if (grid[y - 1]) {
                const dy = y - 1;
                const weight = grid.slice(dy, y).flatMap(row => row[x])[sum]();
                edges.get(`${x},${y},left`)!.set(`${x},${dy},up`, weight);
                edges.get(`${x},${y},right`)!.set(`${x},${dy},up`, weight);
            }
        
            if (grid[y - 2]) {
                const dy = y - 2;
                const weight = grid.slice(dy, y).flatMap(row => row[x])[sum]();
                edges.get(`${x},${y},left`)!.set(`${x},${dy},up`, weight);
                edges.get(`${x},${y},right`)!.set(`${x},${dy},up`, weight);
            }
        
            if (grid[y - 3]) {
                const dy = y - 3;
                const weight = grid.slice(dy, y).flatMap(row => row[x])[sum]();
                edges.get(`${x},${y},left`)!.set(`${x},${dy},up`, weight);
                edges.get(`${x},${y},right`)!.set(`${x},${dy},up`, weight);
            }
        
            if (grid[y + 1]) {
                const dy = y + 1;
                const weight = grid.slice(y + 1, dy + 1).flatMap(row => row[x])[sum]();
                edges.get(`${x},${y},left`)!.set(`${x},${dy},down`, weight);
                edges.get(`${x},${y},right`)!.set(`${x},${dy},down`, weight);
            }
        
            if (grid[y + 2]) {
                const dy = y + 2;
                const weight = grid.slice(y + 1, dy + 1).flatMap(row => row[x])[sum]();
                edges.get(`${x},${y},left`)!.set(`${x},${dy},down`, weight);
                edges.get(`${x},${y},right`)!.set(`${x},${dy},down`, weight);
            }
        
            if (grid[y + 3]) {
                const dy = y + 3;
                const weight = grid.slice(y + 1, dy + 1).flatMap(row => row[x])[sum]();
                edges.get(`${x},${y},left`)!.set(`${x},${dy},down`, weight);
                edges.get(`${x},${y},right`)!.set(`${x},${dy},down`, weight);
            }
        
            if (grid[y][x - 1]) {
                const dx = x - 1;
                const weight = grid[y].slice(dx, x)[sum]();
                edges.get(`${x},${y},up`)!.set(`${dx},${y},left`, weight);
                edges.get(`${x},${y},down`)!.set(`${dx},${y},left`, weight);
            }
        
            if (grid[y][x - 2]) {
                const dx = x - 2;
                const weight = grid[y].slice(dx, x)[sum]();
                edges.get(`${x},${y},up`)!.set(`${dx},${y},left`, weight);
                edges.get(`${x},${y},down`)!.set(`${dx},${y},left`, weight);
            }

            if (grid[y][x - 3]) {
                const dx = x - 3;
                const weight = grid[y].slice(dx, x)[sum]();
                edges.get(`${x},${y},up`)!.set(`${dx},${y},left`, weight);
                edges.get(`${x},${y},down`)!.set(`${dx},${y},left`, weight);
            }

            if (grid[y][x + 1]) {
                const dx = x + 1;
                const weight = grid[y].slice(x + 1, dx + 1)[sum]();
                edges.get(`${x},${y},up`)!.set(`${dx},${y},right`, weight);
                edges.get(`${x},${y},down`)!.set(`${dx},${y},right`, weight);
            }
        
            if (grid[y][x + 2]) {
                const dx = x + 2;
                const weight = grid[y].slice(x + 1, dx + 1)[sum]();
                edges.get(`${x},${y},up`)!.set(`${dx},${y},right`, weight);
                edges.get(`${x},${y},down`)!.set(`${dx},${y},right`, weight);
            }

            if (grid[y][x + 3]) {
                const dx = x + 3;
                const weight = grid[y].slice(x + 1, dx + 1)[sum]();
                edges.get(`${x},${y},up`)!.set(`${dx},${y},right`, weight);
                edges.get(`${x},${y},down`)!.set(`${dx},${y},right`, weight);
            }
        }
    }

    return { nodes, edges };
}

function dijkstra(graph: Graph, start: string, isTarget: (node: string) => boolean = () => false): { distance: Map<string, number>, previous: Map<string, string> } {
    const previous = new Map<string, string>();
    const distance = new Map<string, number>(graph.nodes.map(node => [node, Infinity]));
    distance.set(start, 0);

    const queue = new BinaryHeap(graph.nodes, (a, b) => distance.get(a)! < distance.get(b)!);
    let curr;

    while ((curr = queue.remove()) != null && !isTarget(curr)) {
        for (const [neighbor, weight] of graph.edges.get(curr)!.entries()) {
            const dist = distance.get(curr)! + weight;

            if (dist < distance.get(neighbor)!) {
                distance.set(neighbor, dist);
                previous.set(neighbor, curr);
                queue.upHeapify(neighbor);
            }
        }
    }

    return { distance, previous };
}
22 Comments
2025/02/01
02:04 UTC

4

[2024 Day 3 (Part 2)] Can someone tell why it isn't working?

The problem is as snugar_i mentioned.


import re

def process(line):
    res, inc = 0, True
    match = re.finditer(r"mul\([0-9]{1,3},[0-9]{1,3}\)", line)
    do = [(m.start(), True) for m in re.finditer(r"do\(\)", line)]
    dont = [(m.start(), False) for m in re.finditer(r"don\'t\(\)", line)]
    i, com = 0, sorted(do + dont, key=lambda x: x[0])

    for m in match:
        while i < len(com) and com[i][0] < m.start():
            inc = com[i][1]
            i += 1
        if inc:
            a = m.group()[4:-1].split(",")
            res += int(a[0]) * int(a[1])
    return res


def main():
    res = 0
    with open("input.txt", "r") as file:
        for line in file:
            res += process(line)
    print(res)


if __name__ == "__main__":
    main()
7 Comments
2025/01/31
17:48 UTC

5

[2024 Day 21 Part 2] Stuck on how to find a solution

Hi all

code here

I've been struggling with with day 21 part 2 this year, and I was hoping I could get some guidance on how to improve performance. I guess that's the main point of part 2.

Initially I had a very slow solution involving a min heap, and solving part 1 took 15 minutes. I've since implemented memoization and moved away from a min heap and I've brought the performance to a much faster 0.064s to solve part 1.

I'm still struggling with part 2, for two reasons I think:

My runtime is too slow (takes forever basically) and my string construction mechanism makes me run out of RAM.

I know for a fact that I need to avoid storing whole string representation of paths and instead need to store start and end destinations. I thought I could prune the best path by solving a couple of levels up, and then having only one path but this solution is not working.

How could I store start and end destinations instead if some of the paths have multiple possible ways to get there? I've discarded zig-zags after reading this reddit.

Is my code salvageable? What changes could I make to reach the right level of performance to pass part 2? Should I rewrite it from scratch?

Should I permanently retire from AoC? Shall I change careers and dedicate my llife to pineapple farming?

8 Comments
2025/01/31
05:19 UTC

116

10 years, 500 stars with my own language and compiler

I started Advent of Code back at the beginning, in 2015, and it has been a high-point of the holiday season every year since. I experimented with different programming languages each year, doing many in Haskell. In 2020, David Turner released his programming language Miranda, and I started using that for Advent of Code. However, I grew frustrated with the runtime of solutions, particularly some hard ones at the end of each year. So I started a big project of writing my own compiler for it, which eventually turned into Miranda2, a pure, lazy, functional programming language and self-hosting compiler.

Many thanks to Eric and all his helpers for providing the kickstart for this project.

advent of code repo

Miranda2 repo

8 Comments
2025/01/30
19:35 UTC

3

[2024 Day 15 (Part 2)] [C#] Passing Example But Not Input

Link to puzzle

Hello, I'm able to get the correct answers for Part 1 and Part 2 (10092 and 9021) with the example input given in the puzzle description. I'm also able to get the correct answer for part 1 of my puzzle input but can't seem to figure out why my answer for part 2 is too low. I believe something is wrong with my logic pushing wide boxes vertically? If anyone could help me figure out what's wrong, I'd appreciate you greatly!

My Code

6 Comments
2025/01/30
03:07 UTC

11

[2024 Day 23] Easter Egg Christmas Tree

I was finally getting around to implementing a solution to day 23, making some visuals along the way. I had done plain 2D ones like this one, and a cluster-colored 3D one. I was also checking out the other amazing visuals made by the community (seriously, awesome stuff; never stop). Then when I saw /u/Busy-Championship891's comment:

well here I thought it would be a Christmas tree. :p

It hit me: not only is it a Christmas Tree, but the star is the "answer"!!! (the red/green dots are just random)

Hat's off to the AoC team, this was such a cool easter egg!

2 Comments
2025/01/28
22:16 UTC

8

[2018 day 23] Well, that was "fun"...

Had a look at this as one of the 2018 problems marked as "insane" in the Reddit post rating problem difficulties.

Incrementally ground my way to a solution; my strategy was to subdivide the cube, slowed down by having to have quite generous "margins" for "if I've sampled 1 point in this cube, what's the best possible score for anything in the cube?". When things failed/didn't work and I'd have to adapt / amend my solution, I "cheated" by initialising my "bestN" (the best "number of sensors in range" found so far) variable to the best score I'd found in the previous run (so I could exclude more cube subsections earlier the next time).

So I finally got something that worked (**not** in the recommended 15 seconds but at this point I didn't care), and found my code had a bug at the end so that it infinite looped doing passes with grid-spacing zero (and no work to do) and printing the current bestN each time so that the actual answer was lost off the top of console.

So I figured, I'll fix the exit condition, and reinit with the "winning" version of bestN.

What surprised me was that using **that** value of bestN as an initial value basically gave me an instant solution. Which made me think (I'm not sure 100% correctly), "Damn, the extra 'margin' you have to allow because Manhatten distance isn't axis aligned really screws you. I wonder if anyone used a change of co-ordinates to have a coordinate scheme where it doesn't matter". And then found

https://www.reddit.com/r/adventofcode/comments/a9co1u/comment/ecmpxad/

I'd heard 2018 is the worst year; I've ground backwards through 2023-2019 (complete) since Jan and as 2018 coincided with feeling a bit burnt out on AOC I've been skipping some of the less interesting looking ones for now. I haven't found it *too* bad, but it possibly has the highest number of "I manually fiddled with stuff to get answers" solutions that don't really work autonomously (the "early version of intcode" problems, for example).

On t'other hand, I found those (intcode) problems more interesting in a "I'm an assembler hacker" way than I did for 2019 (where the volume of intcode generally meant "get your interpreter working correctly and don't worry about how the intcode works"). When I had r2 going up by 1 every 5 cycles and it needed to reach 1234567, it was quite satisfying to "manually" set it to 1234566 and single step through to see what happened next.

12 Comments
2025/01/28
21:08 UTC

6

[2024 day16 part1] the answer is wrong with my input, but it can solve my friend's input, why?

7 Comments
2025/01/28
07:15 UTC

1

[2024 day6 part2] I couldn't figure out what's wrong for my solution...


   static int[][] DIR = new int[][]{
        {0, -1},
        {1, 0},
        {0, 1},
        {-1, 0}
    };
    static int RES2 = 0;
    static char FAKE_WALL = '@';
    public static int solutionForPartTwo(Character[][] map) {
        int x = 0;
        int y = 0;
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[i].length; j++) {
                if (Objects.equals(map[i][j], GUARD)) {
                    x = j;
                    y = i;
                }
            }
        }
        map[y][x] = MARK;        
        dfs2(map, x, y, 0);
        return RES2;
    }

    static Character[][] copyArr;
    static int COUNT = 0;
    static int LIMIT = 10000;
    static boolean USE_FAKE_WALL = false;

    public static void dfs2(Character[][] map, int x, int y, int dir) {
        if (COUNT >= LIMIT) {
            RES2++;
            return;
        }

        int[] dirArr = DIR[dir];
        int nextX = x + dirArr[0];
        int nextY = y + dirArr[1];
        int nextDir = (dir + 1) % 4;

        if (nextY >= LENGTH_Y || nextY < 0 || nextX >= LENGTH_X || nextX < 0) {
            return;
        }

        if (Objects.equals(map[nextY][nextX], WALL) || Objects.equals(map[nextY][nextX], FAKE_WALL)) {
            dfs2(map, x, y, nextDir);
        } else {
            if (!USE_FAKE_WALL) {
                USE_FAKE_WALL = true;
                copyArr = Day16.deepCopyArray(map);
                copyArr[nextY][nextX] = FAKE_WALL;

                dfs2(copyArr, x, y, nextDir);
                USE_FAKE_WALL = false;
                COUNT = 0;
            } else {
                COUNT++;
            }
            map[nextY][nextX] = MARK;
            dfs2(map, nextX, nextY, dir);
        }
    }
8 Comments
2025/01/27
09:56 UTC

4

[2024] [PHP] Countdown for my code done

And my countdown of going through my code for 2024 is over. Several days involved me using spreadsheets, paper etc.

https://stuff.ommadawn.dk/2025/01/26/advent-of-code-day-26/

6 Comments
2025/01/27
09:12 UTC

7

[2020 day 19] - understanding the examples

In part 2 of https://adventofcode.com/2020/day/19, they mention that `babbbbaabbbbbabbbbbbaabaaabaaa` will pass the modified rules.

I fail to pass this string, but I find it really hard to workout which set of rules will expand to that. Did you guys have any tricks to be able to do it on paper?

5 Comments
2025/01/26
16:26 UTC

33

[Upping the Ante] [2024 Day *] Advent of Code on MCUs

Hi everybody.

Here are the programs to solve Advent of Code 2024 running on some MCUs I own: this is the repository if you are curious

The boards / MCUs I used are the following:

  • Arduino 33 BLE Sense (Nordic 52840)
  • ESP32
  • ESP32C3
  • ESP32C6
  • nrf52840-dk (Nordic 52840)
  • Nucleo-h743-zi (STM32H7)
  • RP-Pico
  • RP-Pico2
  • STM32F3Discovery (STM32F3)

https://preview.redd.it/8lsa0yon56fe1.jpg?width=3000&format=pjpg&auto=webp&s=f67a81cacd02c2c2bb48eab98bed12e8826a96f7

With my current implementation only the RP-Pico2 and STM32H7 are able to execute the code to determine every solution: the other MCUs do not have enough memory available (I need to double check the esp32c6 but I suspect the problem is the HAL I am using).

Each MCU has flashed all the necessary code to solve all the problems.

Each MCU receives in input through the serial (UART or USB) the input in the format:

START INPUT DAY: <XY>
<input>
END INPUT

The MCU returns on the same serial the result of part 1 and 2 and the overall execution times or "unsupported day" if the particular day is not supported.

To check that I do not have stack smash I normally do one or two test runs going to progressively pass all the inputs and take the times of the third / fourth run.

If you want to take a look at the code, propose some PR to improve the coverage of supported days or add some more MCUs, any help is welcome.

In the next table there are the execution time in milliseconds.

The execution time of day 21 is not zero but some microseconds: I pre-calculated at "compile time" the lookup tables to obtain the solution of part 1 and 2.

dayarduino33blesense.msesp32.msesp32c3.msesp32c6.msnrf52840dk.msnucleoh743zi.mspico.mspico2.msstm32f3discovery.ms
13712131249142612
2461514146417312158
31166618511616
424879401019834
597312931123326753
61022661073837380112729354293053517
71372751144828492217640564613911446716618
8844310393
91149389
10401713125414381449
11425403449508
1210354023543581263353800311
13541717156519442260
143388313288170731759446192142653401020683
1585292525113305828
16140133
1742215131
18119444141148399474
1936621456168118005412195028642090
20967938914956525213215401163294197
21000000000
22422626703014
23429307393386536162655200
247427302999284929
25201198257197
4 Comments
2025/01/25
16:46 UTC

4

[2023 Day 21 (Part 2] Diamond for dummies

Hi, I don't get this whole diamond thing at all. What the heck am I supposed to do?? How can I scale the whole thing up if I start with one single starting point, reach the borders and got a whole lot of "new" starting points for the outer tiles?

5 Comments
2025/01/25
14:52 UTC

0

Doubt in Day 3, Q2

Hi,
I was trying to solve the 2nd part of Day 3 Problem. In which we have to enable and disable multiplication according to when do() comes and don't() comes.
I wrote a solution in C++ using regular Expressions, but the tests cases I thought of are working fine. So I am unsure whats the mistake here.

#include <algorithm>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
#include <unordered_set>

// Test =>
// xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))

int64_t solve_substring(const std::string &str, int startIdx, int endIdx) {
  if (startIdx >= endIdx) {
    return 0;
  }
  int64_t result{0};
  std::regex mulPat(R"(mul\((\d+),(\d+)\))");

  auto match_start = std::sregex_iterator(str.begin() + startIdx,
                                          str.begin() + endIdx, mulPat);
  auto match_end = std::sregex_iterator();

  for (auto it = match_start; it != match_end; ++it) {
    std::smatch match = *it;
    int64_t val1 = std::stoll(match[1].str());
    int64_t val2 = std::stoll(match[2].str());

    result += val1 * val2;
  }
  return result;
}

int64_t solve(const std::string &input) {
    int64_t result{0};
    std::regex doPat(R"(do\(\))");
    std::regex dontPat(R"(don't\(\))");

    auto pDoMatch = std::sregex_iterator(input.begin(), input.end(), doPat);
    auto pEnd = std::sregex_iterator();
    auto pDontMatch = std::sregex_iterator(input.begin(), input.end(), dontPat);

    std::vector<size_t> doIdx{0}, dontIdx{input.size()};

    auto trav = pDoMatch;
    while (trav != pEnd) {
        doIdx.push_back(trav->position());
        ++trav;
    }

    trav = pDontMatch;
    while (trav != pEnd) {
        dontIdx.push_back(trav->position());
        ++trav;
    }

    std::sort(doIdx.begin(), doIdx.end());
    std::sort(dontIdx.begin(), dontIdx.end());

    size_t i{0}, j{0};
    while (i < doIdx.size() && j < dontIdx.size()) {
        size_t start = doIdx[i];
        size_t end = dontIdx[j];

        if (start < end) {
            result += solve_substring(input, start, end);
        } else while (start >= end) {
			++j;
			end = dontIdx[j];
        }
        ++i;
    }

    return result;
}

int main(int argc, char **argv) {
  if (argc < 2) {
    return -1;
  }

  std::ifstream ipFile(argv[1]);
  std::string input{};

  std::string line{};

  while (std::getline(ipFile, line)) {
    input += line;
  }

  auto result = solve(input);
  std::cout << result << std::endl;

  return 0;
}

I am storing the indexes of do() and don't() in an array, sort it, and then compute the answer within that subarray and add them up.

9 Comments
2025/01/25
10:11 UTC

0

[2024 day 17 (part 2)] Confused why my algo does not work (rust)

It seems I made a wrong assertion in my logic... But I cannot find which one...

It can find answer for [3, 0] but not for [5,3,0].

My algo is pretty simple... But the lack of test cannot make me sure there is no stupid bug...

here is my algo : https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ff0938a399b828bc314cb49b88834ed7

Can anyone help me with that ?
---

edit: I've upload it to playground

---

Ok the output is mod 8... so only %8 of b is interesting us... So the bug was is the `next_b` which should be `next_b_output`... : https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ffa180e83a0cd8d000125f7cbf223039

5 Comments
2025/01/25
09:29 UTC

19

[2024 Day 11 (Part 2)] Well, that was embarrassing. There's a lesson here.

Started going back to finish 2024 about a week ago, beginning with the Part 2 of Day 11 which I never managed to run. I was trying all kinds of "clever" ways to save time in the counting, such as caching the sequence you get by expanding different values. Doing this for fun, I'm only spending a couple hours a day fiddling with it but still it was taking forever to debug and then I kept running into scaling issues anyway. Never got past iteration 55 before giving up.

So finally I threw in the towel when my latest attempt failed. And then I had a thought while walking the dog (no connection, that's just my moment in the day when my subconscious works on problems). "No, it can't be that simple, can it?" I asked the dog. But it was. Got home, threw out my fancy buggy classes and implemented the new solution, which worked in under 0.1 seconds. Aargh.

There's some kind of lesson here about spending days and days trying to implement a complicated algorithm when there's a much simpler one staring you in the face.

The simple approach: >!You don't have to keep track of every individual stone. There are duplicates. Lots and lots of duplicates.!<

Remaining: Day 15 part 2 (not hard, but I ran out of programming time) and Days 19-26 (real life caught up with me).

7 Comments
2025/01/24
18:11 UTC

0

I need to print to a readable text file, any suggestions?

I have a program that I developed to manage inventory, but the sales team uses NetSuite to sell the orders. They can print the order out, but I need a way to integrate this with my app. I was thinking of printing to a text file and then pulling the data from that, but everything I do doesn't seem to give me a fully readable output file. I would like a few suggestions.

9 Comments
2025/01/24
12:36 UTC

4

[2024 Day 5 (Part 2)] [C++ / CPP] Seeking Help

Task one was straight forward, task two not so much.

My logic:

while no swaps occur
check each page order to see if it contain one of the instructions,
if it contains and not in correct order, swap them. set swap flag to true

if wasSwapped, then add the middle of that line to the total sum. Not sure where I'm messing up. Please help.

Full source file on GitHub.Gist

double taskTwo(std::vector<std::pair<int, int>>* input_1, std::vector<std::vector<int>>* input_2) {
    std::sort(input_1->begin(), input_1->end());
    for (std::pair<int,int>& rule : *input_1) {
        std::cout << rule.first << '|' << rule.second << std::endl;
    }
    std::cout << std::endl;

    double result = 0;
    for (auto& pages : *input_2) {
        bool swapped = false;
        
        for (auto& rule : *input_1) {
            std::vector<int>::iterator ruleOne = std::find(pages.begin(), pages.end(), rule.first);
            std::vector<int>::iterator ruleTwo = std::find(pages.begin(), pages.end(), rule.second);
            
            if ((ruleOne != pages.end() && ruleTwo != pages.end()) && !(ruleOne < ruleTwo)) {
                swapped = true;

                int indexOne = std::distance(pages.begin(), ruleOne);
                int indexTwo = std::distance(pages.begin(), ruleTwo);

                std::swap(pages[indexOne], pages[indexTwo]);
            }
        }

        if (swapped) {
            result += pages[pages.size()/2];  
            for (int& page : pages) {
                std::cout << page << ',';
            }
            std::cout << std::endl;
        } 
    }
    return result;
}
13 Comments
2025/01/23
17:21 UTC

1

[2019 Day 17] Trying to track down an intcode bug

Got a weird one on this:

My IntCode implementation has run all the previous problems fine.

But for part 1, it seems that the decision for scaffold/no-scaffold is inverted. If I swap # with . I get a sensible output (although I still get an X for the robot position), and I can get the correct answer for part 1 on that basis.

I've also solved the "problem" part of part 2, but I'm guessing I'm going to be out of luck on getting the ASCII module to give me a sensible number since it thinks there's scaffolding where there's spaces and vice-versa.

(I haven't actually tried, because it feels I should fix the bug first anyhow).

I've logged the executed opcodes for both this and day 9, and nothing pops out at me as "this case was never tested during day 9" (e.g. day 17 uses opcode 208 and day 9 doesn't, but day 9 does use opcode 209 and opcode 1008 and between them you'd think that would cover opcode 208).

I've got general debugging output for each opcode as well, but if I turn that on I feel I'm somewhat drowning in noise.

I realise it's hard to help without an implementation, but any suggestions would be appreciated. In particular if there's anything about the specific problem I might have missed (e.g. part 2 has you alter the first value in the program). I didn't see anything like that for part 1 but I'm doubting myself as this "feels" more like a "the program you are executing isn't quite right" than a "your execution implementation isn't quite right".

Thanks in advance...

12 Comments
2025/01/22
23:43 UTC

5

[2024 day17] Higher Register number issue

Hi,

My program works fine for example data because the Register values are so small.
However, in the real data input for such a large number below , how am I supposed to process instruction (adv) where it involves (22817223 / (2^22817223))?

Register A: 22817223
4 Comments
2025/01/22
22:55 UTC

8

[2016 day 19] part 1 and part 2 analytical solutions

Hello,

While doing 2016 day 19, i saw many solutions using algoritms and even data structures.
I searched for Josephus wikipedia article with most algoritms in O(n).

But we can do better. We can have O(1) solutions for both part one and two.

The part one is strait forward by looking at wikipedia article (using rust) :

fn josephus(elves: usize) -> usize {
    // elves = 2^m + rest so we compute elves_scale = 2^m
    let elves_scale = 2_usize.pow(elves.ilog(2));
    2 * (elves - elves_scale) + 1
}

Now for part2, i needed to dig into the output and discovered a pattern that scaled with power of 3 but with terms jumping from 1, 2...n, n+2, n+4 when the number of elves is lower than 2 times the scaling factor.
So the trick to align them is to use the relu function used in neural networks (it's just relu(x) = max(0,x) )

So here is the solution (still using rust) :

fn josephus_midle(elves: isize) -> isize {
    // elves = 3^m + rest so we compute elves_scale = 3^m
    let elves_scale = 3_isize.pow(elves.ilog(3));
    if elves == elves_scale {
        elves
    } else {
        elves - elves_scale + 0.max(elves - 2 * elves_scale)
    }
}

EDIT: part 1 using bit manipulations instead of maths functions:

fn josephus(elves: usize) -> usize {
    let elves_scale = 1 << (usize::BITS - elves.leading_zeros() - 1);
    ((elves & (elves_scale - 1)) << 1) | 1
}

or even simpler :

fn josephus(elves: usize) -> usize {
    let shift = elves.leading_zeros();
    elves << shift + 1 >> shift | 1
}
4 Comments
2025/01/22
21:48 UTC

9

I'd like to know if this is a valid cheat.

Hello everyone, In this day20 of 2024 part 2 question I believe my solution giving this as output is a false positive.

This below is a cheating path where the current (S) is at cordinate (1,1) and decides to go through top wall (@) with cordinates (0,1) So the cheating path becoming going reverse via (S) and straight down and stopping at E with cordinates (10,1). Could this be whats giving me more totals for some cheat distances?

#@#############

#S..#...#.....#

#.#.#.#.#.###.#

#.#...#.#.#...#

#######.#.#.###

#######.#.#...#

#######.#.###.#

###...#...#...#

###.#######.###

#...###...#...#

#E#####.#.###.#

#.#...#.#.#...#

#.#.#.#.#.#.###

#...#...#...###

###############

13 Comments
2025/01/22
07:58 UTC

3

Year 2018, Day 15 - My elf dodge an attack

I've worked on this for some days now, but can't find where things goes wrong.

My algorithm solves the initial examples as described, but when it comes to the additional start-end examples things goes wrong.

Take this example:

╭────────────────────────────────────────────╮
│                                            │
│  #######       #######                     │
│  #G..#E#       #...#E#   E(200)            │
│  #E#E.E#       #E#...#   E(197)            │
│  #G.##.#  -->  #.E##.#   E(185)            │
│  #...#E#       #E..#E#   E(200), E(200)    │
│  #...E.#       #.....#                     │
│  #######       #######                     │
│                                            │
│  Combat ends after 37 full rounds          │
│  Elves win with 982 total hit points left  │
│  Outcome: 37 * 982 = 36334                 │
│                                            │
│                                            │
╰────────────────────────────────────────────╯

When playing out this scenario, the game ends in round 38, but the middle elf dodges a stab somehow:

   0123456
 0 #######
 1 #0..#1#   G0(200), E1(200)
 2 #2#3.4#   E2(200), E3(200), E4(200)
 3 #5.##.#   G5(200)
 4 #...#6#   E6(200)
 5 #...7.#   E7(200)
 6 #######
After 1 rounds:
   0123456
 0 #######
 1 #0.3#1#   G0(197), E3(200), E1(200)
 2 #2#..4#   E2(194), E4(200)
 3 #5.##.#   G5(200)
 4 #...#6#   E6(200)
 5 #..7..#   E7(200)
 6 #######
After 2 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(191), E3(200), E1(200)
 2 #2#..4#   E2(188), E4(200)
 3 #5.##.#   G5(200)
 4 #..7#6#   E7(200), E6(200)
 5 #.....#
 6 #######
After 3 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(185), E3(200), E1(200)
 2 #2#..4#   E2(182), E4(200)
 3 #5.##.#   G5(200)
 4 #.7.#.#   E7(200)
 5 #....6#   E6(200)
 6 #######
After 4 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(179), E3(200), E1(200)
 2 #2#..4#   E2(176), E4(200)
 3 #57##.#   G5(197), E7(200)
 4 #...#.#
 5 #...6.#   E6(200)
 6 #######
After 5 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(173), E3(200), E1(200)
 2 #2#..4#   E2(170), E4(200)
 3 #57##.#   G5(194), E7(200)
 4 #...#.#
 5 #..6..#   E6(200)
 6 #######
After 6 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(167), E3(200), E1(200)
 2 #2#..4#   E2(164), E4(200)
 3 #57##.#   G5(191), E7(200)
 4 #..6#.#   E6(200)
 5 #.....#
 6 #######
After 7 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(161), E3(200), E1(200)
 2 #2#...#   E2(158)
 3 #57##4#   G5(188), E7(200), E4(200)
 4 #.6.#.#   E6(200)
 5 #.....#
 6 #######
After 8 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(155), E3(200), E1(200)
 2 #2#...#   E2(152)
 3 #57##.#   G5(182), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 9 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(149), E3(200), E1(200)
 2 #2#...#   E2(146)
 3 #57##.#   G5(176), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 10 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(143), E3(200), E1(200)
 2 #2#...#   E2(140)
 3 #57##.#   G5(170), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 11 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(137), E3(200), E1(200)
 2 #2#...#   E2(134)
 3 #57##.#   G5(164), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 12 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(131), E3(200), E1(200)
 2 #2#...#   E2(128)
 3 #57##.#   G5(158), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 13 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(125), E3(200), E1(200)
 2 #2#...#   E2(122)
 3 #57##.#   G5(152), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 14 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(119), E3(200), E1(200)
 2 #2#...#   E2(116)
 3 #57##.#   G5(146), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 15 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(113), E3(200), E1(200)
 2 #2#...#   E2(110)
 3 #57##.#   G5(140), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 16 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(107), E3(200), E1(200)
 2 #2#...#   E2(104)
 3 #57##.#   G5(134), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 17 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(101), E3(200), E1(200)
 2 #2#...#   E2(98)
 3 #57##.#   G5(128), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 18 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(95), E3(200), E1(200)
 2 #2#...#   E2(92)
 3 #57##.#   G5(122), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 19 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(89), E3(200), E1(200)
 2 #2#...#   E2(86)
 3 #57##.#   G5(116), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 20 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(83), E3(200), E1(200)
 2 #2#...#   E2(80)
 3 #57##.#   G5(110), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 21 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(77), E3(200), E1(200)
 2 #2#...#   E2(74)
 3 #57##.#   G5(104), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 22 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(71), E3(200), E1(200)
 2 #2#...#   E2(68)
 3 #57##.#   G5(98), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 23 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(65), E3(200), E1(200)
 2 #2#...#   E2(62)
 3 #57##.#   G5(92), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 24 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(59), E3(200), E1(200)
 2 #2#...#   E2(56)
 3 #57##.#   G5(86), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 25 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(53), E3(200), E1(200)
 2 #2#...#   E2(50)
 3 #57##.#   G5(80), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 26 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(47), E3(200), E1(200)
 2 #2#...#   E2(44)
 3 #57##.#   G5(74), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 27 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(41), E3(200), E1(200)
 2 #2#...#   E2(38)
 3 #57##.#   G5(68), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 28 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(35), E3(200), E1(200)
 2 #2#...#   E2(32)
 3 #57##.#   G5(62), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 29 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(29), E3(200), E1(200)
 2 #2#...#   E2(26)
 3 #57##.#   G5(56), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 30 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(23), E3(200), E1(200)
 2 #2#...#   E2(20)
 3 #57##.#   G5(50), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 31 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(17), E3(200), E1(200)
 2 #2#...#   E2(14)
 3 #57##.#   G5(44), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 32 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(11), E3(200), E1(200)
 2 #2#...#   E2(8)
 3 #57##.#   G5(38), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 33 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(5), E3(200), E1(200)
 2 #2#...#   E2(2)
 3 #57##.#   G5(32), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 34 rounds:
   0123456
 0 #######
 1 #03.#1#   G0(2), E3(200), E1(200)
 2 #.#...#
 3 #57##.#   G5(26), E7(200)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 35 rounds:
   0123456
 0 #######
 1 #.3.#1#   E3(197), E1(200)
 2 #.#...#
 3 #57##.#   G5(20), E7(197)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 36 rounds:
   0123456
 0 #######
 1 #3..#1#   E3(197), E1(200)
 2 #.#...#
 3 #57##.#   G5(14), E7(194)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
After 37 rounds:
   0123456
 0 #######
 1 #...#1#   E1(200)
 2 #3#...#   E3(197)
 3 #57##.#   G5(5), E7(191)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
Battle ended during round 38
   0123456
 0 #######
 1 #...#1#   E1(200)
 2 #3#...#   E3(197)
 3 #.7##.#   E7(188)
 4 #6..#4#   E6(200), E4(200)
 5 #.....#
 6 #######
Result = 37 * 985 = 36445

I've looked at this for hours and gone completely blind.

Can someone help me spot where things goes wrong?

16 Comments
2025/01/21
19:18 UTC

9

What is the best order to do previous years?

Hey, I just finished 2024 getting all my 50 stars even if I'm late.
And I was wondering if the chronogical order was actually the best one? if I want to do the previous ones as well

I see that 2016 has not that much people, especially the 24b having only 33 people who got that star!
(Btw I really like the stats page, for example seeing that the 2024 21b was the hardest this year as I thought)
So I was wondering if there were some suggestion in term of difficulty or anything or should I start with 2015?

Stats links sources:

26 Comments
2025/01/21
14:09 UTC

0

[2024 DAY 3] Python - What am I missing?

I thought I had it in the bag when I figured the regex rule to be able to replace everything between don't() and do() with an empty string.

It worked on the samples from the prompt, so I'm pretty clueless atm. get_input() should filter out line terminators, so I think I dodged that pitfall.

from re import findall, sub

def _filter_input(input_data: str) -> str:
    return sub(pattern=r"don't\(\)(.*?)do\(\)", repl="", string=input_data)


def _parse_mults(line: str) -> list:
    mults = findall(pattern=r"mul\(\d{1,3},\d{1,3}\)", string=line)
    return mults


def _total_line_mults(line: str) -> int:
    result = 0
    mults: list = _parse_mults(line)
    for mult in mults:
        a, b = map(int, mult[4:-1].split(","))
        result += (a * b)
    return result


def part_two(input_data: list) -> int:
    result = 0
    single_line = "".join(input_data)
    filtered_line = _filter_input(single_line)
    result += _total_line_mults(filtered_line)
    return result


def get_data(input_data: str, year: str, day: str) -> list[str]:
    base_path = path.dirname(__file__)
    with open(f"{path.join(base_path, year, day, input_data)}.txt", "r") as f:
        input_data = f.read().splitlines()
    return input_data
25 Comments
2025/01/21
08:56 UTC

Back To Top