summary refs log tree commit diff
path: root/04/src/main.rs
blob: 701f60d70bd65c9b7c86688d1f5e39cc1552f669 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use advent_lib::prelude::*;

use regex::Regex;
use std::collections::BTreeSet;


fn main() -> Result<()> {
  let mut args = std::env::args();
  if args.len() != 2 {
    eprintln!("Usage: advent input");
  }
  let _ = args.next();
  let filename = args.next().unwrap();

  let input = advent_lib::read_lines_file(&filename)?;

  let overall_regex = Regex::new(r"([a-z][a-z][a-z]):([^ \n]*)").unwrap();
  let year_regex = Regex::new(r"^[0-9][0-9][0-9][0-9]$").unwrap();
  let height_regex = Regex::new(r"^([0-9]+)(cm|in)$").unwrap();
  let rgb_regex = Regex::new(r"^#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$").unwrap();
  let eye_regex = Regex::new(r"^(amb|blu|brn|gry|grn|hzl|oth)$").unwrap();
  let id_regex = Regex::new(r"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$").unwrap();

  let mut n_valid: i64 = 0;
  let mut current_fields: BTreeSet<String> = BTreeSet::new();
  let mut current_is_valid = true;

  for line in &input {
    if line.trim().len() == 0 {
      //println!("{:?}", current_fields);

      if current_is_valid
        && current_fields.contains("byr")
        && current_fields.contains("iyr")
        && current_fields.contains("eyr")
        && current_fields.contains("hgt")
        && current_fields.contains("hcl")
        && current_fields.contains("ecl")
        && current_fields.contains("pid") {
        n_valid += 1;
      }

      current_fields = BTreeSet::new();
      current_is_valid = true;
    }

    for captures in overall_regex.captures_iter(line) {
      let mut field_name = String::new();
      field_name.push_str(&captures[1]);

      let mut field_value = String::new();
      field_value.push_str(&captures[2]);

      current_fields.insert(field_name);

      match &captures[1] {
        "byr" => {
          if year_regex.is_match(&field_value) {
            let year = field_value.parse::<i64>()?;
            if year < 1920 || year > 2002 {
              current_is_valid = false;
            }
          } else {
            current_is_valid = false;
          }
        },
        "iyr" => {
          if year_regex.is_match(&field_value) {
            let year = field_value.parse::<i64>()?;
            if year < 2010 || year > 2020 {
              current_is_valid = false;
            }
          } else {
            current_is_valid = false;
          }
        },
        "eyr" => {
          if year_regex.is_match(&field_value) {
            let year = field_value.parse::<i64>()?;
            if year < 2020 || year > 2030 {
              current_is_valid = false;
            }
          } else {
            current_is_valid = false;
          }
        },
        "hgt" => {
          if height_regex.is_match(&field_value) {
            let captures = height_regex.captures(&field_value).unwrap();
            let number = captures[1].parse::<i64>()?;

            match &captures[2] {
              "cm" => {
                if number < 150 || number > 193 {
                  current_is_valid = false;
                }
              },
              "in" => {
                if number < 59 || number > 76 {
                  current_is_valid = false;
                }
              },
              _ => { },
            }
          } else {
            current_is_valid = false;
          }
        },
        "hcl" => {
          if !rgb_regex.is_match(&field_value) {
            current_is_valid = false;
          }
        },
        "ecl" => {
          if !eye_regex.is_match(&field_value) {
            current_is_valid = false;
          }
        },
        "pid" => {
          if !id_regex.is_match(&field_value) {
            current_is_valid = false;
          }
        },
        _ => {
        },
      };
    }
    //println!("end of line");
  }

  println!("{}", n_valid);

  Ok(())
}