package day19 import ( "fmt" "os" "strings" "tools" ) func Part1(puzzle tools.AoCPuzzle) interface{} { input := puzzle.GetInputArray() molecule := input[len(input)-1] replacementStrings := input[:len(input)-2] outcomes := tools.NewSet() for _, line := range replacementStrings { parts := strings.Split(line, " => ") doubleChar := len(parts[0]) == 2 var result string for i, c := range molecule { if doubleChar && i == len(molecule)-1 { break } if doubleChar { if byte(c) == parts[0][0] && molecule[i+1] == parts[0][1] { result = molecule[:i] + parts[1] if i < len(molecule)-2 { result += molecule[i+2:] } outcomes.Add(result) } } else { if string(c) == parts[0] { result = molecule[:i] + parts[1] if i < len(molecule)-1 { result += molecule[i+1:] } outcomes.Add(result) } } } } return len(outcomes) } func Part2(puzzle tools.AoCPuzzle) interface{} { input := puzzle.GetInputArray() molecule := input[len(input)-1] replacementStrings := input[:len(input)-2] replacements := make(map[string]string) replacementLengths := make(map[int][]string) var maxLen, minLen int for _, s := range replacementStrings { parts := strings.Split(s, " => ") if _, ok := replacements[parts[1]]; ok { fmt.Println("Double target string found!") os.Exit(1) } else { replacements[parts[1]] = parts[0] x := len(parts[1]) if x > maxLen { maxLen = x } if x < minLen { minLen = x } if _, ok := replacementLengths[x]; ok { replacementLengths[x] = append(replacementLengths[x], parts[1]) } else { replacementLengths[x] = []string{parts[1]} } } } steps := 0 foundSomething := false for len(molecule) > 1 { foundSomething = false for x := maxLen; x >= minLen; x-- { for _, replacement := range replacementLengths[x] { if strings.Contains(molecule, replacement) { molecule = strings.Replace(molecule, replacement, replacements[replacement], 1) foundSomething = true steps++ break } } if foundSomething { break } } if !foundSomething { break } } return steps }