🎄

Advent of Code 2020 day03

2 min read

https://adventofcode.com/2020/day/3

part1

..##.......
#...#...#..
.#....#..#.
..#.#...#.#
.#...##..#.
..#.##.....
.#.#.#....#
.#........#
#.##...#...
#...##....#
.#..#...#.#

のように .# で表されるmap(ただし横方向に無限に同じパターンが続いている)で、左上を起点に一定方向に降りていくと何回 # にぶつかるか、を数える。

part1は「右に3、下に1」で進むと何回ぶつかるか。
入力をparseして # のときのみ true として扱い、単純にfor loopで見ていく。横方向には同じパターンが続いているということで、常にwidthでのmodを見ておけば はみ出た場合を考慮できる。

impl Solution {
    fn new(inputs: Vec<String>) -> Self {
        Self {
            grid: inputs
                .iter()
                .map(|row| row.chars().map(|c| c == '#').collect())
                .collect(),
        }
    }
    fn solve_1(&self) -> usize {
        let width = self.grid[0].len();
        (0..self.grid.len())
            .filter(|&i| self.grid[i][(i * 3) % width])
            .count()
    }
}

part2

part1では「右に3、下に1」の場合だけを考えれば良かったが、他の進み方をしたときも計算する必要がある。ので各方向の場合で数えるメソッドを用意し、それぞれの回数を求めて掛け合わせる。

    fn solve_2(&self) -> usize {
        [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
            .iter()
            .map(|&(right, down)| self.count(right, down))
            .product()
    }
    fn count(&self, right: usize, down: usize) -> usize {
        let width = self.grid[0].len();
        (0..self.grid.len() / down)
            .filter(|&i| self.grid[i * down][(i * right) % width])
            .count()
    }

code

use std::io::{BufRead, BufReader};

struct Solution {
    grid: Vec<Vec<bool>>,
}

impl Solution {
    fn new(inputs: Vec<String>) -> Self {
        Self {
            grid: inputs
                .iter()
                .map(|row| row.chars().map(|c| c == '#').collect())
                .collect(),
        }
    }
    fn solve_1(&self) -> usize {
        self.count(3, 1)
    }
    fn solve_2(&self) -> usize {
        [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
            .iter()
            .map(|&(right, down)| self.count(right, down))
            .product()
    }
    fn count(&self, right: usize, down: usize) -> usize {
        let width = self.grid[0].len();
        (0..self.grid.len() / down)
            .filter(|&i| self.grid[i * down][(i * right) % width])
            .count()
    }
}

fn main() {
    let inputs: Vec<String> = BufReader::new(std::io::stdin().lock())
        .lines()
        .filter_map(|line| line.ok())
        .collect();
    let solution = Solution::new(inputs);
    println!("{}", solution.solve_1());
    println!("{}", solution.solve_2());
}

Discussion

ログインするとコメントできます