-
Notifications
You must be signed in to change notification settings - Fork 1
/
day3.rs
71 lines (55 loc) · 1.87 KB
/
day3.rs
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
#![allow(clippy::must_use_candidate, clippy::missing_panics_doc)]
use std::fs::read_to_string;
const DIGITS: usize = 12;
pub fn calculate_power_consumption(input: &str) -> usize {
let mut counts: Vec<i64> = vec![0; DIGITS];
for line in input.lines() {
for (i, c) in line.chars().enumerate() {
match c {
'0' => counts[i] -= 1,
'1' => counts[i] += 1,
_ => unreachable!(),
}
}
}
let gamma_bits = counts
.iter()
.map(|&count| if count > 0 { '1' } else { '0' })
.collect::<String>();
let epsilon_bits = counts
.iter()
.map(|&count| if count > 0 { '0' } else { '1' })
.collect::<String>();
let gamma_rate = usize::from_str_radix(&gamma_bits, 2).unwrap();
let epsilon_rate = usize::from_str_radix(&epsilon_bits, 2).unwrap();
gamma_rate * epsilon_rate
}
fn get_prefix(input: &str, f: fn(usize, usize) -> bool) -> usize {
let mut prefix = String::new();
for digit in 0..DIGITS {
let filtered: Vec<_> = input.lines().filter(|line| line.starts_with(&prefix)).collect();
if filtered.len() == 1 {
break;
}
let count1 = filtered
.iter()
.map(|&line| line.chars().nth(digit).unwrap())
.filter(|&c| c == '1')
.count();
prefix.push(if f(count1, filtered.len() - count1) { '1' } else { '0' });
}
let filtered: Vec<_> = input.lines().filter(|line| line.starts_with(&prefix)).collect();
usize::from_str_radix(filtered[0], 2).unwrap()
}
pub fn calculate_oxygen_co2(input: &str) -> usize {
let oxygen = get_prefix(input, |count1, count0| count1 >= count0);
let co2 = get_prefix(input, |count1, count0| count1 < count0);
oxygen * co2
}
pub fn main() {
let input = read_to_string("input/day3/input.txt").expect("Input file not found");
let now = std::time::Instant::now();
println!("PART 1 = {}", calculate_power_consumption(&input));
println!("PART 2 = {}", calculate_oxygen_co2(&input));
println!("Execution time: {:?}", now.elapsed());
}