advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

main.go (2030B)

    1 package main
    2 
    3 import (
    4 	"bufio"
    5 	"fmt"
    6 	"os"
    7 )
    8 
    9 const (
   10 	PAREN_L = '(' - '0'
   11 	PAREN_R = ')' - '0'
   12 	PLUS    = '+' - '0'
   13 	MULT    = '*' - '0'
   14 )
   15 
   16 func readInput(filename string) (res [][]int) {
   17 	file, _ := os.Open(filename)
   18 	defer file.Close()
   19 
   20 	scanner := bufio.NewScanner(file)
   21 	res = [][]int{}
   22 	for scanner.Scan() {
   23 		line := []int{}
   24 		for _, ch := range scanner.Text() {
   25 			if ch != ' ' {
   26 				line = append(line, int(ch-'0'))
   27 			}
   28 		}
   29 		res = append(res, line)
   30 	}
   31 	return
   32 }
   33 
   34 func main() {
   35 	input := readInput("./input.txt")
   36 	// 280014646144
   37 	fmt.Println(part1(input))
   38 	// 9966990988262
   39 	fmt.Println(part2(input))
   40 }
   41 
   42 func infixToPostfix(tokens []int, priority map[int]int) (res []int) {
   43 	ops := []int{}
   44 	for _, token := range tokens {
   45 		switch token {
   46 		case PAREN_L:
   47 			ops = append(ops, PAREN_L)
   48 		case PAREN_R:
   49 			for len(ops) > 0 && ops[len(ops)-1] != PAREN_L {
   50 				res, ops = append(res, ops[len(ops)-1]), ops[:len(ops)-1]
   51 			}
   52 			ops = ops[:len(ops)-1] // Remove PAREN_L
   53 		case PLUS, MULT:
   54 			for len(ops) > 0 &&
   55 				ops[len(ops)-1] != PAREN_L &&
   56 				priority[ops[len(ops)-1]] >= priority[token] {
   57 				res, ops = append(res, ops[len(ops)-1]), ops[:len(ops)-1]
   58 			}
   59 			ops = append(ops, token)
   60 		default:
   61 			res = append(res, token)
   62 		}
   63 	}
   64 	for len(ops) > 0 {
   65 		res, ops = append(res, ops[len(ops)-1]), ops[:len(ops)-1]
   66 	}
   67 	return
   68 }
   69 
   70 func calcPostfix(tokens []int) int64 {
   71 	vals := []int64{}
   72 	for _, token := range tokens {
   73 		switch token {
   74 		case PLUS:
   75 			vals[len(vals)-2] += vals[len(vals)-1]
   76 			vals = vals[:len(vals)-1]
   77 		case MULT:
   78 			vals[len(vals)-2] *= vals[len(vals)-1]
   79 			vals = vals[:len(vals)-1]
   80 		default:
   81 			vals = append(vals, int64(token))
   82 		}
   83 	}
   84 	return vals[0]
   85 }
   86 
   87 func part1(input [][]int) (sum int64) {
   88 	priority := map[int]int{}
   89 	for _, tokens := range input {
   90 		sum += calcPostfix(infixToPostfix(tokens, priority))
   91 	}
   92 	return
   93 }
   94 
   95 func part2(input [][]int) (sum int64) {
   96 	priority := map[int]int{PLUS: 1}
   97 	for _, tokens := range input {
   98 		sum += calcPostfix(infixToPostfix(tokens, priority))
   99 	}
  100 	return
  101 }