advent-of-code/solutions/4/go/main.go

104 lines
2.2 KiB
Go
Raw Normal View History

2020-12-05 09:48:31 +00:00
package main
import (
"fmt"
"io/ioutil"
"regexp"
"strconv"
"strings"
k "github.com/wesovilabs/koazee"
)
type tPassport = map[string]string
func stringBetween(s string, min, max int) bool {
num, _ := strconv.Atoi(s)
return min <= num && num <= max
}
func verifyPassport(passport tPassport) (bool, bool) {
requiredKeys := k.StreamOf([]string{"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"})
eyeColors := k.StreamOf([]string{"amb", "blu", "brn", "gry", "grn", "hzl", "oth"})
// Simple
counted := 0
for k := range passport {
if k == "cid" {
continue
}
included, _ := requiredKeys.Contains(k)
if !included {
return false, false
}
counted++
}
if counted < 7 {
return false, false
}
// Complex
if !stringBetween(passport["byr"], 1920, 2002) || !stringBetween(passport["iyr"], 2010, 2020) || !stringBetween(passport["eyr"], 2020, 2030) {
return true, false
}
tmp := []rune(passport["hgt"])
hgtLen := len(tmp)
hgt, _ := strconv.Atoi(string(tmp[0 : hgtLen-2]))
unit := string(tmp[hgtLen-2:])
if unit != "cm" && unit != "in" {
return true, false
}
if unit == "cm" && (hgt < 150 || hgt > 193) {
return true, false
}
if unit == "in" && (hgt < 59 || hgt > 76) {
return true, false
}
if !regexp.MustCompile(`^#[\dabdcdef]{6}$`).MatchString(passport["hcl"]) {
return true, false
}
if !regexp.MustCompile(`^\d{9}$`).MatchString(passport["pid"]) {
return true, false
}
ecl, _ := eyeColors.Contains(passport["ecl"])
if !ecl {
return true, false
}
return true, true
}
func main() {
data, _ := ioutil.ReadFile("./solutions/4/data.txt")
passportsRaw := strings.Split(strings.TrimSpace(string(data)), "\n\n")
passports := []tPassport{}
re := regexp.MustCompile(`\n|\s`)
for _, passportRaw := range passportsRaw {
passport := tPassport{}
entries := re.Split(passportRaw, -1)
for _, entry := range entries {
split := strings.Split(entry, ":")
passport[split[0]] = split[1]
}
passports = append(passports, passport)
}
validSimple := 0
validComplex := 0
for _, passport := range passports {
simple, complex := verifyPassport(passport)
if simple {
validSimple++
}
if complex {
validComplex++
}
}
fmt.Println("Simple Validation:\t", validSimple)
fmt.Println("Extended Validation:\t", validComplex)
}