Solved 2024/18 P2
This commit is contained in:
parent
2674f6e723
commit
2f5a9630d2
126
2024/17/17.md
Normal file
126
2024/17/17.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
## \-\-- Day 17: Chronospatial Computer \-\--
|
||||||
|
|
||||||
|
The Historians push the button on their strange device, but this time,
|
||||||
|
you all just feel like you\'re [falling](/2018/day/6).
|
||||||
|
|
||||||
|
\"Situation critical\", the device announces in a familiar voice.
|
||||||
|
\"Bootstrapping process failed. Initializing debugger\....\"
|
||||||
|
|
||||||
|
The small handheld device suddenly unfolds into an entire computer! The
|
||||||
|
Historians look around nervously before one of them tosses it to you.
|
||||||
|
|
||||||
|
This seems to be a 3-bit computer: its program is a list of 3-bit
|
||||||
|
numbers (0 through 7), like `0,1,2,3`. The computer also has three
|
||||||
|
*registers* named `A`, `B`, and `C`, but these registers aren\'t limited
|
||||||
|
to 3 bits and can instead hold any integer.
|
||||||
|
|
||||||
|
The computer knows *eight instructions*, each identified by a 3-bit
|
||||||
|
number (called the instruction\'s *opcode*). Each instruction also reads
|
||||||
|
the 3-bit number after it as an input; this is called its *operand*.
|
||||||
|
|
||||||
|
A number called the *instruction pointer* identifies the position in the
|
||||||
|
program from which the next opcode will be read; it starts at `0`,
|
||||||
|
pointing at the first 3-bit number in the program. Except for jump
|
||||||
|
instructions, the instruction pointer increases by `2` after each
|
||||||
|
instruction is processed (to move past the instruction\'s opcode and its
|
||||||
|
operand). If the computer tries to read an opcode past the end of the
|
||||||
|
program, it instead *halts*.
|
||||||
|
|
||||||
|
So, the program `0,1,2,3` would run the instruction whose opcode is `0`
|
||||||
|
and pass it the operand `1`, then run the instruction having opcode `2`
|
||||||
|
and pass it the operand `3`, then halt.
|
||||||
|
|
||||||
|
There are two types of operands; each instruction specifies the type of
|
||||||
|
its operand. The value of a *literal operand* is the operand itself. For
|
||||||
|
example, the value of the literal operand `7` is the number `7`. The
|
||||||
|
value of a *combo operand* can be found as follows:
|
||||||
|
|
||||||
|
- Combo operands `0` through `3` represent literal values `0` through
|
||||||
|
`3`.
|
||||||
|
- Combo operand `4` represents the value of register `A`.
|
||||||
|
- Combo operand `5` represents the value of register `B`.
|
||||||
|
- Combo operand `6` represents the value of register `C`.
|
||||||
|
- Combo operand `7` is reserved and will not appear in valid programs.
|
||||||
|
|
||||||
|
The eight instructions are as follows:
|
||||||
|
|
||||||
|
The `adv` instruction (opcode `0`) performs *division*. The numerator is
|
||||||
|
the value in the `A` register. The denominator is found by raising 2 to
|
||||||
|
the power of the instruction\'s *combo* operand. (So, an operand of `2`
|
||||||
|
would divide `A` by `4` (`2^2`); an operand of `5` would divide `A` by
|
||||||
|
`2^B`.) The result of the division operation is *truncated* to an
|
||||||
|
integer and then written to the `A` register.
|
||||||
|
|
||||||
|
The `bxl` instruction (opcode `1`) calculates the [bitwise
|
||||||
|
XOR](https://en.wikipedia.org/wiki/Bitwise_operation#XOR)
|
||||||
|
of register `B` and the instruction\'s *literal* operand, then stores
|
||||||
|
the result in register `B`.
|
||||||
|
|
||||||
|
The `bst` instruction (opcode `2`) calculates the value of its *combo*
|
||||||
|
operand [modulo](https://en.wikipedia.org/wiki/Modulo)
|
||||||
|
8 (thereby keeping only its lowest 3 bits), then writes that value to
|
||||||
|
the `B` register.
|
||||||
|
|
||||||
|
The `jnz` instruction (opcode `3`) does *nothing* if the `A` register is
|
||||||
|
`0`. However, if the `A` register is *not zero*, it
|
||||||
|
*jumps*
|
||||||
|
by setting the instruction pointer to the value of its *literal*
|
||||||
|
operand; if this instruction jumps, the instruction pointer is *not*
|
||||||
|
increased by `2` after this instruction.
|
||||||
|
|
||||||
|
The `bxc` instruction (opcode `4`) calculates the *bitwise XOR* of
|
||||||
|
register `B` and register `C`, then stores the result in register `B`.
|
||||||
|
(For legacy reasons, this instruction reads an operand but *ignores*
|
||||||
|
it.)
|
||||||
|
|
||||||
|
The `out` instruction (opcode `5`) calculates the value of its *combo*
|
||||||
|
operand modulo 8, then *outputs* that value. (If a program outputs
|
||||||
|
multiple values, they are separated by commas.)
|
||||||
|
|
||||||
|
The `bdv` instruction (opcode `6`) works exactly like the `adv`
|
||||||
|
instruction except that the result is stored in the *`B` register*. (The
|
||||||
|
numerator is still read from the `A` register.)
|
||||||
|
|
||||||
|
The `cdv` instruction (opcode `7`) works exactly like the `adv`
|
||||||
|
instruction except that the result is stored in the *`C` register*. (The
|
||||||
|
numerator is still read from the `A` register.)
|
||||||
|
|
||||||
|
Here are some examples of instruction operation:
|
||||||
|
|
||||||
|
- If register `C` contains `9`, the program `2,6` would set register
|
||||||
|
`B` to `1`.
|
||||||
|
- If register `A` contains `10`, the program `5,0,5,1,5,4` would
|
||||||
|
output `0,1,2`.
|
||||||
|
- If register `A` contains `2024`, the program `0,1,5,4,3,0` would
|
||||||
|
output `4,2,5,6,7,7,7,7,3,1,0` and leave `0` in register `A`.
|
||||||
|
- If register `B` contains `29`, the program `1,7` would set register
|
||||||
|
`B` to `26`.
|
||||||
|
- If register `B` contains `2024` and register `C` contains `43690`,
|
||||||
|
the program `4,0` would set register `B` to `44354`.
|
||||||
|
|
||||||
|
The Historians\' strange device has finished initializing its debugger
|
||||||
|
and is displaying some *information about the program it is trying to
|
||||||
|
run* (your puzzle input). For example:
|
||||||
|
|
||||||
|
Register A: 729
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,1,5,4,3,0
|
||||||
|
|
||||||
|
Your first task is to *determine what the program is trying to output*.
|
||||||
|
To do this, initialize the registers to the given values, then run the
|
||||||
|
given program, collecting any output produced by `out` instructions.
|
||||||
|
(Always join the values produced by `out` instructions with commas.)
|
||||||
|
After the above program halts, its final output will be
|
||||||
|
`4,6,3,5,6,3,5,2,1,0`.
|
||||||
|
|
||||||
|
Using the information provided by the debugger, initialize the registers
|
||||||
|
to the given values, then run the program. Once it halts, *what do you
|
||||||
|
get if you use commas to join the values it output into a single
|
||||||
|
string?*
|
||||||
|
|
||||||
|
To begin, [get your puzzle input](17/input).
|
||||||
|
|
||||||
|
Answer:
|
||||||
|
|
31
2024/17/solution.py
Normal file
31
2024/17/solution.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/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 = 'test'
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
def part1():
|
||||||
|
return
|
||||||
|
|
||||||
|
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')
|
@ -96,8 +96,6 @@ the exit?*
|
|||||||
|
|
||||||
Your puzzle answer was `294`.
|
Your puzzle answer was `294`.
|
||||||
|
|
||||||
The first half of this puzzle is complete! It provides one gold star: \*
|
|
||||||
|
|
||||||
## \-\-- Part Two \-\-- {#part2}
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
The Historians aren\'t as used to moving around in this pixelated
|
The Historians aren\'t as used to moving around in this pixelated
|
||||||
@ -137,8 +135,14 @@ Simulate more of the bytes that are about to corrupt your memory space.
|
|||||||
from being reachable from your starting position?* (Provide the answer
|
from being reachable from your starting position?* (Provide the answer
|
||||||
as two integers separated by a comma with no other characters.)
|
as two integers separated by a comma with no other characters.)
|
||||||
|
|
||||||
Answer:
|
Your puzzle answer was `31,22`.
|
||||||
|
|
||||||
Although it hasn\'t changed, you can still [get your puzzle
|
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](18/input).
|
input](18/input).
|
||||||
|
|
||||||
|
@ -12,56 +12,58 @@ input_f = 'input'
|
|||||||
# Part 1 #
|
# Part 1 #
|
||||||
# #
|
# #
|
||||||
#########################################
|
#########################################
|
||||||
def part1():
|
|
||||||
instructions = []
|
if input_f == 'test':
|
||||||
grid = []
|
w = 6
|
||||||
|
h = 6
|
||||||
|
size = 12
|
||||||
|
else:
|
||||||
w = 70
|
w = 70
|
||||||
h = 70
|
h = 70
|
||||||
end = (h,w)
|
size = 1024
|
||||||
start = (0,0)
|
end = (h,w)
|
||||||
with open(input_f) as file:
|
start = (0,0)
|
||||||
for line in file:
|
|
||||||
l = list2int(line.rstrip().split(','))
|
instructions = []
|
||||||
instructions.append((l[0],l[1]))
|
grid = []
|
||||||
#print(instructions)
|
|
||||||
|
with open(input_f) as file:
|
||||||
grid = [[ '.' for x in range(0,w+1)] for y in range(0,h+1)]
|
for line in file:
|
||||||
|
l = list2int(line.rstrip().split(','))
|
||||||
for i in range(1024):
|
instructions.append((l[1],l[0]))
|
||||||
|
grid = [[ '.' for x in range(0,w+1)] for y in range(0,h+1)]
|
||||||
|
|
||||||
|
def is_goal(node):
|
||||||
|
return True if node == end else False
|
||||||
|
|
||||||
|
def get_neighbors(node):
|
||||||
|
directions = ['up','down','left','right']
|
||||||
|
offsets = {
|
||||||
|
'up': (-1, 0),
|
||||||
|
'down': (1, 0),
|
||||||
|
'left': (0, -1),
|
||||||
|
'right': (0, 1),
|
||||||
|
}
|
||||||
|
neighbors = []
|
||||||
|
|
||||||
|
for d in directions:
|
||||||
|
tmp = addTuples(offsets[d],node)
|
||||||
|
if get_value_in_direction(grid,node,d) != '#' and grid_valid(tmp[0],tmp[1],grid):
|
||||||
|
neighbors.append((tmp[0],tmp[1]))
|
||||||
|
return neighbors
|
||||||
|
|
||||||
|
def part1():
|
||||||
|
for i in range(size):
|
||||||
x = instructions[i]
|
x = instructions[i]
|
||||||
grid[x[0]][x[1]] = '#'
|
grid[x[0]][x[1]] = '#'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def is_goal(node):
|
|
||||||
#print(node)
|
|
||||||
|
|
||||||
return True if node == end else False
|
|
||||||
|
|
||||||
def get_neighbors(node):
|
|
||||||
directions = ['up','down','left','right']
|
|
||||||
offsets = {
|
|
||||||
'up': (-1, 0),
|
|
||||||
'down': (1, 0),
|
|
||||||
'left': (0, -1),
|
|
||||||
'right': (0, 1),
|
|
||||||
}
|
|
||||||
neighbors = []
|
|
||||||
|
|
||||||
# Loop through all the directions
|
|
||||||
for d in directions:
|
|
||||||
tmp = addTuples(offsets[d],node)
|
|
||||||
if get_value_in_direction(grid,node,d) != '#' and grid_valid(tmp[0],tmp[1],grid):
|
|
||||||
neighbors.append((tmp[0],tmp[1]))
|
|
||||||
# Return the list of valid neighbors
|
|
||||||
return neighbors
|
|
||||||
|
|
||||||
goal_nodes, path = bfs((0,0),is_goal,get_neighbors)
|
goal_nodes, path = bfs((0,0),is_goal,get_neighbors)
|
||||||
print(goal_nodes)
|
|
||||||
return len(path[goal_nodes[0]])-1
|
|
||||||
|
|
||||||
|
return len(path[goal_nodes[0]])-1, path
|
||||||
|
|
||||||
|
goal_nodes, path = part1()
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
print('Part 1:',goal_nodes, '\t\t', round((time.time() - start_time)*1000), 'ms')
|
||||||
|
|
||||||
|
|
||||||
#########################################
|
#########################################
|
||||||
@ -70,7 +72,13 @@ print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
|||||||
# #
|
# #
|
||||||
#########################################
|
#########################################
|
||||||
def part2():
|
def part2():
|
||||||
return
|
new_path = path
|
||||||
|
for i in range(size,len(instructions)):
|
||||||
|
x = instructions[i]
|
||||||
|
grid[x[0]][x[1]] = '#'
|
||||||
|
goal_nodes, new_path = bfs((0,0),is_goal,get_neighbors)
|
||||||
|
if not goal_nodes:
|
||||||
|
return x[1],x[0]
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
85
2024/19/19.md
Normal file
85
2024/19/19.md
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
## \-\-- Day 19: Linen Layout \-\--
|
||||||
|
|
||||||
|
Today, The Historians take you up to the [hot springs](/2023/day/12) on
|
||||||
|
Gear Island! Very
|
||||||
|
[suspiciously](https://www.youtube.com/watch?v=ekL881PJMjI),
|
||||||
|
absolutely nothing goes wrong as they begin their careful search of the
|
||||||
|
vast field of helixes.
|
||||||
|
|
||||||
|
Could this *finally* be your chance to visit the
|
||||||
|
[onsen](https://en.wikipedia.org/wiki/Onsen) next door?
|
||||||
|
Only one way to find out.
|
||||||
|
|
||||||
|
After a brief conversation with the reception staff at the onsen front
|
||||||
|
desk, you discover that you don\'t have the right kind of money to pay
|
||||||
|
the admission fee. However, before you can leave, the staff get your
|
||||||
|
attention. Apparently, they\'ve heard about how you helped at the hot
|
||||||
|
springs, and they\'re willing to make a deal: if you can simply help
|
||||||
|
them *arrange their towels*, they\'ll let you in for *free*!
|
||||||
|
|
||||||
|
Every towel at this onsen is marked with a *pattern of colored stripes*.
|
||||||
|
There are only a few patterns, but for any particular pattern, the staff
|
||||||
|
can get you as many towels with that pattern as you need. Each
|
||||||
|
stripe
|
||||||
|
can be *white* (`w`), *blue* (`u`), *black* (`b`), *red* (`r`), or
|
||||||
|
*green* (`g`). So, a towel with the pattern `ggr` would have a green
|
||||||
|
stripe, a green stripe, and then a red stripe, in that order. (You
|
||||||
|
can\'t reverse a pattern by flipping a towel upside-down, as that would
|
||||||
|
cause the onsen logo to face the wrong way.)
|
||||||
|
|
||||||
|
The Official Onsen Branding Expert has produced a list of *designs* -
|
||||||
|
each a long sequence of stripe colors - that they would like to be able
|
||||||
|
to display. You can use any towels you want, but all of the towels\'
|
||||||
|
stripes must exactly match the desired design. So, to display the design
|
||||||
|
`rgrgr`, you could use two `rg` towels and then an `r` towel, an `rgr`
|
||||||
|
towel and then a `gr` towel, or even a single massive `rgrgr` towel
|
||||||
|
(assuming such towel patterns were actually available).
|
||||||
|
|
||||||
|
To start, collect together all of the available towel patterns and the
|
||||||
|
list of desired designs (your puzzle input). For example:
|
||||||
|
|
||||||
|
r, wr, b, g, bwu, rb, gb, br
|
||||||
|
|
||||||
|
brwrr
|
||||||
|
bggr
|
||||||
|
gbbr
|
||||||
|
rrbgbr
|
||||||
|
ubwu
|
||||||
|
bwurrg
|
||||||
|
brgr
|
||||||
|
bbrgwb
|
||||||
|
|
||||||
|
The first line indicates the available towel patterns; in this example,
|
||||||
|
the onsen has unlimited towels with a single red stripe (`r`), unlimited
|
||||||
|
towels with a white stripe and then a red stripe (`wr`), and so on.
|
||||||
|
|
||||||
|
After the blank line, the remaining lines each describe a design the
|
||||||
|
onsen would like to be able to display. In this example, the first
|
||||||
|
design (`brwrr`) indicates that the onsen would like to be able to
|
||||||
|
display a black stripe, a red stripe, a white stripe, and then two red
|
||||||
|
stripes, in that order.
|
||||||
|
|
||||||
|
Not all designs will be possible with the available towels. In the above
|
||||||
|
example, the designs are possible or impossible as follows:
|
||||||
|
|
||||||
|
- `brwrr` can be made with a `br` towel, then a `wr` towel, and then
|
||||||
|
finally an `r` towel.
|
||||||
|
- `bggr` can be made with a `b` towel, two `g` towels, and then an `r`
|
||||||
|
towel.
|
||||||
|
- `gbbr` can be made with a `gb` towel and then a `br` towel.
|
||||||
|
- `rrbgbr` can be made with `r`, `rb`, `g`, and `br`.
|
||||||
|
- `ubwu` is *impossible*.
|
||||||
|
- `bwurrg` can be made with `bwu`, `r`, `r`, and `g`.
|
||||||
|
- `brgr` can be made with `br`, `g`, and `r`.
|
||||||
|
- `bbrgwb` is *impossible*.
|
||||||
|
|
||||||
|
In this example, `6` of the eight designs are possible with the
|
||||||
|
available towel patterns.
|
||||||
|
|
||||||
|
To get into the onsen as soon as possible, consult your list of towel
|
||||||
|
patterns and desired designs carefully. *How many designs are possible?*
|
||||||
|
|
||||||
|
To begin, [get your puzzle input](19/input).
|
||||||
|
|
||||||
|
Answer:
|
||||||
|
|
47
2024/19/solution.py
Normal file
47
2024/19/solution.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,time,re
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int,get_re,nprint,bfs
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
input_f = 'test'
|
||||||
|
|
||||||
|
def loadFile():
|
||||||
|
colors = []
|
||||||
|
towels = []
|
||||||
|
with open(input_f) as file:
|
||||||
|
for l,line in enumerate(file):
|
||||||
|
if l == 0:
|
||||||
|
colors = line.rstrip().split(',')
|
||||||
|
if l > 1:
|
||||||
|
towels.append(line.rstrip())
|
||||||
|
return colors,towels
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def part1():
|
||||||
|
colors,towels = loadFile()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
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')
|
Binary file not shown.
7
fred.py
7
fred.py
@ -293,13 +293,16 @@ def nprint(grid, cur: set = None, sign: str = None, positions:list = None):
|
|||||||
if len(sign) > 1:
|
if len(sign) > 1:
|
||||||
print(prepend+sign[0] + grid[idx][jdx] + sign[1], end='') # Print with sign
|
print(prepend+sign[0] + grid[idx][jdx] + sign[1], end='') # Print with sign
|
||||||
else:
|
else:
|
||||||
print(prepend+colored(sign,'green',attrs=["underline"]), end=' ') # Print sign
|
print(prepend+colored(sign,'blue',attrs=["underline","bold"]), end=' ') # Print sign
|
||||||
else:
|
else:
|
||||||
print(prepend+colored(grid[idx][jdx],'green',attrs=["underline"]), end=' ')
|
print(prepend+colored(grid[idx][jdx],'green',attrs=["underline"]), end=' ')
|
||||||
else:
|
else:
|
||||||
if positions is not None:
|
if positions is not None:
|
||||||
if (idx,jdx) in positions:
|
if (idx,jdx) in positions:
|
||||||
print(prepend+colored(grid[idx][jdx],'green'),end=' ')
|
if sign is not None:
|
||||||
|
print(prepend+colored(sign,'green'),end=' ')
|
||||||
|
else:
|
||||||
|
print(prepend+colored(grid[idx][jdx],'green'),end=' ')
|
||||||
else:
|
else:
|
||||||
print(prepend+grid[idx][jdx], end=' ')
|
print(prepend+grid[idx][jdx], end=' ')
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user