Solved 2024/09 P1+P2
This commit is contained in:
parent
f3f88f47d1
commit
71f9fa5a1a
132
2024/09/9.md
Normal file
132
2024/09/9.md
Normal file
@ -0,0 +1,132 @@
|
||||
## \-\-- Day 9: Disk Fragmenter \-\--
|
||||
|
||||
Another push of the button leaves you in the familiar hallways of some
|
||||
friendly [amphipods](/2021/day/23)! Good thing you each somehow got your
|
||||
own personal mini submarine. The Historians jet away in search of the
|
||||
Chief, mostly by driving directly into walls.
|
||||
|
||||
While The Historians quickly figure out how to pilot these things, you
|
||||
notice an amphipod in the corner struggling with his computer. He\'s
|
||||
trying to make more contiguous free space by compacting all of the
|
||||
files, but his program isn\'t working; you offer to help.
|
||||
|
||||
He shows you the *disk map* (your puzzle input) he\'s already generated.
|
||||
For example:
|
||||
|
||||
2333133121414131402
|
||||
|
||||
The disk map uses a dense format to represent the layout of *files* and
|
||||
*free space* on the disk. The digits alternate between indicating the
|
||||
length of a file and the length of free space.
|
||||
|
||||
So, a disk map like `12345` would represent a one-block file, two blocks
|
||||
of free space, a three-block file, four blocks of free space, and then a
|
||||
five-block file. A disk map like `90909` would represent three
|
||||
nine-block files in a row (with no free space between them).
|
||||
|
||||
Each file on disk also has an *ID number* based on the order of the
|
||||
files as they appear *before* they are rearranged, starting with ID `0`.
|
||||
So, the disk map `12345` has three files: a one-block file with ID `0`,
|
||||
a three-block file with ID `1`, and a five-block file with ID `2`. Using
|
||||
one character for each block where digits are the file ID and `.` is
|
||||
free space, the disk map `12345` represents these individual blocks:
|
||||
|
||||
0..111....22222
|
||||
|
||||
The first example above, `2333133121414131402`, represents these
|
||||
individual blocks:
|
||||
|
||||
00...111...2...333.44.5555.6666.777.888899
|
||||
|
||||
The amphipod would like to *move file blocks one at a time* from the end
|
||||
of the disk to the leftmost free space block (until there are no gaps
|
||||
remaining between file blocks). For the disk map `12345`, the process
|
||||
looks like this:
|
||||
|
||||
0..111....22222
|
||||
02.111....2222.
|
||||
022111....222..
|
||||
0221112...22...
|
||||
02211122..2....
|
||||
022111222......
|
||||
|
||||
The first example requires a few more steps:
|
||||
|
||||
00...111...2...333.44.5555.6666.777.888899
|
||||
009..111...2...333.44.5555.6666.777.88889.
|
||||
0099.111...2...333.44.5555.6666.777.8888..
|
||||
00998111...2...333.44.5555.6666.777.888...
|
||||
009981118..2...333.44.5555.6666.777.88....
|
||||
0099811188.2...333.44.5555.6666.777.8.....
|
||||
009981118882...333.44.5555.6666.777.......
|
||||
0099811188827..333.44.5555.6666.77........
|
||||
00998111888277.333.44.5555.6666.7.........
|
||||
009981118882777333.44.5555.6666...........
|
||||
009981118882777333644.5555.666............
|
||||
00998111888277733364465555.66.............
|
||||
0099811188827773336446555566..............
|
||||
|
||||
The final step of this file-compacting process is to update the
|
||||
*filesystem checksum*. To calculate the checksum, add up the result of
|
||||
multiplying each of these blocks\' position with the file ID number it
|
||||
contains. The leftmost block is in position `0`. If a block contains
|
||||
free space, skip it instead.
|
||||
|
||||
Continuing the first example, the first few blocks\' position multiplied
|
||||
by its file ID number are `0 * 0 = 0`, `1 * 0 = 0`, `2 * 9 = 18`,
|
||||
`3 * 9 = 27`, `4 * 8 = 32`, and so on. In this example, the checksum is
|
||||
the sum of these, `1928`.
|
||||
|
||||
[Compact the amphipod\'s hard
|
||||
drive]{title="Bonus points if you make a cool animation of this process."}
|
||||
using the process he requested. *What is the resulting filesystem
|
||||
checksum?* [(Be careful copy/pasting the input for this puzzle; it is a
|
||||
single, very long line.)]{.quiet}
|
||||
|
||||
Your puzzle answer was `6401092019345`.
|
||||
|
||||
## \-\-- Part Two \-\-- {#part2}
|
||||
|
||||
Upon completion, two things immediately become clear. First, the disk
|
||||
definitely has a lot more contiguous free space, just like the amphipod
|
||||
hoped. Second, the computer is running much more slowly! Maybe
|
||||
introducing all of that [file system
|
||||
fragmentation](https://en.wikipedia.org/wiki/File_system_fragmentation)
|
||||
was a bad idea?
|
||||
|
||||
The eager amphipod already has a new plan: rather than move individual
|
||||
blocks, he\'d like to try compacting the files on his disk by moving
|
||||
*whole files* instead.
|
||||
|
||||
This time, attempt to move whole files to the leftmost span of free
|
||||
space blocks that could fit the file. Attempt to move each file exactly
|
||||
once in order of *decreasing file ID number* starting with the file with
|
||||
the highest file ID number. If there is no span of free space to the
|
||||
left of a file that is large enough to fit the file, the file does not
|
||||
move.
|
||||
|
||||
The first example from above now proceeds differently:
|
||||
|
||||
00...111...2...333.44.5555.6666.777.888899
|
||||
0099.111...2...333.44.5555.6666.777.8888..
|
||||
0099.1117772...333.44.5555.6666.....8888..
|
||||
0099.111777244.333....5555.6666.....8888..
|
||||
00992111777.44.333....5555.6666.....8888..
|
||||
|
||||
The process of updating the filesystem checksum is the same; now, this
|
||||
example\'s checksum would be `2858`.
|
||||
|
||||
Start over, now compacting the amphipod\'s hard drive using this new
|
||||
method instead. *What is the resulting filesystem checksum?*
|
||||
|
||||
Your puzzle answer was `6431472344710`.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars:
|
||||
\*\*
|
||||
|
||||
At this point, you should [return to your Advent calendar](/2024) and
|
||||
try another puzzle.
|
||||
|
||||
If you still want to see it, you can [get your puzzle
|
||||
input](9/input).
|
||||
|
131
2024/09/solution.py
Normal file
131
2024/09/solution.py
Normal file
@ -0,0 +1,131 @@
|
||||
#!/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 = 2
|
||||
|
||||
def createMap(diskmap):
|
||||
for i in range(len(instructions)):
|
||||
t = []
|
||||
if i%2 == 0:
|
||||
for x in range(instructions[i]):
|
||||
t.append(int(i/2))
|
||||
else:
|
||||
for x in range(instructions[i]):
|
||||
t.append('')
|
||||
diskmap.append(t)
|
||||
return diskmap
|
||||
|
||||
#########################################
|
||||
# #
|
||||
# Part 1 #
|
||||
# #
|
||||
#########################################
|
||||
|
||||
if part == 1:
|
||||
print("--- Loading File ---")
|
||||
instructions = list2int(list(loadFile(input_f)[0]))
|
||||
print(" %s seconds ---" % (time.time() - start_time))
|
||||
|
||||
diskmap = createMap([])
|
||||
print("--- Creating Map ---")
|
||||
print(" %s seconds ---" % (time.time() - start_time))
|
||||
|
||||
|
||||
for i in range(len(diskmap)):
|
||||
if i%2!=0:
|
||||
try:
|
||||
if len(diskmap[i]) > 0:
|
||||
for x in range(len(diskmap[i])):
|
||||
|
||||
if (len(diskmap[-1])) > 0:
|
||||
diskmap[i][x] = diskmap[-1].pop()
|
||||
|
||||
while diskmap[-1] == [] or diskmap[-1] == [''] or diskmap[-1][0] == '':
|
||||
diskmap.pop()
|
||||
except:
|
||||
break
|
||||
|
||||
numbers = []
|
||||
|
||||
for j in range(len(diskmap)):
|
||||
for i in range(len(diskmap[j])):
|
||||
numbers.append(diskmap[j][i])
|
||||
|
||||
result = 0
|
||||
for idx,i in enumerate(numbers):
|
||||
result += (idx*i)
|
||||
|
||||
print("--- Calculating Part 1 ---")
|
||||
print(result)
|
||||
print(" %s seconds ---" % (time.time() - start_time))
|
||||
#########################################
|
||||
# #
|
||||
# Part 2 #
|
||||
# #
|
||||
#########################################
|
||||
if part == 2:
|
||||
print("--- Loading File ---")
|
||||
instructions = list2int(list(loadFile(input_f)[0]))
|
||||
print(" %s seconds ---" % (time.time() - start_time))
|
||||
|
||||
diskmap = createMap([])
|
||||
print("--- Creating Map ---")
|
||||
print(" %s seconds ---" % (time.time() - start_time))
|
||||
|
||||
def split_list(input_list):
|
||||
digits = [x for x in input_list if x != '']
|
||||
empties = [x for x in input_list if x == '']
|
||||
if not empties:
|
||||
return [digits]
|
||||
elif digits:
|
||||
return [digits, empties]
|
||||
|
||||
diskmap = [sublist for sublist in diskmap if sublist != []]
|
||||
|
||||
for i in range(len(diskmap)):
|
||||
if '' in diskmap[i]:
|
||||
solved = False
|
||||
if len(diskmap[i]) > 0:
|
||||
offset = 0
|
||||
while not solved:
|
||||
if len(diskmap[i]) >= len(diskmap[-(1+offset)]) and diskmap[-(1+offset)][0] != '':
|
||||
for x in range(len(diskmap[-(1+offset)])):
|
||||
|
||||
if (len(diskmap[-(1+offset)])) > 0:
|
||||
diskmap[i][x] = diskmap[-(1+offset)][x]
|
||||
diskmap[-(1+offset)][x] = ''
|
||||
|
||||
diskmap = diskmap[:i] + split_list(diskmap[i]) + diskmap[i+1:]
|
||||
solved = True
|
||||
elif i < len(diskmap)-offset-2:
|
||||
offset += 1
|
||||
else:
|
||||
solved = True
|
||||
|
||||
elif diskmap[i] == []:
|
||||
diskmap.remove(i)
|
||||
|
||||
|
||||
numbers = []
|
||||
|
||||
for j in range(len(diskmap)):
|
||||
for i in range(len(diskmap[j])):
|
||||
t = diskmap[j][i]
|
||||
if t == '':
|
||||
numbers.append(0)
|
||||
else:
|
||||
numbers.append(t)
|
||||
|
||||
result = 0
|
||||
for idx,i in enumerate(numbers):
|
||||
result += (idx*i)
|
||||
|
||||
print("--- Calculating Part 1 ---")
|
||||
print(result)
|
||||
print(" %s seconds ---" % (time.time() - start_time))
|
1
2024/09/test2
Normal file
1
2024/09/test2
Normal file
@ -0,0 +1 @@
|
||||
233313312141413140231423542
|
Loading…
Reference in New Issue
Block a user