DEV Community

Discussion on: Advent of Code 2020 Solution Megathread - Day 3: Toboggan Trajectory

Collapse
 
benwtrent profile image
Benjamin Trent • Edited

Rust again

enum Entry {
    Tree,
    Snow
}

impl From<&str> for Entry {
    fn from(s: &str) -> Self {
        match s { 
            "." => Entry::Snow,
            "#" => Entry::Tree,
            _ => panic!(format!("unexpected string {}", s))
        }
    }
}

#[aoc_generator(day3)]
fn input_to_vec(input: &str) -> Vec<Vec<Entry>> {
    input.lines().map(|i| {
        let splt = i.split("").filter(|s| !s.is_empty()).map(|s| Entry::from(s)).collect();
        splt
    }).collect()
}

fn tree_count_for_steps(input: &Vec<Vec<Entry>>, x: usize, y: usize) -> usize {
    let mut ct = 0;
    let mut right = 0;
    for r in 1..input.len() {
        if r % y > 0 {
            continue;
        }
        let row = &input[r];
        right += x;
        right %= row.len();
        if let Entry::Tree = row[right] {
            ct += 1;
        }
    }
    ct
}

#[aoc(day3, part1)]
fn tree_count(input: &Vec<Vec<Entry>>) -> usize {
    tree_count_for_steps(input, 3, 1)
}

#[aoc(day3, part2)]
fn tree_count_for_all_paths(input: &Vec<Vec<Entry>>) -> usize {
    let mut ct = 1;
    for (x, y) in vec![(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)].into_iter() {
        ct *= tree_count_for_steps(input, x, y);
    }
    ct
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ballpointcarrot profile image
Christopher Kruse • Edited

Rustaceans gonna stick together 🦀:

use aoc_runner_derive::{aoc, aoc_generator};

#[aoc_generator(day3)]
fn parse_input_day3(input: &str) -> Vec<Vec<u8>> {
    input
        .lines()
        .map(|l| {
            l.chars()
                .map(|ch| match ch {
                    '.' => 0,
                    '#' => 1,
                    _ => panic!("Unexpected character!"),
                })
                .collect()
        })
        .collect()
}

#[aoc(day3, part1)]
fn toboggan_at_fixed_slope(input: &Vec<Vec<u8>>) -> usize {
    toboggan_at_slope(input, (3, 1))
}

fn toboggan_at_slope(input: &Vec<Vec<u8>>, slope: (usize, usize)) -> usize {
    let (slope_x, slope_y) = slope;
    let mut xpos = 0;
    let mut tree_count = 0;
    for row in input.iter().step_by(slope_y) {
        if *row.get(xpos % (row.len())).unwrap() == 1 {
            tree_count += 1;
        }
        xpos += slope_x;
    }
    tree_count
}

#[aoc(day3, part2)]
fn toboggan_at_other_slopes(input: &Vec<Vec<u8>>) -> usize {
    let slopes = vec![(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)];
    slopes
        .iter()
        .map(|s| toboggan_at_slope(input, *s))
        .fold(1, |memo, x| memo * x)
}
Enter fullscreen mode Exit fullscreen mode

As always, also available on Github.


The enum implementation for your input is cool; I wouldn't have thought of that.