summaryrefslogtreecommitdiffstats
path: root/2015/rs/code/eight/src/main.rs
blob: 1d582d747d810b8d71ade6a06c7c58b3a80d51b9 (plain) (blame)
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
static INPUT: &str = include_str!("input.txt");

#[derive(Copy, Clone)]
enum ParseState {
  Verbatim,
  Esc,
  Hex1,
  Hex2
}

fn main() {
  let valueified = INPUT.split('\n')
    .filter(|s| !s.is_empty());

  let (oglen, parsedlen) = valueified.clone()
    .map(|s| {
      let rs = s.strip_prefix('"').and_then(|s| s.strip_suffix('"')).unwrap();
      let mut buf = String::with_capacity(s.len());
      let mut state = ParseState::Verbatim;
      for c in rs.chars() {
        match (state, c) {
          (ParseState::Verbatim, '\\') => { state = ParseState::Esc; },
          (ParseState::Verbatim, c) => { buf.push(c); },

          (ParseState::Esc, 'x') => { state = ParseState::Hex1; },
          (ParseState::Esc, c) => { buf.push(c); state = ParseState::Verbatim; },

          (ParseState::Hex1, _) => { state = ParseState::Hex2; },
          (ParseState::Hex2, _) => { buf.push('?'); state = ParseState::Verbatim; },
        }
      }
      (s, buf)
    })
    .fold((0, 0), |(a1, b1), (a2, b2)| (a1 + a2.len(), b1 + b2.len()));
  let lendiff = oglen - parsedlen;
  println!("Literal Length - Parsed Length: {lendiff}");

  let (oglen, enclen) = valueified
    .map(|s| {
      let mut buf = String::with_capacity(s.len() * 2);
      buf.push('"');
      for c in s.chars() {
        match c {
          '\\' => { buf += "\\\\" },
          '"' => { buf += "\\\"" },
          c => { buf.push(c) },
        }
      }
      buf.push('"');
      (s, buf)
    })
    .fold((0, 0), |(a1, b1), (a2, b2)| (a1 + a2.len(), b1 + b2.len()));
  let lendiff = enclen - oglen;
  println!("Encoded Length - Literal Length: {lendiff}");
}