diff --git a/2024/17/17.md b/2024/17/17.md new file mode 100644 index 0000000..37a308f --- /dev/null +++ b/2024/17/17.md @@ -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: + diff --git a/2024/17/solution.py b/2024/17/solution.py new file mode 100644 index 0000000..a8f60c2 --- /dev/null +++ b/2024/17/solution.py @@ -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') \ No newline at end of file diff --git a/2024/18/18.md b/2024/18/18.md index ec66fde..153baad 100644 --- a/2024/18/18.md +++ b/2024/18/18.md @@ -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). diff --git a/2024/18/solution.py b/2024/18/solution.py index 75bfcea..ca707cb 100644 --- a/2024/18/solution.py +++ b/2024/18/solution.py @@ -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) - - grid = [[ '.' for x in range(0,w+1)] for y in range(0,h+1)] - - for i in range(1024): + size = 1024 +end = (h,w) +start = (0,0) + +instructions = [] +grid = [] + +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') \ No newline at end of file diff --git a/2024/19/19.md b/2024/19/19.md new file mode 100644 index 0000000..416084e --- /dev/null +++ b/2024/19/19.md @@ -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: + diff --git a/2024/19/solution.py b/2024/19/solution.py new file mode 100644 index 0000000..7a299ba --- /dev/null +++ b/2024/19/solution.py @@ -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') \ No newline at end of file diff --git a/__pycache__/fred.cpython-311.pyc b/__pycache__/fred.cpython-311.pyc index 0f304cb..5eb4c88 100644 Binary files a/__pycache__/fred.cpython-311.pyc and b/__pycache__/fred.cpython-311.pyc differ diff --git a/fred.py b/fred.py index 35f1b70..27faa62 100644 --- a/fred.py +++ b/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: