137 lines
2.6 KiB
Go
137 lines
2.6 KiB
Go
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))
|
|
}
|