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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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);
}
|