diff options
Diffstat (limited to 'day4/src/main.rs')
| -rw-r--r-- | day4/src/main.rs | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/day4/src/main.rs b/day4/src/main.rs new file mode 100644 index 0000000..7f50790 --- /dev/null +++ b/day4/src/main.rs @@ -0,0 +1,135 @@ +use std::env; +use std::io::BufReader; +use std::io::BufRead; +use std::fs::File; +use std::process; +use std::collections::{HashSet, HashMap}; + +#[macro_use] extern crate text_io; + +struct Guard { + id: u32, + minutes: Vec<u32>, + total: Option<u32>, + max_min: Option<usize> +} + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() != 2 { + println!("Wrong number of arguments. Provide just a file name."); + 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 mut lines: Vec<String> = file.lines() + .map(|line| line.expect("Could not parse line.")) + .collect(); + &lines.sort(); + + // exercise 1 + let mut guards: HashMap<u32, Guard> = HashMap::new(); + let mut id: Option<u32> = None; + let mut start_min: Option<u32> = None; + for line in &lines { + let (year, month, day, hour, minute, command): (u32, u32, u32, u32, u32, String); + scan!(line.bytes() => "[{}-{}-{} {}:{}]", year, month, day, hour, minute); + command = (&line[19..]).to_string(); + match command.as_ref() { + "falls asleep" => { + println!("Debug: line: '{}', cmd: '{}', start_min: {}", &line, &command, minute); + start_min = Some(minute); + } + "wakes up" => { + println!("Debug: line: '{}', cmd: '{}', end_min: {}", &line, &command, minute); + let gid = id.expect("Id not set."); + if !guards.contains_key(&gid) { + let minutes = vec![0; 60]; + let g = Guard { id: gid, minutes, total: None, max_min: None }; + guards.insert(gid, g); + } + let mut guard_opt = guards.get_mut(&gid); + let mut guard = guard_opt.expect("Guard not set."); + let min = start_min.expect("start_min not set."); + for i in 0..60 { + if min <= i && i <= minute { + guard.minutes[i as usize] += 1; + } + } + } + _ => { + let new_id: u32; + scan!(command.bytes() => "Guard #{} begins shift", new_id); + println!("Debug: line: '{}', cmd: '{}', id: {}", &line, &command, new_id); + id = Some(new_id); + start_min = None; + } + } + } + + let ids: Vec<u32> = guards.keys().map(|v| *v).collect(); + let mut guard_id: u32 = 0; + let mut best_total = 0; + for id in &ids { + let mut guard_opt = (&mut guards).get_mut(&id); + let mut guard = guard_opt.expect("Guard not set."); + println!("Debug: Guard {}", guard.id); + let total = guard.minutes.iter().fold(0, |acc, x| acc + x); + guard.total = Some(total); + + let mut best_index: usize = 0; + for i in 1..60 { + if guard.minutes[i as usize] > guard.minutes[best_index] { + best_index = i; + println!("Debug: Best index for guard {} is now {}", &id, &i); + } + } + guard.max_min = Some(best_index); + + if total > best_total { + best_total = total; + guard_id = *id; + } + } + + let guard = guards.get(&guard_id).expect("Guard not set."); + let mut index = 0; + let mut best_minute = 0; + for i in 0..60 { + let val = guard.minutes[i as usize]; + if val > best_minute { + index = i; + best_minute = val; + } + } + + let mut guard_id_2: usize = 0; + let mut guard_max_min: usize = 0; + let mut guard_max_val: u32 = 0; + for id in &ids { + let guard = &guards.get(id).expect("guard not set"); + let max_min = guard.max_min.expect("max_min not set."); + let val = guard.minutes[max_min]; + if val > guard_max_val { + guard_id_2 = *id as usize; + guard_max_min = max_min; + guard_max_val = val; + println!("Best guard max_min combo is now guard {} and minute {}, value: {}", &id, &max_min, &val); + } + } + + println!("1. Guard id: {}", guard_id); + println!("1. Minute index: {}", index); + println!("1. Result: {}", index * guard_id); + println!("2. Guard id: {}", guard_id_2); + println!("2. Minute index: {}", guard_max_min); + println!("2. Result: {}", guard_max_min * guard_id_2); +}
\ No newline at end of file |
