adventofcode/2018/day05/day05.go

106 lines
1.8 KiB
Go
Raw Normal View History

2018-12-05 14:57:22 +00:00
package main
import (
"bufio"
2018-12-05 15:12:29 +00:00
"bytes"
2018-12-05 14:57:22 +00:00
"fmt"
"log"
"os"
"strconv"
)
func main() {
2018-12-05 15:12:29 +00:00
inp := []byte(StdinToString())
2018-12-05 14:57:22 +00:00
fmt.Println("= Part 1 =")
fmt.Println(part1(inp))
fmt.Println("\n= Part 2 =")
fmt.Println(part2(inp))
}
2018-12-05 15:12:29 +00:00
func part1(inp []byte) int {
2018-12-05 14:57:22 +00:00
last := inp
curr := react(last)
2018-12-05 15:12:29 +00:00
for !bytes.Equal(last, curr) {
2018-12-05 14:57:22 +00:00
last = curr
curr = react(last)
}
return len(curr)
}
// useShortest will skip runs where there are fewer letters in the input than the current shortest...
// It reduced _my_ runtime by about 3 minutes, but may fail depending on your input
var useShortest bool
2018-12-05 15:12:29 +00:00
func part2(inp []byte) int {
2018-12-05 14:57:22 +00:00
// If yours fails, try setting this to false
useShortest = true
shortest := len(inp)
var shortestCount int
var count int
for i := 65; i <= 90; i++ {
2018-12-05 15:12:29 +00:00
var try []byte
2018-12-05 14:57:22 +00:00
if useShortest {
2018-12-05 15:12:29 +00:00
count = countByte(inp, byte(i))
2018-12-05 14:57:22 +00:00
if count < shortestCount {
continue
}
}
for j := range inp {
if int(inp[j]) == i || int(inp[j]) == i+32 {
continue
}
2018-12-05 15:12:29 +00:00
try = append(try, inp[j])
2018-12-05 14:57:22 +00:00
}
v := part1(try)
if v < shortest {
shortest = v
shortestCount = count
}
}
return shortest
}
2018-12-05 15:12:29 +00:00
func countByte(h []byte, n byte) int {
var ret int
for i := range h {
if h[i] == n {
ret++
}
}
return ret
}
func react(v []byte) []byte {
var ret []byte
2018-12-05 14:57:22 +00:00
for i := 0; i < len(v); i++ {
2018-12-05 15:39:41 +00:00
if i < len(v)-1 && sameDecase(v[i], v[i+1]) {
2018-12-05 14:57:22 +00:00
i++
continue
}
2018-12-05 15:12:29 +00:00
ret = append(ret, v[i])
2018-12-05 14:57:22 +00:00
}
return ret
}
func StdinToString() string {
var input string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input += scanner.Text()
}
return input
}
func Atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi")
}
return ret
}
2018-12-05 15:39:41 +00:00
func sameDecase(val1, val2 byte) bool {
return val1+32 == val2 || val2+32 == val1
2018-12-05 14:57:22 +00:00
}