use std::env::args; use std::fs::File; use std::io::Read; struct CharIterator { reader: File, buffer: [u8; 256], size: usize, pos: usize, } impl CharIterator { fn new(reader: File) -> CharIterator { CharIterator { reader: reader, buffer: [0; 256], size: 0, pos: 0, } } } impl Iterator for CharIterator { type Item = char; fn next(&mut self) -> Option { if self.pos == self.size { self.size = self.reader.read(&mut self.buffer).ok()?; self.pos = 0; } if self.size == 0 { return None; } let byte = self.buffer[self.pos]; self.pos += 1; return Some(char::from(byte)); } } fn main() { let path = args().nth(1).unwrap(); let file = File::open(path).unwrap(); let mut v1 = 0; let mut v2 = 0; let mut state = 0; let mut enabled = true; let mut sum1 = 0; let mut sum2 = 0; for c in CharIterator::new(file) { state = match (state, c) { (0, 'm') => 1, (1, 'u') => 2, (2, 'l') => 3, (3, '(') => 4, (4, c) if c.is_ascii_digit() => { v1 = v1 * 10 + c.to_digit(10).unwrap(); 4 }, (4, ',') => 5, (5, c) if c.is_ascii_digit() => { v2 = v2 * 10 + c.to_digit(10).unwrap(); 5 }, (5, ')') => { sum1 += v1 * v2; if enabled { sum2 += v1 * v2; } v1 = 0; v2 = 0; 0 }, (0, 'd') => 6, (6, 'o') => 7, (7, '(') => 8, (8, ')') => { enabled = true; 0 }, (7, 'n') => 9, (9, '\'') => 10, (10, 't') => 11, (11, '(') => 12, (12, ')') => { enabled = false; 0 }, _ => { v1 = 0; v2 = 0; 0 }, }; } println!("part1: {}", sum1); println!("part2: {}", sum2); }