#![warn(clippy::pedantic)] use std::io::{stdin, BufRead}; fn find_rating(num_bits: usize, mut range: &[usize], keep_most_common_bit: bool) -> usize { for idx in (0..num_bits).rev() { if range.len() == 1 { break; } let nth_bit = |x| x >> idx & 1; let partition_point = range.iter().position(|&n| nth_bit(n) == 1).unwrap(); let center_bit = nth_bit(range[range.len() / 2]); let keep_first_half = if keep_most_common_bit { center_bit == 0 } else { center_bit == 1 }; if keep_first_half { range = &range[..partition_point]; } else { range = &range[partition_point..]; } } range[0] } fn main() { let lines: Vec<_> = stdin().lock().lines().map(Result::unwrap).collect(); let num_bits = lines[0].len(); let gamma: usize = (0..num_bits) .map(|i| { lines .iter() .filter(|line| line.chars().nth(i).unwrap() == '1') .count() }) .map(|n| if n > lines.len() / 2 { 1 } else { 0 }) .reduce(|accum, bit| accum << 1 | bit) .unwrap(); let sigma = !gamma & ((1 << num_bits) - 1); println!("{}", gamma * sigma); let mut numbers: Vec<_> = lines .iter() .map(|n| usize::from_str_radix(n, 2).unwrap()) .collect(); numbers.sort_unstable(); let oxygen = find_rating(num_bits, &numbers, true); let co2 = find_rating(num_bits, &numbers, false); println!("{}", oxygen * co2); }