package main import ( "bufio" "io" "log" "os" "strings" ) func main() { fields := []string{ "byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid", "cid", } optionalFields := []string{ "cid", } f, err := os.Open("input") if err != nil { panic(err) } validPasses := 0 currentPassValues := map[string]string{} currentPassIsInvalid := false r := bufio.NewReader(f) // log.Println("=== New pass ===") for { line, err := r.ReadString('\n') if err != io.EOF && err != nil { panic(nil) } if err == io.EOF { line = "" } line = strings.TrimSpace(line) if len(currentPassValues) <= 0 && err == io.EOF { break } if len(currentPassValues) <= 0 && len(line) == 0 { continue } if len(currentPassValues) > 0 && (err == io.EOF || len(line) == 0) { // Check if all required fields can be found b: for _, fieldName := range fields { if _, ok := currentPassValues[fieldName]; !ok { // field is missing for _, optionalFieldName := range optionalFields { if optionalFieldName == fieldName { // skip this field for check log.Printf("-- %s is missing (optional)", fieldName) break b } } log.Printf("-- %s is missing", fieldName) currentPassIsInvalid = true break b } } if currentPassIsInvalid { log.Println("** INVALID", currentPassValues) } else { log.Println("** VALID", currentPassValues) validPasses++ } // log.Println("=== New pass ===") currentPassValues = map[string]string{} currentPassIsInvalid = false } if !currentPassIsInvalid { passFields := strings.Fields(line) for _, field := range passFields { fieldSplit := strings.SplitN(field, ":", 2) fieldName := fieldSplit[0] fieldValue := fieldSplit[1] // log.Printf("<- %s %s\n", fieldName, fieldValue) if _, ok := currentPassValues[fieldName]; ok { currentPassIsInvalid = true log.Println("-- dupe:", fieldName) } currentPassValues[fieldName] = fieldValue } } } log.Printf("%d passes valid\n", validPasses) }