main.go (2264B)
1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "os" 7 "regexp" 8 ) 9 10 func readInput(filename string) (res []map[string]string) { 11 file, _ := os.Open(filename) 12 defer file.Close() 13 14 scanner := bufio.NewScanner(file) 15 matcher := regexp.MustCompile(`(eyr|hgt|hcl|pid|byr|ecl|iyr|cid):([^ ]+)`) 16 passport := make(map[string]string) 17 for scanner.Scan() { 18 line := scanner.Text() 19 if line == "" { 20 res = append(res, passport) 21 passport = make(map[string]string) 22 } else { 23 matches := matcher.FindAllStringSubmatch(line, -1) 24 for _, kv := range matches { 25 passport[kv[1]] = kv[2] 26 } 27 } 28 } 29 res = append(res, passport) 30 return 31 } 32 33 func main() { 34 input := readInput("./input.txt") 35 // 260 36 fmt.Println(part1(input)) 37 // 153 38 fmt.Println(part2(input)) 39 } 40 41 func isValid(pp map[string]string) bool { 42 _, has_cid := pp["cid"] 43 return len(pp) == 8 || (len(pp) == 7 && !has_cid) 44 } 45 46 func part1(input []map[string]string) (valid_count int) { 47 for _, pp := range input { 48 if isValid(pp) { 49 valid_count += 1 50 } 51 } 52 return 53 } 54 55 func isValid2(pp map[string]string) bool { 56 valid := isValid(pp) 57 if valid { 58 ok, _ := regexp.MatchString(`^[0-9]{4}$`, pp["byr"]) 59 valid = valid && ok && (pp["byr"] >= "1920" && pp["byr"] <= "2002") 60 } 61 if valid { 62 ok, _ := regexp.MatchString(`^[0-9]{4}$`, pp["iyr"]) 63 valid = valid && ok && (pp["iyr"] >= "2010" && pp["iyr"] <= "2020") 64 } 65 if valid { 66 ok, _ := regexp.MatchString(`^[0-9]{4}$`, pp["eyr"]) 67 valid = valid && ok && (pp["eyr"] >= "2020" && pp["eyr"] <= "2030") 68 } 69 if valid { 70 matcher := regexp.MustCompile(`^([0-9]{2,3})(cm|in)$`) 71 matches := matcher.FindStringSubmatch(pp["hgt"]) 72 valid = valid && matches != nil && 73 ((matches[2] == "cm" && matches[1] >= "150" && matches[1] <= "193") || 74 (matches[2] == "in" && matches[1] >= "59" && matches[1] <= "76")) 75 } 76 if valid { 77 ok, _ := regexp.MatchString(`^#[0-9a-f]{6}$`, pp["hcl"]) 78 valid = valid && ok 79 } 80 if valid { 81 ok, _ := regexp.MatchString(`^(amb|blu|brn|gry|grn|hzl|oth)$`, pp["ecl"]) 82 valid = valid && ok 83 } 84 if valid { 85 ok, _ := regexp.MatchString(`^[0-9]{9}$`, pp["pid"]) 86 valid = valid && ok 87 } 88 return valid 89 } 90 91 func part2(input []map[string]string) (valid_count int) { 92 for _, pp := range input { 93 if isValid2(pp) { 94 valid_count += 1 95 } 96 } 97 return 98 }