package main import ( "fmt" "io/ioutil" "regexp" "strconv" "strings" ) type Entry map[string]string type Validator func(i Entry) bool // i is a string because reasons func numRange(i string, start, end int) bool { d, err := strconv.Atoi(i) if err != nil { return false } if d >= start && d <= end { return true } return false } func validByr(i Entry) bool { return numRange(i["byr"], 1920, 2002) } func validIyr(i Entry) bool { return numRange(i["iyr"], 2010, 2020) } func validEyr(i Entry) bool { return numRange(i["eyr"], 2020, 2030) } func validHgt(i Entry) bool { if strings.HasSuffix(i["hgt"], "cm") { return numRange(strings.TrimSuffix(i["hgt"], "cm"), 150, 193) } else if strings.HasSuffix(i["hgt"], "in") { return numRange(strings.TrimSuffix(i["hgt"], "in"), 59, 76) } else { return false } } func validHcl(i Entry) bool { match, err := regexp.Match(`^#[0-9a-f]{6}$`, []byte(i["hcl"])) if err != nil { return false } return match } func validEcl(i Entry) bool { v := false for _, c := range []string{"amb", "blu", "brn", "gry", "grn", "hzl", "oth"} { if i["ecl"] == c { v = true } } return v } func validPid(i Entry) bool { match, err := regexp.Match(`^\d{9}$`, []byte(i["pid"])) if err != nil { return false } return match } func main() { var entries []Entry d, _ := ioutil.ReadFile("in4.txt") s := string(d) splits := strings.Split(s, "\n\n") for _, s := range splits { fields := strings.Fields(s) m := make(map[string]string) for _, f := range fields { d := strings.Split(f, ":") m[d[0]] = d[1] } entries = append(entries, m) } var valid []Entry reqs := []string{"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"} for _, e := range entries { hasall := true for _, r := range reqs { if _, exists := e[r]; !exists { hasall = false } } if hasall == true { valid = append(valid, e) } } fmt.Printf("Valid Structure: %d\n", len(valid)) total := 0 validations := []Validator{validByr, validIyr, validEyr, validHgt, validHcl, validEcl, validPid} for _, e := range valid { v := true for _, f := range validations { if !f(e) { v = false } } if v == true { total += 1 } } fmt.Printf("Valid Data: %d\n", total) }