use std::io::{self, BufRead}; use std::str; #[derive(Debug)] enum StateMachine { Normal, Escape, Hexadecimal(u8) } fn memory_length(input: &str) -> usize { let mut count: usize = 0; let mut state = StateMachine::Normal; for c in input.chars() { state = match (c, state) { // Normal. ('\\', StateMachine::Normal) => { StateMachine::Escape } (_, s @ StateMachine::Normal) => { count += 1; s } // Escape. ('x', StateMachine::Escape) => { StateMachine::Hexadecimal(1) } (_, StateMachine::Escape) => { count += 1; StateMachine::Normal } // Hexadecimal. (_, StateMachine::Hexadecimal(mut hex)) => { if hex == 2 { count += 1; StateMachine::Normal } else { hex += 1; StateMachine::Hexadecimal(hex) } } }; // println!("{} - {} => {:?}", count, c, state); } count - 2 } fn code_length(input: &str) -> usize { input.len() } fn main() { let stdin = io::stdin(); let lines = stdin.lock().lines() .filter_map(|line| line.ok()) .collect::>(); let count_1: usize = lines.iter() .map(|line| code_length(&line)) .sum(); let count_2: usize = lines.iter() .map(|line| memory_length(&line)) .sum(); println!("count_1={}", count_1); println!("count_2={}", count_1 - count_2); } #[cfg(test)] mod tests { use super::{code_length, memory_length}; #[test] fn example_01() { let line = r#""""#; assert_eq!(2, code_length(line)); assert_eq!(0, memory_length(line)); } #[test] fn example_02() { let line = r#""abc""#; assert_eq!(5, code_length(line)); assert_eq!(3, memory_length(line)); } #[test] fn example_03() { let line = r#""aaa\"aaa""#; assert_eq!(10, code_length(line)); assert_eq!(7, memory_length(line)); } #[test] fn example_04() { let line = r#""\x27""#; assert_eq!(6, code_length(line)); assert_eq!(1, memory_length(line)); } }