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 }