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 }