day16 part1

This commit is contained in:
Alex Chao
2020-08-04 21:12:29 -04:00
parent 627540fe31
commit a3f3210c46
3 changed files with 201 additions and 2 deletions
+4 -2
View File
@@ -1,9 +1,10 @@
# Advent of Code 2019
Language: GoLang.
[https://adventofcode.com/2019](https://adventofcode.com/2019)
---
## Summary of Days
## Summary
Day | Name | Type of Algo & Notes
--- | --- | ---
1 | The Tyranny of the Rocket Equation | - Simple math problem
@@ -20,4 +21,5 @@ Day | Name | Type of Algo & Notes
12 | The N-Body Problem | I like to call this a _(harmonic) frequency_ algo. Finding the harmonic frequency of multiple bodies/items and then finding the Least Common Multiple of those frequencies will tell you when all the bodies have returned to their initial state. <br> - I've used this approach for a leetcode problem about prisoners in jail cells too
13 | Care Package | Intcode again! It's basically every other day... <br> - part1: 2D array manipulation again <br> - part2: holy algo, some logic to basically play Bricks game. <br> - This is more of a design question for how you manage state
14 | Space Stoichiometry | __Weighted Graph and Breadth First Traversals__ <br> - Because not all of the products have a quantity of 1, it complicates the graph's data model. I ended up mapping the product/chemical name to a map of its stoichiometry where the product's number is positive & reactants were negative. <br> - part2: not just a simple division because of "extra byproducts" of generating each piece of fuel. I just let this brute force thing run for ~30 seconds...
15 | Oxygen System | YAY INTCODE 🙄 <br> - Combination of __searching algo__, __backtracking algo__ and the the Intcode... <br> - I've realized that I really need to stop using x and y for 2D grids and start using row and col because mathematically x is horizontal and y is vertical... My brain is all jumbled up <br> - Created a Robot struct/class that has a computer inside of it. It goes and searches around, collecting data on the floor types at various coordinates. That data is transformed into a 2D grid/array, and then finally fed into a backtracking, searching algorithm to determine the shortest path (turns out there's only one path to the O2 tank...) <br> - part2 is fairly straight forward 2D grid traversing and tagging a spread of oxygen to valid tiles/hallway spaces
15 | Oxygen System | YAY INTCODE 🙄 <br> - Combination of __2D grid searching algo__, __backtracking algo__ and the the Intcode... <br> - I've realized that I really need to stop using x and y for 2D grids and start using row and col because mathematically x is horizontal and y is vertical... My brain is all jumbled up <br> - Created a Robot struct/class that has a computer inside of it. It goes and searches around, collecting data on the floor types at various coordinates. That data is transformed into a 2D grid/array, and then finally fed into a backtracking, searching algorithm to determine the shortest path (turns out there's only one path to the O2 tank...) <br> - part2 is fairly straight forward 2D grid traversing and tagging a spread of oxygen to valid tiles/hallway spaces
16 | Flawed Frequency Transmission | - Some really weird, contrived (as if this whole thing isn't) phase calculator?..
+118
View File
@@ -0,0 +1,118 @@
--- Day 15: Oxygen System ---
Out here in deep space, many things can go wrong. Fortunately, many of those things have indicator lights. Unfortunately, one of those lights is lit: the oxygen system for part of the ship has failed!
According to the readouts, the oxygen system must have failed days ago after a rupture in oxygen tank two; that section of the ship was automatically sealed once oxygen levels went dangerously low. A single remotely-operated repair droid is your only option for fixing the oxygen system.
The Elves' care package included an Intcode program (your puzzle input) that you can use to remotely control the repair droid. By running that program, you can direct the repair droid to the oxygen system and fix the problem.
The remote control program executes the following steps in a loop forever:
Accept a movement command via an input instruction.
Send the movement command to the repair droid.
Wait for the repair droid to finish the movement operation.
Report on the status of the repair droid via an output instruction.
Only four movement commands are understood: north (1), south (2), west (3), and east (4). Any other command is invalid. The movements differ in direction, but not in distance: in a long enough east-west hallway, a series of commands like 4,4,4,4,3,3,3,3 would leave the repair droid back where it started.
The repair droid can reply with any of the following status codes:
0: The repair droid hit a wall. Its position has not changed.
1: The repair droid has moved one step in the requested direction.
2: The repair droid has moved one step in the requested direction; its new position is the location of the oxygen system.
You don't know anything about the area around the repair droid, but you can figure it out by watching the status codes.
For example, we can draw the area using D for the droid, # for walls, . for locations the droid can traverse, and empty space for unexplored locations. Then, the initial state looks like this:
D
To make the droid go north, send it 1. If it replies with 0, you know that location is a wall and that the droid didn't move:
#
D
To move east, send 4; a reply of 1 means the movement was successful:
#
.D
Then, perhaps attempts to move north (1), south (2), and east (4) are all met with replies of 0:
##
.D#
#
Now, you know the repair droid is in a dead end. Backtrack with 3 (which you already know will get a reply of 1 because you already know that location is open):
##
D.#
#
Then, perhaps west (3) gets a reply of 0, south (2) gets a reply of 1, south again (2) gets a reply of 0, and then west (3) gets a reply of 2:
##
#..#
D.#
#
Now, because of the reply of 2, you know you've found the oxygen system! In this example, it was only 2 moves away from the repair droid's starting position.
What is the fewest number of movement commands required to move the repair droid from its starting position to the location of the oxygen system?
Your puzzle answer was 280.
--- Part Two ---
You quickly repair the oxygen system; oxygen gradually fills the area.
Oxygen starts in the location containing the repaired oxygen system. It takes one minute for oxygen to spread to all open locations that are adjacent to a location that already contains oxygen. Diagonal locations are not adjacent.
In the example above, suppose you've used the droid to explore the area fully and have the following map (where locations that currently contain oxygen are marked O):
##
#..##
#.#..#
#.O.#
###
Initially, the only location which contains oxygen is the location of the repaired oxygen system. However, after one minute, the oxygen spreads to all open (.) locations that are adjacent to a location containing oxygen:
##
#..##
#.#..#
#OOO#
###
After a total of two minutes, the map looks like this:
##
#..##
#O#O.#
#OOO#
###
After a total of three minutes:
##
#O.##
#O#OO#
#OOO#
###
And finally, the whole region is full of oxygen after a total of four minutes:
##
#OO##
#O#OO#
#OOO#
###
So, in this example, all locations contain oxygen after 4 minutes.
Use the repair droid to get a complete map of the area. How many minutes will it take to fill with oxygen?
Your puzzle answer was 400.
Both parts of this puzzle are complete! They provide two gold stars: **
+79
View File
@@ -0,0 +1,79 @@
package main
import (
"adventofcode/util"
"fmt"
"log"
"strconv"
"strings"
)
func main() {
// parse input file into a slice of numbers
input := util.ReadFile("../input.txt")
characters := strings.Split(input, "")
digits := make([]int, len(characters))
for i, v := range characters {
digits[i], _ = strconv.Atoi(v)
}
// generate all patterns once at start
patterns := make([][]int, len(digits))
for i := range digits {
patterns[i] = generatePattern(i+1, len(digits))
}
// run through 100 phases, overwriting digits
for i := 0; i < 100; i++ {
digits = getNextOutputNumber(digits, patterns)
}
// Transform into AoC output
var firstEightDigits int
for i := 0; i < 8; i++ {
firstEightDigits *= 10
firstEightDigits += digits[i]
}
fmt.Printf("First 8 digits after 100 phases: %v\n", firstEightDigits)
}
// generatePattern takes in the index (one indexed, not zero) that is being considered, and returns the pattern to multiply
// digits by
func generatePattern(oneIndex, lengthNeeded int) []int {
if oneIndex < 1 {
log.Fatal("Input to generatePattern must be a positive int")
}
basePattern := []int{0, 1, 0, -1}
pattern := make([]int, 0, 4*(oneIndex+1))
for len(pattern)-1 < lengthNeeded {
for _, v := range basePattern {
for i := 0; i < oneIndex; i++ {
pattern = append(pattern, v)
}
}
}
return pattern[1 : lengthNeeded+1]
}
// takes in digits and all patterns, generates next set of digits
func getNextOutputNumber(digits []int, patterns [][]int) []int {
output := make([]int, len(digits))
for index := range digits {
// for this index, sum up all products of digits and this index's pattern
var sum int
for i := 0; i < len(digits); i++ {
sum += patterns[index][i] * digits[i]
}
// ensure the sum is positive & take the single's place digit
if sum < 0 {
sum *= -1
}
sum %= 10
// assign to output slice for the same index
output[index] = sum
}
return output
}