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

  • @Acters
    link
    2
    edit-2
    4 days ago

    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)
    
    
    • @[email protected]OPM
      link
      fedilink
      14 days ago

      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
        link
        24 days ago

        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.

          • @Acters
            link
            23 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.