DEV Community

Discussion on: Advent of Code 2020 Solution Megathread - Day 9: Encoding Error

Collapse
 
ballpointcarrot profile image
Christopher Kruse

+1 Rust solution.

I started out with isize because I just knew that the second half would add negative numbers somehow. Then it didn't. :/

I got part 1 done rather quickly comparatively. I then spent far to long arguing with the rust compiler over lifetimes of slices and the ability to sum on borrowed vs. non-borrowed values.

Ultimately I moved into using a more C-style for-loop driven solution, where we walk down the entry vector until we're too big, and then step down to the next item.

Didn't get the elegant interator-driven solution, but meh - a win's a win. :)

As always, on Github.

use aoc_runner_derive::{aoc, aoc_generator};
use std::cmp::Ordering;

#[aoc_generator(day9)]
fn parse_input_day9(input: &str) -> Vec<isize> {
    input
        .lines()
        .map(|line| str::parse(line).unwrap())
        .collect()
}

fn process_xmas(input: &Vec<isize>, preamble_count: usize) -> &isize {
    let mut buffer: Vec<isize> = input.iter().copied().take(preamble_count).collect();
    input
        .iter()
        .skip(preamble_count)
        .find(|num| {
            match buffer.iter().find(|buf_num| {
                buffer
                    .iter()
                    .any(|buf_addend| *buf_addend + *buf_num == **num)
            }) {
                Some(_n) => {
                    buffer.push(**num);
                    buffer.remove(0);
                    false
                }
                None => true,
            }
        })
        .unwrap()
}

#[aoc(day9, part1)]
fn find_target_value(input: &Vec<isize>) -> isize {
    let preamble_count = 25;
    *process_xmas(input, preamble_count)
}

#[aoc(day9, part2)]
fn hit_weak_point_for_massive_damage(input: &Vec<isize>) -> isize {
    let preamble_count = 25;
    let target_value = *process_xmas(input, preamble_count);
    let mut span: &[isize];
    for (idx, _) in input.iter().enumerate() {
        let mut slider = idx.clone();
        let mut over = false;
        while !over {
            span = &input[idx..slider];
            match target_value.cmp(&span.iter().sum::<isize>()) {
                Ordering::Greater => {
                    slider += 1;
                }
                Ordering::Equal => {
                    return *span.iter().min().unwrap() + *span.iter().max().unwrap();
                }
                Ordering::Less => {
                    over = true;
                }
            }
        }
    }
    -1
}

Enter fullscreen mode Exit fullscreen mode