aoc-2021-rust

Advent of Code 2021 Solutions in Rust
git clone https://git.sinitax.com/sinitax/aoc-2021-rust
Log | Files | Refs | README | sfeed.txt

main.rs (2149B)


      1fn filter_lines<T>(lines: &Vec<&str>, char_sel : T) -> u32 where T: Fn(u32, u32) -> char {
      2    let mut cands : Vec<&str> = lines.clone();
      3    let bits = cands[0].len();
      4    for bit in 0..bits {
      5        let valcount : u32 = cands.len().try_into().unwrap();
      6
      7        let mut count : u32 = 0;
      8        for line in &cands {
      9            if line.chars().nth(bit).unwrap() == '1' {
     10                count += 1;
     11            }
     12        }
     13
     14        let c = char_sel(count, valcount);
     15        cands.retain(|x| x.chars().nth(bit).unwrap() == c);
     16
     17        if cands.len() == 1 {
     18            break;
     19        }
     20    }
     21
     22    assert_ne!(cands.len(), 0);
     23    return u32::from_str_radix(cands[0], 2).unwrap();
     24}
     25
     26fn part1(aoc: &mut aoc::Info) {
     27    let lines : Vec<&str> = aoc.input.lines().collect();
     28    assert_ne!(lines.len(), 0);
     29
     30    let valcount : usize = lines.len();
     31    let bits : usize = lines[0].len();
     32    let mut bitcounts : Vec<usize> = vec![0; bits];
     33    bitcounts.fill(0);
     34
     35    for line in lines {
     36        for i in 0..bits {
     37            if line.chars().nth(i).unwrap() == '1' {
     38                bitcounts[i] += 1;
     39            }
     40        }
     41    }
     42
     43    let mut gamma : u32 = 0;
     44    let mut epsilon : u32 = 0;
     45    for i in 0..bits {
     46        if bitcounts[i] > valcount / 2 {
     47            gamma = (gamma << 1) | 1;
     48            epsilon = (epsilon << 1) | 0;
     49        } else {
     50            gamma = (gamma << 1) | 0;
     51            epsilon = (epsilon << 1) | 1;
     52        }
     53    }
     54
     55    aoc.answer = Some(format!("{}", gamma * epsilon));
     56    aoc.solution = Some("3958484");
     57}
     58
     59fn part2(aoc: &mut aoc::Info) {
     60    let lines : Vec<&str> = aoc.input.lines().collect();
     61    assert_ne!(lines.len(), 0);
     62
     63    let oxyfn = |count,valcount|
     64        if (count as f32) >= ((valcount as f32) / 2.0).ceil()
     65            { '1' } else { '0' };
     66    let oxygen = filter_lines(&lines, oxyfn);
     67
     68    let co2fn = |count,valcount|
     69        if (count as f32) < ((valcount as f32) / 2.0).floor()
     70            { '1' } else { '0' };
     71    let co2 = filter_lines(&lines, co2fn);
     72
     73    aoc.answer = Some(format!("{}", oxygen * co2));
     74    aoc.solution = Some("1613181");
     75}
     76
     77fn main() {
     78    aoc::run(part1, part2);
     79}