package main import ( "bufio" "bytes" "fmt" "log" "os" "strconv" ) func main() { inp := []byte(StdinToString()) fmt.Println("= Part 1 =") fmt.Println(part1(inp)) fmt.Println("\n= Part 2 =") fmt.Println(part2(inp)) } func part1(inp []byte) int { last := inp curr := react(last) for !bytes.Equal(last, curr) { 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 func part2(inp []byte) int { // 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++ { var try []byte if useShortest { count = countByte(inp, byte(i)) if count < shortestCount { continue } } for j := range inp { if int(inp[j]) == i || int(inp[j]) == i+32 { continue } try = append(try, inp[j]) } v := part1(try) if v < shortest { shortest = v shortestCount = count } } return shortest } 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 for i := 0; i < len(v); i++ { if i < len(v)-1 && sameDecase(v[i], v[i+1]) { i++ continue } ret = append(ret, v[i]) } 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 } func sameDecase(val1, val2 byte) bool { return val1+32 == val2 || val2+32 == val1 }