main.rs (2276B)
1 fn main() {
2 let mut width = 0;
3 let input = std::fs::read_to_string("input.txt")
4 .unwrap()
5 .trim()
6 .split('\n')
7 .map(|x| {
8 width = x.len();
9 i32::from_str_radix(x, 2).unwrap()
10 })
11 .collect::<Vec<_>>();
12 // 2003336
13 println!("Part 1 : {}", part_1(&input, width));
14 // 1877139
15 println!("Part 2 : {}", part_2(&input, width));
16 }
17
18 fn part_1(input: &Vec<i32>, width: usize) -> i32 {
19 let mut gamma = 0;
20 let mut epsilon = 0;
21
22 for i in (0..width).rev() {
23 let mask = 1 << i;
24 let one_count = input.iter().fold(0, |acc, x| acc + (x & mask != 0) as i32);
25 let zero_count = input.len() as i32 - one_count;
26 // ties go to 1
27 if one_count >= zero_count {
28 gamma |= mask;
29 } else {
30 epsilon |= mask;
31 }
32 }
33
34 gamma * epsilon
35 }
36
37 fn part_2(input: &Vec<i32>, width: usize) -> i32 {
38 let mut gamma = 0;
39 let mut epsilon = 0;
40
41 let mut o2_candidate = input.clone();
42 let mut co2_candidate = input.clone();
43
44 for i in (0..width).rev() {
45 let mask = 1 << i;
46
47 if o2_candidate.len() > 1 {
48 let gamma_one_count = o2_candidate
49 .iter()
50 .fold(0, |acc, x| acc + (x & mask != 0) as i32);
51 let gamma_zero_count = o2_candidate.len() as i32 - gamma_one_count;
52 // ties go to 1
53 if gamma_one_count >= gamma_zero_count {
54 gamma |= mask;
55 }
56 o2_candidate = o2_candidate
57 .into_iter()
58 .filter(|&x| x >> i == gamma >> i)
59 .collect();
60 }
61
62 if co2_candidate.len() > 1 {
63 let epsilon_one_count = co2_candidate
64 .iter()
65 .fold(0, |acc, x| acc + (x & mask != 0) as i32);
66 let epsilon_zero_count = co2_candidate.len() as i32 - epsilon_one_count;
67 // ties go to 0
68 if epsilon_one_count < epsilon_zero_count {
69 epsilon |= mask;
70 }
71 co2_candidate = co2_candidate
72 .into_iter()
73 .filter(|&x| x >> i == epsilon >> i)
74 .collect();
75 }
76 }
77
78 o2_candidate[0] * co2_candidate[0]
79 }