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`.
|
||||
|
||||
The first half of this puzzle is complete! It provides one gold star: \*
|
||||
|
||||
## \-\-- Part Two \-\-- {#part2}
|
||||
|
||||
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
|
||||
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).
|
||||
|
||||
|
@ -12,56 +12,58 @@ input_f = 'input'
|
||||
# Part 1 #
|
||||
# #
|
||||
#########################################
|
||||
def part1():
|
||||
instructions = []
|
||||
grid = []
|
||||
|
||||
if input_f == 'test':
|
||||
w = 6
|
||||
h = 6
|
||||
size = 12
|
||||
else:
|
||||
w = 70
|
||||
h = 70
|
||||
end = (h,w)
|
||||
start = (0,0)
|
||||
with open(input_f) as file:
|
||||
for line in file:
|
||||
l = list2int(line.rstrip().split(','))
|
||||
instructions.append((l[0],l[1]))
|
||||
#print(instructions)
|
||||
size = 1024
|
||||
end = (h,w)
|
||||
start = (0,0)
|
||||
|
||||
grid = [[ '.' for x in range(0,w+1)] for y in range(0,h+1)]
|
||||
instructions = []
|
||||
grid = []
|
||||
|
||||
for i in range(1024):
|
||||
with open(input_f) as file:
|
||||
for line in file:
|
||||
l = list2int(line.rstrip().split(','))
|
||||
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]
|
||||
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)
|
||||
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()
|
||||
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():
|
||||
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()
|
||||
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:
|
||||
print(prepend+sign[0] + grid[idx][jdx] + sign[1], end='') # Print with sign
|
||||
else:
|
||||
print(prepend+colored(sign,'green',attrs=["underline"]), end=' ') # Print sign
|
||||
print(prepend+colored(sign,'blue',attrs=["underline","bold"]), end=' ') # Print sign
|
||||
else:
|
||||
print(prepend+colored(grid[idx][jdx],'green',attrs=["underline"]), end=' ')
|
||||
else:
|
||||
if positions is not None:
|
||||
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:
|
||||
print(prepend+grid[idx][jdx], end=' ')
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user