package main import ( "fmt" "log" "os" "regexp" "strconv" "strings" "git.annabunch.es/annabunches/adventofcode/2020/lib/util" ) func countValidPassports(input []string, step string) int { total := 0 for _, line := range input { if strings.Contains(line, "byr:") && strings.Contains(line, "iyr:") && strings.Contains(line, "eyr:") && strings.Contains(line, "hgt:") && strings.Contains(line, "hcl:") && strings.Contains(line, "ecl:") && strings.Contains(line, "pid:") { if step == "1" { total += 1 continue } i := validatePassport(line) if i == 0 { log.Printf("Failed: %s", line) } else { log.Printf("Passed: %s", line) } total += i } } return total } func validatePassport(input string) int { fields := strings.Split(input, " ") for _, field := range fields { if field == "" { continue } subFields := strings.Split(field, ":") if len(subFields) != 2 { log.Panicf("Failed to split subfields on '%s'", field) } name := subFields[0] value := subFields[1] switch name { case "byr": ivalue := makeInt(value) if ivalue < 1920 || ivalue > 2002 { return 0 } case "iyr": ivalue := makeInt(value) if ivalue < 2010 || ivalue > 2020 { return 0 } case "eyr": ivalue := makeInt(value) if ivalue < 2020 || ivalue > 2030 { return 0 } case "hgt": if strings.HasSuffix(value, "cm") { ivalue := makeInt(strings.TrimSuffix(value, "cm")) if ivalue < 150 || ivalue > 193 { return 0 } } else if strings.HasSuffix(value, "in") { ivalue := makeInt(strings.TrimSuffix(value, "in")) if ivalue < 59 || ivalue > 76 { return 0 } } else { return 0 } case "hcl": match, err := regexp.MatchString("^#[0-9a-f]{6}$", value) if err != nil { log.Panicf(err.Error()) } if !match { return 0 } case "ecl": if value != "amb" && value != "blu" && value != "brn" && value != "gry" && value != "grn" && value != "hzl" && value != "oth" { return 0 } case "pid": match, err := regexp.MatchString("^[0-9]{9}$", value) if err != nil { log.Panicf(err.Error()) } if !match { return 0 } case "cid": default: log.Panicf("Got bad field data: ") } } return 1 } func makeInt(input string) int { i, err := strconv.Atoi(input) if err != nil { log.Panicf(err.Error()) } return i } func main() { step := os.Args[1] values := util.InputParserStrings(os.Args[2]) values = util.SplitOnBlankLine(values) fmt.Println("Valid Passports:", countValidPassports(values, step)) }