Advent Of Code

1012 readers
2 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 19 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 2 years ago
MODERATORS
1
 
 

Advent of Code is an annual Advent calendar of small programming puzzles that can be solved in any programming language you like.

Puzzles have a backstory and then a collection of different inputs with people getting a random input and needing to submit the corresponding output for the puzzle and their input to successfully complete it.

Puzzles start easy and get harder as the days go on. Every day has two different puzzles in increase in difficulty with you getting access to the second puzzle after solving the first.

Puzzles are released every day at midnight ET and can be completed anytime after they are released (but people who solve them quicker after they're been released get more points for the site leaderboard).

https://adventofcode.com


What can I post here?

Anything relating to the event! Whether that be a meme, asking for help, sharing solutions, etc.

Every day a megathread will be posted that solutions to that day should go into. In the megathread you can post code using code blocks or by linking to repositories or pastebins.

To make a code block make three backticks, make a new line and put the code on lines, then put a newline and do three backticks on that

e.g.

```
console.log('Hello World')
```

becomes

console.log('Hello World')  

If you want a spot to post code externally (e.g. if it is too large or you want to have a spot to store it) we have a forgejo instance and an opengist instance

you can find them at https://git.programming.dev and https://blocks.programming.dev


How should I format my post titles?

Try to keep titles in this general format:

[help, etc. category if applicable] [YEAR Day # (Part X)] [programming language if applicable] Post Title

For example:

[2023 Day #5 (Part 3)] [Rust] My attempt at a solution

Another example:

[Help] [2023 Day #2] What does this sentence mean

This helps people avoid spoilers and lets people use it as an archive by searching if they find out about the event in the middle and are starting from the beginning

2
45
Programming.Dev AoC Leaderboard (self.advent_of_code)
submitted 1 year ago* (last edited 1 year ago) by Ategon to c/advent_of_code
 
 

Hey everyone! I set up a private leaderboard for the programming.dev community so we can have one for the community in addition to the global one

The leaderboard code is 3316962-6587d422

Looking forward to seeing you guys there! Ill make a post at the end with the top people on the leaderboard and the version on the site will auto update as people complete challenges


Full instructions on Joining the Leaderboard

  • Log in on https://adventofcode.com/ using one of the methods such as through GitHub
  • Go to the leaderboard section in the navbar
  • Click the private leaderboard button on the page
  • Enter 3316962-6587d422 into the text box for entering a leaderboard join code
  • Click join

Update: Ive made a new leaderboard so that I could rename it to something that isnt just my username, the code there is updated to the new one that should be joined

3
 
 

hi I know this is a year old, but I solved it and used a custom implementation of binary search to solve this.
interestingly enough, in python at least, it is almost as performant as the quadratic equation for solving this lol (43.7 microseconds vs 64.9 microseconds) but now that I realized it is a simple parabola, you can just get the maximum after getting the minimum time and practically matches the quadratic equation performance. lol I know the math is faster as search space grows but I still think its interesting how performant this was.

TLDR: I'm so data structures and programming pilled that I forgot basic algebra.

code

from os.path import dirname,realpath,join

def profiler(method):
    from time import perf_counter_ns
    def wrapper_method(*args: any, **kwargs: any) -> any:
        start_time = perf_counter_ns()
        ret = method(*args, **kwargs)
        stop_time = perf_counter_ns() - start_time
        time_len = min(9, ((len(str(stop_time))-1)//3)*3)
        time_conversion = {9: 'seconds', 6: 'milliseconds', 3: 'microseconds', 0: 'nanoseconds'}
        print(f"Method {method.__name__} took : {stop_time / (10**time_len)} {time_conversion[time_len]}")
        return ret
    return wrapper_method

def binary_search(low_point, high_point, record_distance,record_time,min_or_max):
    if min_or_max == 'min':
        # custom binary search algorithm for minimum charge time to surpass the target distance
        while low_point < high_point:
            mid = (low_point + high_point)//2
            if ((record_time - mid) * mid) > record_distance:
                # if it is valid then we mark it as the high_point and continue searching
                high_point = mid
            else:
                # if it is not valid then we check if the next number up is valid and that should be the minimum time
                if ((record_time - mid + 1) * (mid + 1)) > record_distance:
                    return mid + 1
                # else we continue searching
                low_point = mid + 1
    elif min_or_max == 'max':
        # custom binary search algorithm for maximum charge time to surpass the target distance
        while low_point < high_point:
            mid = -((low_point + high_point)//-2) # math trick to do ceiling division
            if ((record_time - mid) * mid) > record_distance:
                low_point = mid
            else:
                # if it is not valid then we check if the next number down is valid and that should be the maximum time
                if ((record_time - mid + 1) * (mid + 1)) > record_distance:
                    return mid - 1
                # else we continue searching
                high_point = mid - 1

@profiler
def solver(input_str: str) -> tuple[int,int]:
    part_1_solve = 1
    for record_time,record_distance in zip( *[ [ int(number) for number in line.split()[1:] ] for line in input_str.split('\n') ] ):
        minimum_time = binary_search(0,record_time//2,record_distance,record_time,'min')
        # maximum_time = binary_search(record_time//2,record_time,record_distance,record_time,'max') # before I realized it was parabola lmao
        maximum_time = record_time - minimum_time
        part_1_solve *= maximum_time - minimum_time + 1

    # part 2
    # instead of splitting the numbers into multiple pairs, we will just remove the spaces and have one pair of numbers for time and distance.
    record_time,record_distance = [ int(line.replace(' ', '').split(':')[1]) for line in input_str.split('\n') ]
    minimum_time = binary_search(0,record_time//2,record_distance,record_time,'min')
    # maximum_time = binary_search(record_time//2,record_time,record_distance,record_time,'max') # before I realized it was parabola lmao
    maximum_time = record_time - minimum_time
    part_2_solve = maximum_time - minimum_time + 1

    return part_1_solve,part_2_solve

if __name__ == "__main__":
    BASE_DIR = dirname(realpath(__file__))
    with open(join(BASE_DIR, r'input'), 'r') as f:
        input_data = f.read().replace('\r', '').strip()
    result = solver(input_data)
    print("Part 1:", result[0], "\nPart 2:", result[1])

4
5
 
 

I'm looking for something like this (these are not correct, just an example for what I'm looking for):

  • 2021 - day 1: Dijkstra Algorithm
  • 2021 - day 2: Dynamic Programming
  • 2021 - day 3: Time efficiency, Hash tables
  • etc

If there is no such thing, does anyone have a (fairly) complete (github) repository of python implementations from which I can build such a list myself? I would make all the puzzles myself, but I'm not that fast, I'm currently still on day 15 of 2024.

6
5
Visualisation Megathread (self.advent_of_code)
submitted 1 month ago* (last edited 1 month ago) by CameronDev to c/advent_of_code
 
 

Visualizations are hard, and take time, so here is a thread to highlight the visualizations that we have found/created.

Please feel free to post your visualisations!

7
2
Final Leaderboard (programming.dev)
submitted 1 month ago* (last edited 1 month ago) by CameronDev to c/advent_of_code
 
 

Those of you running behind, keep at it, but this is the leaderboard as it stands at the end of 2024.

Happy new year!

8
 
 

Hello,

I am trying to solve the day 7 using Rust and this is what I came up with so far:

use std::fs;

fn calculate(answer: &i32, numbers: &mut Vec<i32>) -> bool {
    if numbers.len() >= 2 {
	let tmp1 = numbers[0];
	let tmp2 = numbers[1];
	numbers.remove(0);
	numbers.remove(0);

	numbers.insert(0, tmp1 * tmp2);

	if calculate(answer, numbers) == true {
	    return true;
	} else {
	    numbers.remove(0);
	    numbers.insert(0, tmp1 + tmp2);
	    if calculate(answer, numbers) == true {
		return true;
	    } else {
		return false;
	    }
	}
    } else {
	if *answer == numbers[0] {
	    println!("> {} true", numbers[0]);
	    return true;
	} else {
	    println!("> {} false", numbers[0]);
	    return false;
	}
    }
}

fn main() {
    let contents = fs::read_to_string("sample.txt")
        .expect("Should have been able to read the file");

    for line in contents.lines() {
	let tmp = line.split(":").collect::<Vec<&str>>();
	let answer = tmp[0].to_string().parse::<i32>().unwrap();
	println!("{:?}", answer);
	let numbers_str = tmp[1].split(" ");
	let mut numbers: Vec<i32> = Vec::new();
	for num in numbers_str {
	    if num.len() == 0 {
		continue;
	    }
	    numbers.push(num.parse::<i32>().unwrap());
	}
	println!("{:?}", numbers);
	if calculate(&answer, &mut numbers) == true {
	    println!("it's true");
	}
    }
}

I don't know why the recursion is not working. any help would be appreciated.

9
5
Using LLMs to solve AOC (www.jerpint.io)
submitted 1 month ago by CameronDev to c/advent_of_code
 
 

A lot lower success rate than I suspected, I guess a lot of the scoreboard times were probably legit?

10
 
 

Now that Advent of Code 2024 has concluded, I wanted to get people's opinion on what puzzles they especially liked looking back. This could be because of the puzzle mechanics, the description, because you are especially proud of your solution that day, or for any other reason.

Feel free to answer even if you only saw part of the puzzles.

My picks would be:

  • 14 (Restroom Redoubt, robots moving into christmas tree shape). Even though it caught me off-guard in the moment, I did like that part 2 had this very imprecise requirement for once. Definitely made for varied, creative solutions.
  • 15 (Warehouse Woes, robots pushing boxes) The second part was a fairly big complexity spike with just a minor change in the tasks. Basically a form of simulation where the hard part is finding a good data representation for the setup. I liked this one because debugging was such a visual process for me, by printing the grids.
  • 17 (Chronospatial Computer, running a machine code) For me the first really tricky one, but still doable. These assembly puzzles are just neat. A lot of computation is started with a pretty small input, and the task is basically to really understand how this "computer" works.

What have been your favorites?

11
82
Preliminary Leaderboard (programming.dev)
submitted 1 month ago* (last edited 1 month ago) by CameronDev to c/advent_of_code
 
 

Well, that was a month. Congrats everyone who has reached the end, and thanks to everyone who has contributed solutions and advice.

Sometime in January I will create a megathread for visualizations. If anyone has any other ideas, happy to hear them, otherwise, take a well earned 11 month rest until next year :D

12
 
 

Here's a writeup of my experience this year! It's been a lot of fun, especially hanging out with people here and on Mastodon. Thanks everyone, and Eric in particular!

13
 
 

Day 25: Code Chronicle

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

14
 
 
15
7
submitted 2 months ago* (last edited 2 months ago) by CameronDev to c/advent_of_code
 
 

I am wondering if manual inspection is the way to go for pt2? Seems almost achievable with some formatting. Anyone been down this road?

16
13
submitted 2 months ago* (last edited 2 months ago) by CameronDev to c/advent_of_code
 
 

Day 24: Crossed Wires

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

17
 
 

Day 23: LAN Party

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

18
 
 

Day 22: Monkey Market

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

19
 
 

Day 21: Keypad Conundrum

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

20
 
 

I was unable to upload even the shortest video because it was too long for my instance. Therefore, please enjoy the following:

  1. Partial visualization of test data. I cut this short because it took 40 seconds to do just a few (out of 81) paths: https://youtube.com/shorts/7UvzgSsMQNA
  2. Partial visualization of full data. I cut this short because I didn't want to wait 40 minutes. It's sped up 2x by making it 60fps (each step is approximately one frame) https://youtu.be/cv9qSdrV2Z4
  3. Full visualization, but it only shows the end paths, not individual steps: https://youtube.com/shorts/ozQ77ikI7JI

Unfortunately youtube is forcing my videos to be shorts due to aspect ratio and length, I don't know if I can force them to a regular video

21
 
 

Day 20: Race Condition

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

22
23
submitted 2 months ago* (last edited 2 months ago) by [email protected] to c/advent_of_code
 
 

I wanted to get an idea of how the blocks were landing and here's some thoughts on what I came up with:

  • they were building a simple maze (duh I guess).
  • the final (blocking) block is highlighted as a tiny red dot for half a second or so (edit: now flashing!).
  • my generated path jumped about seemingly at random even when blocks landed elsewhere so I don't animate the dropping of the first 1000 blocks as it's more noise than data.
  • the ~500 blocks before the final one don't affect my path at all, so it's quite a boring end.
  • Lemmy doesn't like long animations, so I skip 10 blocks at a time.

If you want to toast your CPU for a few seconds, here's some terrible Uiua code.

Data  ← ≡◇(⊜⋕⊸≠@,)°/$"_\n_" &fras "AOC2024day18.txt"
End   ← 70_70
Count ← 1024

D₄      ← [1_0 ¯1_0 0_1 0_¯1]
Valid   ← ▽¬⊸∊:▽⊸(≡/××⊃(≤⊢End|≥0))+D₄¤
BestLen ← ⍣(-1⧻⊢path(Valid|≍End)0_0↙:Data|∞)
Chop!   ← ◌⍢(⨬(⊙◌+1|⊙⊙◌:):⟜^0⌊÷2+,,|>)

BadBlock ← -1Chop!(=∞BestLen)Count ⧻Data
Skip     ← 1000
Step     ← 10
Times    ← ⍜(-Skip|⁅⍜(÷Step|⇡⌊))+1BadBlock

# paths - will ruthlessly spawn new threads until your CPU burns.
∵(×1_1_0)wait≡spawn(°⊚°□⊢path(Valid|≍End)0_0↙:Data)Times

¤∵(×0_0_1)⬚0+↯+1End0°⊚↙Skip Data           # old blocks
+:∵(×0_1_1)≡(⬚0+↯+1End0°⊚↘Skip↙)Times¤Data # add new blocks
≡+                                         # superimpose
⊂:⍜(⊡|⋅1_0_0) ⊡BadBlock Data⊣.             # Add frame for final block.
⍥(⊂:↙¯2.)10                                # Freeze frame.
≡(▽⟜≡▽4)                                   # Scale up.
&fwa "AOC2024day18.gif"gif 60
23
 
 

Day 19 - Linen Layout

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

24
 
 

Full input link (it's kinda cool ngl): https://youtu.be/Jw3CXcaHZ0Q

25
 
 

I thought about it for 15 mins, but couldn't think of any mathematical tricks. I thought of lots of minor tricks, like comparing the number to the result and not adding any more multiplications if it's over, things that would cut 10%-20% here and there, but nothing which fundamentally changes big O running time.

For reference, here's my solution for part 2 in smalltalk. I just generated every possible permutation and tested it. Part 1 is similar, mainly I just used bit magic to avoid generating permutations.

(even if you haven't used it, smalltalk is fairly readable, everything is left to right, except in parens)

day7p2: in
	| input | 
	
	input := in lines collect: [ :l | (l splitOn: '\:|\s' asRegex) reject: #isEmpty thenCollect: #asInteger ].
	
	^ (input select: [ :line |
		(#(1 2 3) permutationsWithRepetitionsOfSize: line size - 2) 
			anySatisfy: [ :num | (self d7addmulcat: line ops: num) = (line at: 1)]
	]) sum: #first.
d7addmulcat: nums ops: ops
	| final |
	
	final := nums at: 2.
	ops withIndexDo: [ :op :i |
		op = 1 ifTrue: [ final := final * (nums at: i + 2) ].
		op = 2 ifTrue: [ final := final + (nums at: i + 2) ].
		op = 3 ifTrue: [ final := (final asString, (nums at: i+2) asString) asInteger ]
	].

	^ final
view more: next ›