use std::env; use std::io::BufReader; use std::io::BufRead; use std::fs::File; use std::process; use std::collections::HashMap; type State = Vec<(i64, char)>; type RuleKey = (char, char, char, char, char); type Rules = HashMap; static ITERATIONS: usize = 20; fn parse_initial_state(line: &String) -> State { let initial: Vec = line[15..].chars().collect(); let mut slice: State = Vec::new(); for i in -(ITERATIONS as i64) - 2..0 { slice.push((i, '.')); } for (i, ch) in initial.iter().enumerate() { slice.push((i as i64, *ch)); } for i in initial.len()..initial.len() + ITERATIONS + 2 { slice.push((i as i64, '.')); } for (i, _) in &slice { print!("{} ", i); } print!("\n"); slice } fn parse_rule(rules: &mut Rules, line: &String) { let chs: Vec = line.chars().collect(); let res: char = chs[chs.len() - 1]; let p = chs[0..6].to_vec(); let rule_key = (p[0], p[1], p[2], p[3], p[4]); rules.insert(rule_key, res); } fn main() { let args: Vec = env::args().collect(); if args.len() != 2 { println!("Wrong number of arguments. Provide a file name and worker count."); process::exit(1); } let filename = &args[1]; println!("Using file {} as input.", filename); let f = match File::open(filename) { Ok(file) => file, Err(e) => { println!("Failed to open file {}. {:?}", filename, e); process::exit(1); } }; let file = BufReader::new(&f); let lines: Vec = file.lines() .map(|line| line.expect("Could not parse line.")) .collect(); let mut initial_state: State = Vec::new(); let mut rules: Rules = HashMap::new(); for (i, line) in lines.iter().enumerate() { match i { 0 => { initial_state = parse_initial_state(&line); } 1 => { } _ => { parse_rule(&mut rules, &line); } } } assert_ne!(initial_state.len(), 0); let state_len = initial_state.len(); let mut states: Vec = vec![initial_state]; for iteration in 0..ITERATIONS { let mut new_state: State = vec![(-999, '.'); state_len]; { let prev_state = &states[states.len() - 1]; for (i, _) in prev_state.iter().enumerate() { if i < 2 || i >= state_len - 2 { continue; } let rule_key = (prev_state[i-2].1, prev_state[i-1].1, prev_state[i].1, prev_state[i+1].1, prev_state[i+2].1); let value = rules[&rule_key]; new_state[i] = (prev_state[i].0, value); } } if iteration % 1000 == 0 { println!("Iteration: {}", iteration); } states.push(new_state); } for (i, state) in states.iter().enumerate() { print!("{}: ", i); for tupl in state { let ch = tupl.1; print!("{}", ch); } print!("\n"); } let mut total = 0; let last_i = states.len() - 1; let last_state = &states[last_i]; for (_, &tupl) in last_state.iter().enumerate() { let (i, ch) = tupl; if ch == '#' { total += i; } } println!("Result: {}", total); }