adventofcode/2020/day04/main.go

125 lines
2.8 KiB
Go

package main
import (
"encoding/hex"
"fmt"
"strconv"
"strings"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := h.StdinToStringSlice()
var passports []*Passport
var p *Passport
p, inp = GetFirstPassport(inp)
for p != nil {
passports = append(passports, p)
p, inp = GetFirstPassport(inp)
}
var valid int
for _, t := range passports {
if t.IsValid() {
valid++
}
}
fmt.Printf("%d Valid Passports\n", valid)
}
type Passport struct {
BirthYear string
IssueYear string
Expiration string
Height string
HairColor string
EyeColor string
PassportID string
CountryID string
}
func GetFirstPassport(input []string) (*Passport, []string) {
ret := Passport{}
var k int
for k = range input {
if strings.TrimSpace(input[k]) == "" {
break
}
pts := strings.Split(input[k], " ")
for pk := range pts {
keyval := strings.Split(pts[pk], ":")
if len(keyval) == 2 {
switch keyval[0] {
case "byr":
ret.BirthYear = keyval[1]
case "iyr":
ret.IssueYear = keyval[1]
case "eyr":
ret.Expiration = keyval[1]
case "hgt":
ret.Height = keyval[1]
case "hcl":
ret.HairColor = keyval[1]
case "ecl":
ret.EyeColor = keyval[1]
case "pid":
ret.PassportID = keyval[1]
case "cid":
ret.CountryID = keyval[1]
}
}
}
}
if k == 0 {
return nil, []string{}
}
return &ret, input[k+1:]
}
func (p *Passport) ValidBirthYear() bool {
wrk, err := strconv.Atoi(p.BirthYear)
return err == nil && wrk >= 1920 && wrk <= 2002
}
func (p *Passport) ValidIssueYear() bool {
wrk, err := strconv.Atoi(p.IssueYear)
return err == nil && wrk >= 2010 && wrk <= 2020
}
func (p *Passport) ValidExpiration() bool {
wrk, err := strconv.Atoi(p.Expiration)
return err == nil && wrk >= 2020 && wrk <= 2030
}
func (p *Passport) ValidHeight() bool {
if strings.Contains(p.Height, "in") {
wrk, err := strconv.Atoi(strings.TrimSuffix(p.Height, "in"))
return err == nil && wrk >= 59 && wrk <= 76
} else if strings.Contains(p.Height, "cm") {
wrk, err := strconv.Atoi(strings.TrimSuffix(p.Height, "cm"))
return err == nil && wrk >= 150 && wrk <= 193
}
return false
}
func (p *Passport) ValidHairColor() bool {
if !strings.HasPrefix(p.HairColor, "#") {
return false
}
_, err := hex.DecodeString(p.HairColor[1:])
return err == nil
}
func (p *Passport) ValidEyeColor() bool {
return p.EyeColor == "amb" || p.EyeColor == "blu" || p.EyeColor == "brn" || p.EyeColor == "gry" || p.EyeColor == "grn" || p.EyeColor == "hzl" || p.EyeColor == "oth"
}
func (p *Passport) ValidPassportID() bool {
_, err := strconv.Atoi(p.PassportID)
return err == nil && len(p.PassportID) == 9
}
func (p *Passport) IsValid() bool {
return p.ValidBirthYear() && p.ValidIssueYear() && p.ValidExpiration() && p.ValidHeight() && p.ValidHairColor() && p.ValidEyeColor() && p.ValidPassportID()
}