mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
finished day25!
This commit is contained in:
@@ -31,3 +31,4 @@ Day | Name | Type of Algo & Notes
|
|||||||
22 | Slam Shuffle | - Seems fairly easy at first... But the part 2 has numbers somewhere in the 32-bit number to 64-bit number range... So the part 1 code is pretty much useless... <br> I gave up on part 2. It's some crazy __linear algebra with modular inverses?..__ Theoretically it makes some sense.. but I had to read someone else's solution for hours to kind of understand the implementation...
|
22 | Slam Shuffle | - Seems fairly easy at first... But the part 2 has numbers somewhere in the 32-bit number to 64-bit number range... So the part 1 code is pretty much useless... <br> I gave up on part 2. It's some crazy __linear algebra with modular inverses?..__ Theoretically it makes some sense.. but I had to read someone else's solution for hours to kind of understand the implementation...
|
||||||
23 | Category Six | Intcode computer NETWORK of 50 computers... <br> Oof that's a lot of stuff to coordinate, but not too hard, make a Network struct. <br> Part2 doesn't seem too different, but includes a NAT device, which is simple enough to just store in variables in the goroutine... <br> That has to be record time for me to finish a day :) Sigh of relief after day22.
|
23 | Category Six | Intcode computer NETWORK of 50 computers... <br> Oof that's a lot of stuff to coordinate, but not too hard, make a Network struct. <br> Part2 doesn't seem too different, but includes a NAT device, which is simple enough to just store in variables in the goroutine... <br> That has to be record time for me to finish a day :) Sigh of relief after day22.
|
||||||
24 | Planet of Discord | Almost done... When the input if 25 character you know it's going to be a crazy AoC day... <br> Part1 is fairly straightforward _2D slice traversal_. <br> Part2 makes it a recursive map... of course <br> I chose to utilize predefined-length arrays to minimize having to make lots of slices. If the number of minutes was not known ahead of time, then a doubly linked list could have worked to expand layers indefinitely. Or a map with int-indexes because those could be negative. <br> I wrote a lot of code to just handle recursive structures... There's probably a way to clean this up and I definitely didn't plan my approach well enough before writing code
|
24 | Planet of Discord | Almost done... When the input if 25 character you know it's going to be a crazy AoC day... <br> Part1 is fairly straightforward _2D slice traversal_. <br> Part2 makes it a recursive map... of course <br> I chose to utilize predefined-length arrays to minimize having to make lots of slices. If the number of minutes was not known ahead of time, then a doubly linked list could have worked to expand layers indefinitely. Or a map with int-indexes because those could be negative. <br> I wrote a lot of code to just handle recursive structures... There's probably a way to clean this up and I definitely didn't plan my approach well enough before writing code
|
||||||
|
25 | Cryostasis | One final Intcode problem <br>
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
+------------+------------+
|
||||||
|
+------------+ | | |
|
||||||
|
| | | HOT | NAVIGATION |
|
||||||
|
| __WEIGH__ | | CHOCOLATE | *easter |
|
||||||
|
|__STATION__ | | FOUNTAIN | egg |
|
||||||
|
| | +------------+------------+
|
||||||
|
+------------+------------+ | |
|
||||||
|
| | | | STORAGE |
|
||||||
|
| SECURITY | KITCHEN | | *coin |
|
||||||
|
| CHECKPOINT | *shell | | |
|
||||||
|
| | | +--------+------------+
|
||||||
|
+------------+------------+ | | |
|
||||||
|
| | |HOLODECK| PASSAGES |
|
||||||
|
| CORRIDOR | | | *hypercube |
|
||||||
|
| *spool of | +--------| |
|
||||||
|
| cat6 | | |
|
||||||
|
+------------+------------+------------+
|
||||||
|
| | |
|
||||||
|
| CREW | ARCADE |
|
||||||
|
| QUARTERS | *giant |
|
||||||
|
| | electro |
|
||||||
|
+------------+-----+--------------+----+ magnet |
|
||||||
|
| | | ENGINE ROOM | | |
|
||||||
|
| HALLWAY | | *molten lava | +------------+
|
||||||
|
| *sand | +--------------+ | |
|
||||||
|
| | | |
|
||||||
|
+------------+------------+------------+ OBSERVATORY+------------+
|
||||||
|
| | | *asterisk | |
|
||||||
|
| STABLES | __HULL BREACH__ | | GIFT |
|
||||||
|
| *fixed | | | WRAPPING |
|
||||||
|
| point | | | STATION |
|
||||||
|
+------------+-----+--------------+----+------------+------------+------------+
|
||||||
|
| SICK BAY | | | |
|
||||||
|
|*infinite loop| | WARP | SCIENCE |
|
||||||
|
+--------------+ | DRIVE | LAB |
|
||||||
|
| *escape pod| *photons |
|
||||||
|
+------------+------------+
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
Intcode struct is defined within this file
|
||||||
|
Helper function that converts strings to ASCII codes to be written to the computer
|
||||||
|
it could all be combined together into a new computer...
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"adventofcode/util"
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// read the input file, modify it to a slice of numbers
|
||||||
|
inputFile := util.ReadFile("../input.txt")
|
||||||
|
|
||||||
|
splitStrings := strings.Split(inputFile, ",")
|
||||||
|
|
||||||
|
inputNumbers := make([]int, len(splitStrings))
|
||||||
|
for i, v := range splitStrings {
|
||||||
|
inputNumbers[i], _ = strconv.Atoi(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
comp := MakeComputer(inputNumbers)
|
||||||
|
comp.Step(-1)
|
||||||
|
|
||||||
|
for comp.IsRunning {
|
||||||
|
text := readFromCommandLine()
|
||||||
|
|
||||||
|
// write string to slice of ascii values
|
||||||
|
instruction := convertStringToASCII(text)
|
||||||
|
|
||||||
|
// write instructions to intcode/ascii computer
|
||||||
|
for _, v := range instruction {
|
||||||
|
comp.Step(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Collect four items: coin, spool of cat6, sand, and fixed point,
|
||||||
|
// NOTE: then proceed through the weigh station
|
||||||
|
// NOTE: I figured this out by picking up everything and just eliminating
|
||||||
|
// NOTE: options using the feedback of "too heavy or too light"
|
||||||
|
|
||||||
|
// ! Code is 2181046280
|
||||||
|
}
|
||||||
|
// fmt.Printf("Hull damage: %v\n", comp.Outputs[len(comp.Outputs)-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFromCommandLine() string {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
text, _ := reader.ReadString('\n')
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to convert a string to its character's ASCII values
|
||||||
|
func convertStringToASCII(input string) []int {
|
||||||
|
result := make([]int, len(input))
|
||||||
|
for i, v := range input {
|
||||||
|
// cast rune to int
|
||||||
|
result[i] = int(v)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Intcode is an OOP approach *************************************************
|
||||||
|
MakeComputer is equivalent to the constructor
|
||||||
|
Step takes in an input int and updates properties in the computer:
|
||||||
|
- InstructionIndex: where to read the next instruction from
|
||||||
|
- LastOutput, what the last opcode 4 outputted
|
||||||
|
- PuzzleIndex based if the last instruction modified the puzzle at all
|
||||||
|
****************************************************************************/
|
||||||
|
type Intcode struct {
|
||||||
|
PuzzleInput []int // file/puzzle input parsed into slice of ints
|
||||||
|
InstructionIndex int // stores the index where the next instruction is
|
||||||
|
RelativeBase int // relative base for opcode 9 and param mode 2
|
||||||
|
Outputs []int // stores all outputs
|
||||||
|
IsRunning bool // will be true until a 99 opcode is hit
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeComputer initializes a new comp
|
||||||
|
func MakeComputer(PuzzleInput []int) *Intcode {
|
||||||
|
puzzleInputCopy := make([]int, len(PuzzleInput))
|
||||||
|
copy(puzzleInputCopy, PuzzleInput)
|
||||||
|
|
||||||
|
comp := Intcode{
|
||||||
|
puzzleInputCopy,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
make([]int, 0),
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
return &comp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step will read the next 4 values in the input `sli` and make updates
|
||||||
|
// according to the opcodes
|
||||||
|
// Update to run iteratively (while the computer is running)
|
||||||
|
// it will also return out if a -1 input is asked for
|
||||||
|
// then call Step again to provide the next input, or run with -1 from the start
|
||||||
|
// to run the computer until it asks for an input OR terminates
|
||||||
|
func (comp *Intcode) Step(input int) {
|
||||||
|
for comp.IsRunning {
|
||||||
|
// read the instruction, opcode and the indexes where the params point to
|
||||||
|
opcode, paramIndexes := comp.GetOpCodeAndParamIndexes()
|
||||||
|
param1, param2, param3 := paramIndexes[0], paramIndexes[1], paramIndexes[2]
|
||||||
|
|
||||||
|
// ensure params are within the bounds of PuzzleInput, resize if necessary
|
||||||
|
switch opcode {
|
||||||
|
case 1, 2, 7, 8:
|
||||||
|
comp.ResizeMemory(param1, param2, param3)
|
||||||
|
case 5, 6:
|
||||||
|
comp.ResizeMemory(param1, param2)
|
||||||
|
case 3, 4, 9:
|
||||||
|
comp.ResizeMemory(param1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch opcode {
|
||||||
|
case 99: // 99: Terminates program
|
||||||
|
// fmt.Println("Terminating...")
|
||||||
|
comp.IsRunning = false
|
||||||
|
case 1: // 1: Add next two paramIndexes, store in third
|
||||||
|
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] + comp.PuzzleInput[param2]
|
||||||
|
comp.InstructionIndex += 4
|
||||||
|
case 2: // 2: Multiply next two and store in third
|
||||||
|
comp.PuzzleInput[param3] = comp.PuzzleInput[param1] * comp.PuzzleInput[param2]
|
||||||
|
comp.InstructionIndex += 4
|
||||||
|
case 3: // 3: Takes one input and saves it to position of one parameter
|
||||||
|
// check if input has already been used (i.e. input == -1)
|
||||||
|
// if it's been used, return out to prevent further Steps
|
||||||
|
// NOTE: making a big assumption that -1 will never be an input...
|
||||||
|
if input == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// else recurse with a -1 to signal the initial input has been processed
|
||||||
|
comp.PuzzleInput[param1] = input
|
||||||
|
comp.InstructionIndex += 2
|
||||||
|
|
||||||
|
// change the input value so the next time a 3 opcode is hit, will return out
|
||||||
|
input = -1
|
||||||
|
case 4: // 4: outputs its input value
|
||||||
|
output := comp.PuzzleInput[param1]
|
||||||
|
// set LastOutput of the computer & log it
|
||||||
|
comp.Outputs = append(comp.Outputs, output)
|
||||||
|
|
||||||
|
// NOTE: day25 specific, print out the output message
|
||||||
|
fmt.Print(string(output))
|
||||||
|
|
||||||
|
comp.InstructionIndex += 2
|
||||||
|
// 5: jump-if-true: if first param != 0, move pointer to second param, else nothing
|
||||||
|
case 5:
|
||||||
|
if comp.PuzzleInput[param1] != 0 {
|
||||||
|
comp.InstructionIndex = comp.PuzzleInput[param2]
|
||||||
|
} else {
|
||||||
|
comp.InstructionIndex += 3
|
||||||
|
}
|
||||||
|
// 6: jump-if-false, if first param == 0 then set instruction pointer to 2nd param, else nothing
|
||||||
|
case 6:
|
||||||
|
if comp.PuzzleInput[param1] == 0 {
|
||||||
|
comp.InstructionIndex = comp.PuzzleInput[param2]
|
||||||
|
} else {
|
||||||
|
comp.InstructionIndex += 3
|
||||||
|
}
|
||||||
|
// 7: less-than, if param1 < param2 then store 1 in postion of 3rd param, else store 0
|
||||||
|
case 7:
|
||||||
|
if comp.PuzzleInput[param1] < comp.PuzzleInput[param2] {
|
||||||
|
comp.PuzzleInput[param3] = 1
|
||||||
|
} else {
|
||||||
|
comp.PuzzleInput[param3] = 0
|
||||||
|
}
|
||||||
|
comp.InstructionIndex += 4
|
||||||
|
// 8: equals, if param1 == param2 then set position of 3rd param to 1, else store 0
|
||||||
|
case 8:
|
||||||
|
if comp.PuzzleInput[param1] == comp.PuzzleInput[param2] {
|
||||||
|
comp.PuzzleInput[param3] = 1
|
||||||
|
} else {
|
||||||
|
comp.PuzzleInput[param3] = 0
|
||||||
|
}
|
||||||
|
comp.InstructionIndex += 4
|
||||||
|
// 9: adjust relative base
|
||||||
|
case 9:
|
||||||
|
comp.RelativeBase += comp.PuzzleInput[param1]
|
||||||
|
comp.InstructionIndex += 2
|
||||||
|
default:
|
||||||
|
log.Fatalf("Error: unknown opcode %v at index %v", opcode, comp.PuzzleInput[comp.InstructionIndex])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GetOpCodeAndParamIndexes will parse the instruction at comp.PuzzleInput[comp.InstructionIndex]
|
||||||
|
- opcode will be the left two digits, mod by 100 will get that
|
||||||
|
- rest of instructions will be grabbed via mod 10
|
||||||
|
- these also have to be parsed for the
|
||||||
|
*/
|
||||||
|
func (comp *Intcode) GetOpCodeAndParamIndexes() (int, [3]int) {
|
||||||
|
instruction := comp.PuzzleInput[comp.InstructionIndex]
|
||||||
|
|
||||||
|
// opcode is the lowest two digits, so mod by 100
|
||||||
|
opcode := instruction % 100
|
||||||
|
instruction /= 100
|
||||||
|
|
||||||
|
// assign the indexes that need to be read by reading the parameter modes
|
||||||
|
var paramIndexes [3]int
|
||||||
|
for i := 1; i <= 3 && comp.InstructionIndex+i < len(comp.PuzzleInput); i++ {
|
||||||
|
// grab the mode with a mod, last digit
|
||||||
|
mode := instruction % 10
|
||||||
|
instruction /= 10
|
||||||
|
|
||||||
|
switch mode {
|
||||||
|
case 0: // position mode, index will be the value at the index
|
||||||
|
paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i]
|
||||||
|
case 1: // immediate mode, the index itself
|
||||||
|
paramIndexes[i-1] = comp.InstructionIndex + i
|
||||||
|
case 2: // relative mode, like position mode but index is added to relative base
|
||||||
|
paramIndexes[i-1] = comp.PuzzleInput[comp.InstructionIndex+i] + comp.RelativeBase
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return opcode, paramIndexes
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResizeMemory will take any number of integers and resize the computer's memory appropriately
|
||||||
|
func (comp *Intcode) ResizeMemory(sizes ...int) {
|
||||||
|
// get largest of input sizes
|
||||||
|
maxArg := sizes[0]
|
||||||
|
for _, v := range sizes {
|
||||||
|
if v > maxArg {
|
||||||
|
maxArg = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// resize if PuzzleInput's length is shorter
|
||||||
|
if maxArg >= len(comp.PuzzleInput) {
|
||||||
|
// make empty slice to copy into, of the new, larger size
|
||||||
|
resizedPuzzleInput := make([]int, maxArg+1)
|
||||||
|
// copy old puzzle input values in
|
||||||
|
copy(resizedPuzzleInput, comp.PuzzleInput)
|
||||||
|
|
||||||
|
// overwrite puzzle input
|
||||||
|
comp.PuzzleInput = resizedPuzzleInput
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("There is no part2, the 50th star is the sun!")
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
--- Day 25: Cryostasis ---
|
||||||
|
As you approach Santa's ship, your sensors report two important details:
|
||||||
|
|
||||||
|
First, that you might be too late: the internal temperature is -40 degrees.
|
||||||
|
|
||||||
|
Second, that one faint life signature is somewhere on the ship.
|
||||||
|
|
||||||
|
The airlock door is locked with a code; your best option is to send in a small droid to investigate the situation. You attach your ship to Santa's, break a small hole in the hull, and let the droid run in before you seal it up again. Before your ship starts freezing, you detach your ship and set it to automatically stay within range of Santa's ship.
|
||||||
|
|
||||||
|
This droid can follow basic instructions and report on its surroundings; you can communicate with it through an Intcode program (your puzzle input) running on an ASCII-capable computer.
|
||||||
|
|
||||||
|
As the droid moves through its environment, it will describe what it encounters. When it says Command?, you can give it a single instruction terminated with a newline (ASCII code 10). Possible instructions are:
|
||||||
|
|
||||||
|
Movement via north, south, east, or west.
|
||||||
|
To take an item the droid sees in the environment, use the command take <name of item>. For example, if the droid reports seeing a red ball, you can pick it up with take red ball.
|
||||||
|
To drop an item the droid is carrying, use the command drop <name of item>. For example, if the droid is carrying a green ball, you can drop it with drop green ball.
|
||||||
|
To get a list of all of the items the droid is currently carrying, use the command inv (for "inventory").
|
||||||
|
Extra spaces or other characters aren't allowed - instructions must be provided precisely.
|
||||||
|
|
||||||
|
Santa's ship is a Reindeer-class starship; these ships use pressure-sensitive floors to determine the identity of droids and crew members. The standard configuration for these starships is for all droids to weigh exactly the same amount to make them easier to detect. If you need to get past such a sensor, you might be able to reach the correct weight by carrying items from the environment.
|
||||||
|
|
||||||
|
Look around the ship and see if you can find the password for the main airlock.
|
||||||
|
|
||||||
|
Your puzzle answer was 2181046280.
|
||||||
|
|
||||||
|
--- Part Two ---
|
||||||
|
As you move through the main airlock, the air inside the ship is already heating up to reasonable levels. Santa explains that he didn't notice you coming because he was just taking a quick nap. The ship wasn't frozen; he just had the thermostat set to "North Pole".
|
||||||
|
|
||||||
|
You make your way over to the navigation console. It beeps. "Status: Stranded. Please supply measurements from 49 stars to recalibrate."
|
||||||
|
|
||||||
|
"49 stars? But the Elves told me you needed fifty--"
|
||||||
|
|
||||||
|
Santa just smiles and nods his head toward the window. There, in the distance, you can see the center of the Solar System: the Sun!
|
||||||
|
|
||||||
|
The navigation console beeps again.
|
||||||
|
|
||||||
|
If you like, you can .
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||||
Reference in New Issue
Block a user