diff --git a/2024/20/solution.py b/2024/20/solution.py index f5b9e79..d6de43b 100644 --- a/2024/20/solution.py +++ b/2024/20/solution.py @@ -2,7 +2,7 @@ import sys,time,re,copy from pprint import pprint sys.path.insert(0, '../../') -from fred import list2int,get_re,nprint,lprint,loadFile,dijkstra,toGrid,findInGrid,create_graph_from_grid,get_value_in_direction,addTuples +from fred import list2int,get_re,nprint,lprint,loadFile,dijkstra,toGrid,findInGrid,create_graph_from_grid,get_value_in_direction,addTuples,dprint start_time = time.time() input_f = 'input' @@ -24,42 +24,57 @@ def part1(): path, dist = dijkstra(graph,start,end) cheatWalls = [] - + for r,row in enumerate(grid): for c,pos in enumerate(row): if pos == '.': if get_value_in_direction(grid,(r,c),'up') == '#' and get_value_in_direction(grid,(r,c),'down') == '#': - cheatWalls.append(addTuples((r,c),(-1,0))) - cheatWalls.append(addTuples((r,c),(1,0))) + if addTuples((r,c),(-1,0)) not in cheatWalls and r != 1 and r != len(grid)-2 and c != 1 and c != len(row)-2: + cheatWalls.append(addTuples((r,c),(-1,0))) + if addTuples((r,c),(1,0)) not in cheatWalls and r != 1 and r != len(grid)-2 and c != 1 and c != len(row)-2: + cheatWalls.append(addTuples((r,c),(1,0))) elif get_value_in_direction(grid,(r,c),'left') == '#' and get_value_in_direction(grid,(r,c),'right') == '#': - cheatWalls.append(addTuples((r,c),(0,-1))) - cheatWalls.append(addTuples((r,c),(0,1))) + if addTuples((r,c),(0,-1)) not in cheatWalls and r != 1 and r != len(grid)-2 and c != 1 and c != len(row)-2: + cheatWalls.append(addTuples((r,c),(0,-1))) + if addTuples((r,c),(0,1)) not in cheatWalls and r != 1 and r != len(grid)-2 and c != 1 and c != len(row)-2: + cheatWalls.append(addTuples((r,c),(0,1))) + if pos == '#': if get_value_in_direction(grid,(r,c),'up') == '.' and get_value_in_direction(grid,(r,c),'down') == '.': - cheatWalls.append((r,c)) - cheatWalls.append((r,c)) + if (r,c) not in cheatWalls and r != 0 and r != len(grid)-1 and c != 0 and c != len(row)-1: + cheatWalls.append((r,c)) elif get_value_in_direction(grid,(r,c),'left') == '.' and get_value_in_direction(grid,(r,c),'right') == '.': - cheatWalls.append((r,c)) - cheatWalls.append((r,c)) + if (r,c) not in cheatWalls and r != 0 and r != len(grid)-1 and c != 0 and c != len(row)-1: + cheatWalls.append((r,c)) + - #print(dist) - #nprint(grid,positions=path) + #nprint(grid,positions=cheatWalls) results = {} startDist = dist #print(cheatWalls) + + count = 0 + for c in cheatWalls: + #print(c) newGrid = copy.deepcopy(grid) newGrid[c[0]][c[1]] = '.' graph = create_graph_from_grid(newGrid,start,end,'#') path, dist = dijkstra(graph,start,end) + #nprint(grid,(c[0],c[1]),sign='o',positions=path) + #input() dist = startDist-dist - if dist not in results: - results[dist] = 0 - results[dist] += 1 - - pprint(results) + if dist != 0: + if dist > 100: + count += 1 + #if dist not in results: + # results[dist] = 0 + #results[dist] += 1 + print(count) + print(results) + return count start_time = time.time() print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms') diff --git a/2024/25/25.md b/2024/25/25.md new file mode 100644 index 0000000..130a273 --- /dev/null +++ b/2024/25/25.md @@ -0,0 +1,190 @@ +## \-\-- Day 25: Code Chronicle \-\-- + +Out of ideas and time, The Historians agree that they should go back to +check the *Chief Historian\'s office* one last time, just in case he +went back there without you noticing. + +When you get there, you are surprised to discover that the door to his +office is *locked*! You can hear someone inside, but knocking +[yields]{title="function knock() { + yield no_response; +}"} no response. The locks on this floor are all fancy, expensive, +virtual versions of [five-pin tumbler +locks](https://en.wikipedia.org/wiki/Pin_tumbler_lock), +so you contact North Pole security to see if they can help open the +door. + +Unfortunately, they\'ve lost track of which locks are installed and +which keys go with them, so the best they can do is send over +*schematics of every lock and every key* for the floor you\'re on (your +puzzle input). + +The schematics are in a cryptic file format, but they do contain +manufacturer information, so you look up their support number. + +\"Our Virtual Five-Pin Tumbler product? That\'s our most expensive +model! *Way* more secure than\--\" You explain that you need to open a +door and don\'t have a lot of time. + +\"Well, you can\'t know whether a key opens a lock without actually +trying the key in the lock (due to quantum hidden variables), but you +*can* rule out some of the key/lock combinations.\" + +\"The virtual system is complicated, but part of it really is a crude +simulation of a five-pin tumbler lock, mostly for marketing reasons. If +you look at the schematics, you can figure out whether a key could +possibly fit in a lock.\" + +He transmits you some example schematics: + + ##### + .#### + .#### + .#### + .#.#. + .#... + ..... + + ##### + ##.## + .#.## + ...## + ...#. + ...#. + ..... + + ..... + #.... + #.... + #...# + #.#.# + #.### + ##### + + ..... + ..... + #.#.. + ###.. + ###.# + ###.# + ##### + + ..... + ..... + ..... + #.... + #.#.. + #.#.# + ##### + +\"The locks are schematics that have the top row filled (`#`) and the +bottom row empty (`.`); the keys have the top row empty and the bottom +row filled. If you look closely, you\'ll see that each schematic is +actually a set of columns of various heights, either extending downward +from the top (for locks) or upward from the bottom (for keys).\" + +\"For locks, those are the pins themselves; you can convert the pins in +schematics to a list of heights, one per column. For keys, the columns +make up the shape of the key where it aligns with pins; those can also +be converted to a list of heights.\" + +\"So, you could say the first lock has pin heights `0,5,3,4,3`:\" + + ##### + .#### + .#### + .#### + .#.#. + .#... + ..... + +\"Or, that the first key has heights `5,0,2,1,3`:\" + + ..... + #.... + #.... + #...# + #.#.# + #.### + ##### + +\"These seem like they should fit together; in the first four columns, +the pins and key don\'t overlap. However, this key *cannot* be for this +lock: in the rightmost column, the lock\'s pin overlaps with the key, +which you know because in that column the sum of the lock height and key +height is more than the available space.\" + +\"So anyway, you can narrow down the keys you\'d need to try by just +testing each key with each lock, which means you would have to check\... +wait, you have *how* many locks? But the only installation *that* size +is at the North\--\" You disconnect the call. + +In this example, converting both locks to pin heights produces: + + 0,5,3,4,3 + 1,2,0,5,3 + +Converting all three keys to heights produces: + + 5,0,2,1,3 + 4,3,4,0,2 + 3,0,2,0,1 + +Then, you can try every key with every lock: + +- Lock `0,5,3,4,3` and key `5,0,2,1,3`: *overlap* in the last column. +- Lock `0,5,3,4,3` and key `4,3,4,0,2`: *overlap* in the second + column. +- Lock `0,5,3,4,3` and key `3,0,2,0,1`: all columns *fit*! +- Lock `1,2,0,5,3` and key `5,0,2,1,3`: *overlap* in the first column. +- Lock `1,2,0,5,3` and key `4,3,4,0,2`: all columns *fit*! +- Lock `1,2,0,5,3` and key `3,0,2,0,1`: all columns *fit*! + +So, in this example, the number of unique lock/key pairs that fit +together without overlapping in any column is `3`. + +Analyze your lock and key schematics. *How many unique lock/key pairs +fit together without overlapping in any column?* + +Your puzzle answer was `3395`. + +The first half of this puzzle is complete! It provides one gold star: \* + +## \-\-- Part Two \-\-- {#part2} + +You and The Historians crowd into the office, startling the Chief +Historian awake! The Historians all take turns looking confused until +one asks where he\'s been for the last few months. + +\"I\'ve been right here, working on this high-priority request from +Santa! I think the only time I even stepped away was about a month ago +when I went to grab a cup of coffee\...\" + +Just then, the Chief notices the time. \"Oh no! I\'m going to be late! I +must have fallen asleep trying to put the finishing touches on this +*chronicle* Santa requested, but now I don\'t have enough time to go +visit the last 50 places on my list and complete the chronicle before +Santa leaves! He said he needed it before tonight\'s sleigh launch.\" + +One of The Historians holds up the list they\'ve been using this whole +time to keep track of where they\'ve been searching. Next to each place +you all visited, they checked off that place with a *star*. Other +Historians hold up their own notes they took on the journey; as The +Historians, how could they resist writing everything down while visiting +all those historically significant places? + +The Chief\'s eyes get wide. \"With all this, we might just have enough +time to finish the chronicle! Santa said he wanted it wrapped up with a +bow, so I\'ll call down to the wrapping department and\... hey, could +*you* bring it up to Santa? I\'ll need to be in my seat to watch the +sleigh launch by then.\" + +You nod, and The Historians quickly work to collect their notes into the +final set of pages for the chronicle. + +You don\'t have enough stars to finish the chronicle, though. You need +13 more. + +Although it hasn\'t changed, you can still [get your puzzle +input](25/input). + diff --git a/2024/25/solution.py b/2024/25/solution.py new file mode 100644 index 0000000..649904e --- /dev/null +++ b/2024/25/solution.py @@ -0,0 +1,66 @@ +#!/bin/python3 +import sys,time,re +from pprint import pprint +sys.path.insert(0, '../../') +from fred import list2int,get_re,nprint,lprint,loadFile +start_time = time.time() + +input_f = 'input' + +######################################### +# # +# Part 1 # +# # +######################################### +def part1(): + instructions = [] + with open(input_f) as file: + for line in file: + instructions.append(list(line.rstrip())) + + keys = [] + locks = [] + + for i in range(0,len(instructions),8): + tmp = [] + # lock + if instructions[i] == list('#####'): + + for l in range(5): + tmp.append(sum(element == '#' for element in [row[l] for row in instructions[i:i+7]])-1) + if tmp not in locks: + locks.append(tmp) + + # key + elif instructions[i] == list('.....'): + for l in range(5): + tmp.append(sum(element == '#' for element in [row[l] for row in instructions[i:i+7]])-1) + if tmp not in keys: + keys.append(tmp) + fits = 0 + works = True + for k in keys: + for l in locks: + for i in range(5): + if k[i] + l[i] > 5: + works = False + if works: + fits += 1 + works = True + + return fits + +start_time = time.time() +print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms') + + +######################################### +# # +# Part 2 # +# # +######################################### +def part2(): + return + +start_time = time.time() +print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms') \ No newline at end of file