[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