package main import ( "bufio" "fmt" "log" "os" "regexp" "strconv" "strings" ) func proccessLines(path string, f func(string) (stop bool, err error)) error { file, err := os.Open(path) if err != nil { return err } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { stop, err := f(scanner.Text()) if stop || err != nil { return err } } if err := scanner.Err(); err != nil { return err } return nil } var matcher = regexp.MustCompile(`([0-9]+)-([0-9]+) ([a-zA-Z]): ([a-zA-Z]+)`) func part1() { totalValid := 0 err := proccessLines("input.txt", func(line string) (stop bool, err error) { results := matcher.FindStringSubmatch(line) if results == nil { err = fmt.Errorf("invalid line %s", line) return } minCount, err := strconv.Atoi(results[1]) if err != nil { return } maxCount, err := strconv.Atoi(results[2]) if err != nil { return } letter := results[3] password := results[4] // fmt.Printf("Make sure %s is in %s between %d and %d times\n", letter, password, minCount, maxCount) // Validate count := strings.Count(password, letter) if minCount <= count && count <= maxCount { totalValid++ } return }) if err != nil { log.Fatal(err) } fmt.Printf("Total valid %d\n", totalValid) } func part2() { totalValid := 0 err := proccessLines("input.txt", func(line string) (stop bool, err error) { results := matcher.FindStringSubmatch(line) if results == nil { err = fmt.Errorf("invalid line %s", line) return } pos1, err := strconv.Atoi(results[1]) if err != nil { return } pos2, err := strconv.Atoi(results[2]) if err != nil { return } // 1 vs 0 indexed pos1-- pos2-- letter := results[3] password := results[4] // fmt.Printf("Make sure %s is in %s between %d and %d times\n", letter, password, minCount, maxCount) // Validate if pos1 >= len(password) || pos2 >= len(password) { return } letter1 := string(password[pos1]) letter2 := string(password[pos2]) if (letter == letter1 || letter == letter2) && letter1 != letter2 { totalValid++ } return }) if err != nil { log.Fatal(err) } fmt.Printf("Total valid %d\n", totalValid) } func main() { part1() part2() }