package main
import (
"bufio"
"log"
"os"
"regexp"
"strings"
)
type passData map[string]string
var re = regexp.MustCompile(`(.*?):(.*?) `)
var fields = []struct {
name string
validator func(string) bool
}{
{"byr", byrValid},
{"iyr", iyrValid},
{"eyr", eyrValid},
{"hgt", hgtValid},
{"hcl", hclValid},
{"ecl", eclValid},
{"pid", pidValid},
}
func main() {
if err := realMain(); err != nil {
log.Println(err)
}
}
func realMain() error {
data, err := readInput()
if err != nil {
return err
}
var valid int
for _, d := range data {
var notvalid bool
for _, f := range fields {
value, ok := d[f.name]
if !ok {
notvalid = true
break
}
if !f.validator(value) {
notvalid = true
break
}
}
if !notvalid {
valid++
}
}
log.Println(valid)
return nil
}
func readInput() ([]passData, error) {
fd, err := os.Open("input.txt")
if err != nil {
return nil, err
}
defer fd.Close()
var ret []passData
buf := bufio.NewScanner(fd)
item := strings.Builder{}
for buf.Scan() {
if buf.Text() != "" {
item.WriteString(buf.Text())
item.WriteByte(' ')
} else {
ret = append(ret, parseData(item.String()))
item.Reset()
}
}
ret = append(ret, parseData(item.String()))
return ret, nil
}
func parseData(in string) passData {
ret := passData{}
res := re.FindAllString(in, -1)
for _, pair := range res {
pair = strings.TrimSpace(pair)
p := strings.SplitAfter(pair, ":")
ret[strings.TrimRight(p[0], ":")] = p[1]
}
return ret
}