[ADD] Added day 17 solution
This commit is contained in:
parent
f8fbc4531d
commit
ff3010e617
3 changed files with 319 additions and 0 deletions
5
17/input.txt
Normal file
5
17/input.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Register A: 64012472
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 2,4,1,7,7,5,0,3,1,7,4,1,5,5,3,0
|
||||||
309
17/main.go
Normal file
309
17/main.go
Normal file
|
|
@ -0,0 +1,309 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FILE_PATH = "./input.txt"
|
||||||
|
|
||||||
|
//const FILE_PATH = "./sample.txt"
|
||||||
|
|
||||||
|
func LoadInput(filename string) ([]string, error) {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
lines = append(lines, scanner.Text())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComputerParams struct {
|
||||||
|
startA int
|
||||||
|
startB int
|
||||||
|
startC int
|
||||||
|
program []int
|
||||||
|
}
|
||||||
|
|
||||||
|
type structuredInput = ComputerParams
|
||||||
|
|
||||||
|
func TransformInput(lines []string) structuredInput {
|
||||||
|
var startA int
|
||||||
|
var startB int
|
||||||
|
var startC int
|
||||||
|
var numb int
|
||||||
|
var numbs []string
|
||||||
|
var program = make([]int, 0)
|
||||||
|
|
||||||
|
startA, _ = strconv.Atoi(lines[0][len("Register A: "):])
|
||||||
|
startB, _ = strconv.Atoi(lines[1][len("Register B: "):])
|
||||||
|
startC, _ = strconv.Atoi(lines[2][len("Register C: "):])
|
||||||
|
|
||||||
|
numbs = strings.Split(lines[4][len("Program: "):], ",")
|
||||||
|
|
||||||
|
for _, temp := range numbs {
|
||||||
|
numb, _ = strconv.Atoi(temp)
|
||||||
|
program = append(program, numb)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ComputerParams{startA, startB, startC, program}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Program struct {
|
||||||
|
a int
|
||||||
|
b int
|
||||||
|
c int
|
||||||
|
|
||||||
|
i int
|
||||||
|
out []int
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
ADV = iota
|
||||||
|
BXL = iota
|
||||||
|
BST = iota
|
||||||
|
JNZ = iota
|
||||||
|
BXC = iota
|
||||||
|
OUT = iota
|
||||||
|
BDV = iota
|
||||||
|
CDV = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
func getCombo(program Program, operand int) int {
|
||||||
|
if operand >= 0 && operand <= 3 {
|
||||||
|
return operand
|
||||||
|
}
|
||||||
|
|
||||||
|
if operand == 4 {
|
||||||
|
return program.a
|
||||||
|
}
|
||||||
|
if operand == 5 {
|
||||||
|
return program.b
|
||||||
|
}
|
||||||
|
if operand == 6 {
|
||||||
|
return program.c
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeProgram(params ComputerParams) Program {
|
||||||
|
var program = Program{params.startA, params.startB, params.startC, 0, make([]int, 0)}
|
||||||
|
var opcode int
|
||||||
|
var operand int
|
||||||
|
var value int
|
||||||
|
|
||||||
|
for program.i < len(params.program) {
|
||||||
|
opcode = params.program[program.i]
|
||||||
|
operand = params.program[program.i+1]
|
||||||
|
|
||||||
|
switch opcode {
|
||||||
|
case ADV:
|
||||||
|
{
|
||||||
|
value = getCombo(program, operand)
|
||||||
|
program.a = int(float64(program.a) / math.Pow(2, float64(value)))
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
case BXL:
|
||||||
|
{
|
||||||
|
program.b = program.b ^ operand
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
case BST:
|
||||||
|
{
|
||||||
|
value = getCombo(program, operand)
|
||||||
|
program.b = value % 8
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
case JNZ:
|
||||||
|
{
|
||||||
|
if program.a != 0 {
|
||||||
|
program.i = operand
|
||||||
|
} else {
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case BXC:
|
||||||
|
{
|
||||||
|
program.b = program.b ^ program.c
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
case OUT:
|
||||||
|
{
|
||||||
|
program.out = append(program.out, getCombo(program, operand)%8)
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
case BDV:
|
||||||
|
{
|
||||||
|
value = getCombo(program, operand)
|
||||||
|
program.b = int(float64(program.a) / math.Pow(2, float64(value)))
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
case CDV:
|
||||||
|
{
|
||||||
|
value = getCombo(program, operand)
|
||||||
|
program.c = int(float64(program.a) / math.Pow(2, float64(value)))
|
||||||
|
program.i += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return program
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part1(input structuredInput) int {
|
||||||
|
var result int = 0
|
||||||
|
input.startA = 265652340990877
|
||||||
|
var program = executeProgram(input)
|
||||||
|
for i := 0; i < len(program.out); i++ {
|
||||||
|
fmt.Printf("%d,", program.out[i])
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
var numbs = [][]int{
|
||||||
|
[]int{0, 0, 0},
|
||||||
|
[]int{0, 0, 1},
|
||||||
|
[]int{0, 1, 0},
|
||||||
|
[]int{0, 1, 1},
|
||||||
|
[]int{1, 0, 0},
|
||||||
|
[]int{1, 0, 1},
|
||||||
|
[]int{1, 1, 0},
|
||||||
|
[]int{1, 1, 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
func clone(input []int) []int {
|
||||||
|
var result = make([]int, len(input))
|
||||||
|
|
||||||
|
for i, numb := range input {
|
||||||
|
result[i] = numb
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func insert(numbers []int, numb []int, position int) ([]int, bool) {
|
||||||
|
var result = clone(numbers)
|
||||||
|
for i := 0; i < len(numb); i++ {
|
||||||
|
if position+i < 0 && numb[i] == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if numbers[position+i] != -1 && numbers[position+i] != numb[i] {
|
||||||
|
return []int{}, true
|
||||||
|
}
|
||||||
|
result[position+i] = numb[i]
|
||||||
|
}
|
||||||
|
return result, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func invs(is []int, should []int) []int {
|
||||||
|
var result = []int{0, 0, 0}
|
||||||
|
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
if should[i] == 1 && is[i] == 0 || should[i] == 0 && is[i] == 1 {
|
||||||
|
result[i] = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func bToi(numbers []int) int {
|
||||||
|
var result = 0
|
||||||
|
var pow = math.Pow(2, float64(len(numbers)-1))
|
||||||
|
for i := 0; i < len(numbers); i++ {
|
||||||
|
result += numbers[i] * int(pow)
|
||||||
|
pow = pow / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part2(input structuredInput) int {
|
||||||
|
var result int = 0
|
||||||
|
var poss [][]int = make([][]int, 1)
|
||||||
|
var next [][]int = make([][]int, 0)
|
||||||
|
var number []int = make([]int, 3*16)
|
||||||
|
var error bool
|
||||||
|
var position int
|
||||||
|
var temp []int
|
||||||
|
var work []int
|
||||||
|
for i := 0; i < len(number); i++ {
|
||||||
|
number[i] = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
poss[0] = number
|
||||||
|
|
||||||
|
for j := 15; j >= 0; j-- {
|
||||||
|
next = make([][]int, 0)
|
||||||
|
for i := 0; i < len(poss); i++ {
|
||||||
|
work = poss[i]
|
||||||
|
position = j * 3
|
||||||
|
for m := 0; m < len(numbs); m++ {
|
||||||
|
temp, error = insert(work, numbs[m], position)
|
||||||
|
if error {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
temp, error = insert(temp, invs(numbs[m], numbs[input.program[len(input.program)-j-1]]), position-(7-m))
|
||||||
|
if error {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
next = append(next, temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
poss = next
|
||||||
|
}
|
||||||
|
|
||||||
|
var lowest int = -1
|
||||||
|
var dec int
|
||||||
|
for i := 0; i < len(poss); i++ {
|
||||||
|
dec = bToi(poss[i])
|
||||||
|
if lowest == -1 || lowest > dec {
|
||||||
|
lowest = dec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = lowest
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var start time.Time
|
||||||
|
var elapsed time.Duration = 0
|
||||||
|
input, err := LoadInput(FILE_PATH)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error loading input:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
structuredInput := TransformInput(input)
|
||||||
|
fmt.Println("Structured Input:", structuredInput)
|
||||||
|
|
||||||
|
start = time.Now()
|
||||||
|
fmt.Println("Solution Part 1: ", Part1(structuredInput))
|
||||||
|
elapsed = time.Since(start)
|
||||||
|
fmt.Printf("Part 1 took %s\n", elapsed)
|
||||||
|
|
||||||
|
start = time.Now()
|
||||||
|
fmt.Println("Solution Part 2: ", Part2(structuredInput))
|
||||||
|
elapsed = time.Since(start)
|
||||||
|
fmt.Printf("Part 2 took %s\n", elapsed)
|
||||||
|
}
|
||||||
5
17/sample.txt
Normal file
5
17/sample.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Register A: 2024
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,3,5,4,3,0
|
||||||
Loading…
Reference in a new issue