Solved 2024/25 P1
This commit is contained in:
parent
add8230d4b
commit
34e7c2a4db
@ -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
190
2024/25/25.md
Normal 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
66
2024/25/solution.py
Normal 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')
|
Loading…
Reference in New Issue
Block a user