Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "strconv"
- "strings"
- "time"
- )
- type config struct {
- Passports []passport
- }
- type passport struct {
- Byr string //`json:"byr"` // birth year
- Iyr string //`json:"iyr"` // issue year
- Eyr string //`json:"eyr"` // expiration year
- Hgt string //`json:"hgt"` // height
- Hcl string //`json:"hcl"` // hair color
- Ecl string //`json:"ecl"` // eye color
- Pid string //`json:"pid"` // passport id
- Cid string //`json:"cid"` // country id
- }
- func parse() config {
- f, err := os.Open("input.txt")
- if err != nil {
- log.Println(err)
- }
- defer func() {
- err = f.Close()
- if err != nil {
- log.Println(err)
- }
- }()
- fb, err := ioutil.ReadAll(f)
- if err != nil {
- log.Println(err)
- }
- var jb []byte
- for i := range fb {
- switch {
- case i == 0: // beginning
- header := []byte("{\"passports\":[{\"")
- for hb := range header {
- jb = append(jb, header[hb])
- }
- jb = append(jb, fb[i])
- case fb[i] == 58: // :
- colon := []byte("\":\"")
- for cb := range colon {
- jb = append(jb, colon[cb])
- }
- case fb[i] == 32: // space
- space := []byte("\",\"")
- for sb := range space {
- jb = append(jb, space[sb])
- }
- case fb[i] == 10: // newline
- if fb[i-1] != 10 {
- newline := []byte("\",\"") // treat like space
- for nb := range newline {
- jb = append(jb, newline[nb])
- }
- } else {
- // divider
- jb = jb[:len(jb)-2]
- divider := []byte("},{\"")
- for db := range divider {
- jb = append(jb, divider[db])
- }
- }
- default:
- jb = append(jb, fb[i])
- }
- }
- jb = jb[:len(jb)-2]
- footer := []byte("}]}")
- for ftb := range footer {
- jb = append(jb, footer[ftb])
- }
- var batch config
- err = json.Unmarshal(jb, &batch)
- if err != nil {
- log.Println(err.Error())
- }
- return batch
- }
- func byr(done chan bool, d string) {
- birth_year, err := strconv.Atoi(d)
- if err != nil {
- log.Println(err)
- }
- switch {
- case birth_year >= 1920 && birth_year <= 2002:
- done <- true
- return
- default:
- done <- false
- return
- }
- }
- func ecl(done chan bool, d string) {
- switch d {
- case "amb":
- done <- true
- return
- case "blu":
- done <- true
- return
- case "brn":
- done <- true
- return
- case "gry":
- done <- true
- return
- case "grn":
- done <- true
- return
- case "hzl":
- done <- true
- return
- case "oth":
- done <- true
- return
- default:
- done <- false
- return
- }
- }
- func pid(done chan bool, d string) {
- passport_id := []byte(d)
- switch len(passport_id) {
- case 9:
- done <- true
- return
- default:
- done <- false
- return
- }
- }
- func iyr(done chan bool, d string) {
- issue_year, err := strconv.Atoi(d)
- if err != nil {
- log.Println(err)
- }
- switch {
- case issue_year >= 2010 && issue_year <= 2020:
- done <- true
- return
- default:
- done <- false
- return
- }
- }
- func eyr(done chan bool, d string) {
- expiration_year, err := strconv.Atoi(d)
- if err != nil {
- log.Println(err)
- }
- switch {
- case expiration_year >= 2020 && expiration_year <= 2030:
- done <- true
- return
- default:
- done <- false
- return
- }
- }
- func hcl(done chan bool, d string) { // # + 6*char (0-9),(a-f) TODO: read about octal
- hair_color := []byte(d)
- switch len(hair_color) {
- case 7: // check
- switch hair_color[0] {
- case 35: // #, check
- for i := 1; i < len(hair_color); i++ {
- switch hair_color[i] {
- case 060: // 0
- break
- case 061: // 1
- break
- case 062: // 2
- break
- case 063: // 3
- break
- case 064: // 4
- break
- case 065: // 5
- break
- case 066: // 6
- break
- case 067: // 7
- break
- case 070: // 8
- break
- case 071: // 9
- break
- case 97: // a
- break
- case 98: // b
- break
- case 99: // c
- break
- case 100: // d
- break
- case 101: // e
- break
- case 102: // f
- break
- default:
- done <- false
- return
- }
- }
- done <- true
- return
- default:
- done <- false
- return
- }
- default:
- done <- false
- return
- }
- }
- func hgt(done chan bool, d string) {
- _, err := strconv.Atoi(d)
- if err != nil {
- switch {
- case strings.Contains(d, "cm"):
- height := strings.Split(d, "")
- height = height[:len(height)-2]
- height_value, err := strconv.Atoi(strings.Join(height, ""))
- if err != nil {
- done <- false
- return
- }
- switch {
- case height_value >= 150 && height_value <= 193:
- done <- true
- return
- default:
- done <- false
- return
- }
- case strings.Contains(d, "in"):
- height := strings.Split(d, "")
- height = height[:len(height)-2]
- height_value, err := strconv.Atoi(strings.Join(height, ""))
- if err != nil {
- done <- false
- return
- }
- switch {
- case height_value >= 59 && height_value <= 76:
- done <- true
- return
- default:
- done <- false
- return
- }
- default:
- done <- false
- return
- }
- }
- done <- false
- return
- }
- func is_valid(p passport) bool {
- done := make(chan bool, 7)
- go byr(done, p.Byr)
- go ecl(done, p.Ecl)
- go pid(done, p.Pid)
- go iyr(done, p.Iyr)
- go eyr(done, p.Eyr)
- go hcl(done, p.Hcl)
- go hgt(done, p.Hgt)
- i := 0
- for i != 7 { // TODO: research later... write small program
- switch <-done {
- case false:
- return false
- case true:
- i++
- }
- }
- return true
- }
- func main() {
- t := time.Now()
- batch := parse()
- var valid int
- var not_valid int
- for i := range batch.Passports {
- switch {
- case batch.Passports[i].Byr == "":
- break
- case batch.Passports[i].Ecl == "":
- break
- case batch.Passports[i].Pid == "":
- break
- case batch.Passports[i].Iyr == "":
- break
- case batch.Passports[i].Eyr == "":
- break
- case batch.Passports[i].Hcl == "":
- break
- case batch.Passports[i].Hgt == "":
- break
- default:
- if is_valid(batch.Passports[i]) {
- valid++
- } else {
- not_valid++
- }
- }
- }
- d := time.Since(t)
- fmt.Printf("valid: %v not valid: %v total: %v/%v time: %v", valid, not_valid, valid+not_valid, len(batch.Passports), d.Nanoseconds())
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement