Solved 2024/25 P1

This commit is contained in:
FrederikBaerentsen 2024-12-25 12:10:22 +01:00
parent add8230d4b
commit 34e7c2a4db
3 changed files with 288 additions and 17 deletions

View File

@ -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')

190
2024/25/25.md Normal file
View File

@ -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).

66
2024/25/solution.py Normal file
View File

@ -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')