summaryrefslogtreecommitdiffstats
path: root/2015/rs/src/eight.rs
blob: ce9a8a7789903015a7347644ff74d6b23704a234 (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: &'static str = include_str!("eight.txt");

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

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, c) => { state = ParseState::Hex2(c.to_digit(16).unwrap() * 16); },
          (ParseState::Hex2(n), c) => { buf.push(/*char::from_u32(n + c.to_digit(16).unwrap()).unwrap()*/'?'); 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}");
}