this post was submitted on 25 Dec 2024
15 points (100.0% liked)

Advent Of Code

995 readers
3 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 1 year ago
MODERATORS
 

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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] Acters@lemmy.world 2 points 1 week ago* (last edited 1 week ago) (1 children)

Python3

ah well this year ends with a simple ~12.5 ms solve and not too much of a brain teaser. Well at least I got around to solving all of the challenges.

Code

from os.path import dirname,realpath,join

from collections.abc import Callable
def profiler(method) -> Callable[..., any]:
    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

@profiler
def solver(locks_and_keys_str: str) -> int:
    locks_list = []
    keys_list  = []

    for schematic in locks_and_keys_str.split('\n\n'):
        if schematic[0] == '#':
            locks_list.append(tuple([column.index('.') for column in zip(*schematic.split())]))
        else:
            keys_list.append(tuple([column.index('#') for column in zip(*schematic.split())]))
    
    count = 0
    for lock_configuration in locks_list:
        for key_configuration in keys_list:
            for i,l in enumerate(lock_configuration):
                if l>key_configuration[i]:
                    # break on the first configuration that is invalid
                    break
            else:
                # skipped when loop is broken
                count += 1
    
    return count

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("Day 25 final solve:", result)

[โ€“] CameronDev@programming.dev 1 points 1 week ago (1 children)

Congrats on reaching the finish line!

The bit that caught me out was that the key + lock should equal 5 in reality, instead of being up to 5 in the challenge.

[โ€“] Acters@lemmy.world 2 points 1 week ago (1 children)

Thanks! I quickly wrote it but didn't think to count things. I just took the index of where the edge was located at and ran with it.

So I don't understand what you mean by equal 5. Could you elaborate? Cause I must have read the challenge text differently.

[โ€“] CameronDev@programming.dev 1 points 6 days ago (1 children)

For a real world lock, the key height + pin height must equal the height of the barrel exactly. If it is taller or shorter, the lock will bind and not open.

https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Pin_tumbler_no_key.svg/400px-Pin_tumbler_no_key.svg.png

For the challenge, as long as its not overlapping (too tall), its a valid key/lock pair.

[โ€“] Acters@lemmy.world 2 points 6 days ago

Oh! I didn't think it that way, lol, I was thinking this quickly through. I didn't think of relating to physical locks because it clearly said it was virtual. But I guess, there could theoretically be a physical tumbler lock with 0-5 spacers, it would just be a tall lock. You know like how some master keys have it so that there are spacers for the master key or the client key to open the lock.