AoC Day 15, Parts 1 & 2 (Solved)

This commit is contained in:
🐙PiperYxzzy
2023-12-15 07:37:18 +02:00
parent 5fd0920ef2
commit ddb00d61b5
4 changed files with 184 additions and 0 deletions

70
2023/15/README.md Executable file
View File

@@ -0,0 +1,70 @@
## \-\-\- Day 15: Lens Library ---
The newly-focused parabolic reflector dish is sending all of the collected light to a point on the side of yet another mountain - the largest mountain on Lava Island. As you approach the mountain, you find that the light is being collected by the wall of a large facility embedded in the mountainside.
You find a door under a large sign that says "Lava Production Facility" and next to a smaller sign that says "Danger - Personal Protective Equipment required beyond this point".
As you step inside, you are immediately greeted by a somewhat panicked reindeer wearing goggles and a loose-fitting [hard hat](https://en.wikipedia.org/wiki/Hard_hat). The reindeer leads you to a shelf of goggles and hard hats (you quickly find some that fit) and then further into the facility. At one point, you pass a button with a faint snout mark and the label "PUSH FOR HELP". No wonder you were loaded into that [trebuchet](1) so quickly!
You pass through a final set of doors surrounded with even more warning signs and into what must be the room that collects all of the light from outside. As you admire the large assortment of lenses available to further focus the light, the reindeer brings you a book titled "Initialization Manual".
"Hello!", the book cheerfully begins, apparently unaware of the concerned reindeer reading over your shoulder. "This procedure will let you bring the Lava Production Facility online - all without burning or melting anything unintended!"
"Before you begin, please be prepared to use the Holiday ASCII String Helper algorithm (appendix 1A)." You turn to appendix 1A. The reindeer leans closer with interest.
The HASH algorithm is a way to turn any [string](https://en.wikipedia.org/wiki/String_(computer_science)) of characters into a single _number_ in the range 0 to 255. To run the HASH algorithm on a string, start with a _current value_ of `0`. Then, for each character in the string starting from the beginning:
- Determine the [ASCII code](https://en.wikipedia.org/wiki/ASCII#Printable_characters) for the current character of the string.
- Increase the _current value_ by the ASCII code you just determined.
- Set the _current value_ to itself multiplied by `17`.
- Set the _current value_ to the [remainder](https://en.wikipedia.org/wiki/Modulo) of dividing itself by `256`.
After following these steps for each character in the string in order, the _current value_ is the output of the HASH algorithm.
So, to find the result of running the HASH algorithm on the string `HASH`:
- The _current value_ starts at `0`.
- The first character is `H`; its ASCII code is `72`.
- The _current value_ increases to `72`.
- The _current value_ is multiplied by `17` to become `1224`.
- The _current value_ becomes `200` (the remainder of `1224` divided by `256`).
- The next character is `A`; its ASCII code is `65`.
- The _current value_ increases to `265`.
- The _current value_ is multiplied by `17` to become `4505`.
- The _current value_ becomes `153` (the remainder of `4505` divided by `256`).
- The next character is `S`; its ASCII code is `83`.
- The _current value_ increases to `236`.
- The _current value_ is multiplied by `17` to become `4012`.
- The _current value_ becomes `172` (the remainder of `4012` divided by `256`).
- The next character is `H`; its ASCII code is `72`.
- The _current value_ increases to `244`.
- The _current value_ is multiplied by `17` to become `4148`.
- The _current value_ becomes `52` (the remainder of `4148` divided by `256`).
So, the result of running the HASH algorithm on the string `HASH` is `52`.
The _initialization sequence_ (your puzzle input) is a comma-separated list of steps to start the Lava Production Facility. _Ignore newline characters_ when parsing the initialization sequence. To verify that your HASH algorithm is working, the book offers the sum of the result of running the HASH algorithm on each step in the initialization sequence.
For example:
```
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7
```
This initialization sequence specifies 11 individual steps; the result of running the HASH algorithm on each of the steps is as follows:
- `rn=1` becomes `30`.
- `cm-` becomes `253`.
- `qp=3` becomes `97`.
- `cm=2` becomes `47`.
- `qp-` becomes `14`.
- `pc=4` becomes `180`.
- `ot=9` becomes `9`.
- `ab=5` becomes `197`.
- `pc-` becomes `48`.
- `pc=6` becomes `214`.
- `ot=7` becomes `231`.
In this example, the sum of these results is `1320`. Unfortunately, the reindeer has stolen the page containing the expected verification number and is currently running around the facility with it excitedly.
Run the HASH algorithm on each step in the initialization sequence. _What is the sum of the results?_ (The initialization sequence is one long line; be careful when copy-pasting it.)

112
2023/15/code.go Normal file
View File

@@ -0,0 +1,112 @@
package main
import (
"fmt"
"strconv"
"strings"
"github.com/jpillora/puzzler/harness/aoc"
)
func main() {
aoc.Harness(run)
}
// on code change, run will be executed 4 times:
// 1. with: false (part1), and example input
// 2. with: true (part2), and example input
// 3. with: false (part1), and user input
// 4. with: true (part2), and user input
// the return value of each run is printed to stdout
type Lense struct {
Label string
Focus int
}
func run(part2 bool, input string) any {
// when you're ready to do part 2, remove this "not implemented" block
if part2 {
boxes := make([][]Lense, 256)
for _, l := range strings.Split(input, "\n") {
if l == "" {
continue
}
for _, s := range strings.Split(l, ",") {
if strings.Contains(s, "-") {
// Dash logic
spl := strings.Split(s, "-")
label := spl[0]
box := hash(label)
remove:
for i := range boxes[box] {
if boxes[box][i].Label == label {
boxes[box] = append(boxes[box][:i], boxes[box][i+1:]...)
break remove
}
}
} else if strings.Contains(s, "=") {
// Eq logic
spl := strings.Split(s, "=")
label := spl[0]
lens, _ := strconv.Atoi(spl[1])
box := hash(label)
insert := Lense{label, lens}
replaced := false
replace:
for i := range boxes[box] {
if boxes[box][i].Label == label {
boxes[box][i] = insert
replaced = true
break replace
}
}
if !replaced {
boxes[box] = append(boxes[box], insert)
}
} else {
panic(fmt.Sprintf("bad control '%v'", s))
}
}
}
// Calculate
sum := 0
for b := range boxes {
for l := range boxes[b] {
val := (1 + b) * (1 + l) * boxes[b][l].Focus
sum += val
}
}
return sum
}
// solve part 1 here
hsum := 0
for _, l := range strings.Split(input, "\n") {
for _, s := range strings.Split(l, ",") {
hsum += hash(s)
}
}
return hsum
}
func hash(str string) int {
h := 0
for _, s := range str {
ascii := int(rune(s))
h += ascii
h *= 17
h = h % 256
}
return h
}

1
2023/15/input-example.txt Executable file
View File

@@ -0,0 +1 @@
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7

1
2023/15/input-user.txt Normal file

File diff suppressed because one or more lines are too long