summaryrefslogtreecommitdiff
path: root/2024/04/rust/src/main.rs
blob: f1f464fc4a1c4008102bd39a8698761ad9e192a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#![feature(iter_order_by)]

use aoc::grid::{chebyshev_ball, Grid};
use std::io;

fn main() -> io::Result<()> {
    let grid: Vec<Vec<char>> = io::stdin()
        .lines()
        .map(|line| line.unwrap().chars().collect())
        .collect();
    let grid = Grid::new(grid);

    let silver: usize = silver(&grid);
    let gold: usize = gold(&grid);
    println!("silver: {silver}");
    println!("gold: {gold}");

    return Ok(());
}

fn silver(grid: &Grid<char>) -> usize {
    grid.points()
        .flat_map(|p| chebyshev_ball(1).map(move |dp| grid.ray(p, dp)))
        .map(|cs| cs.take(4).eq_by("XMAS".chars(), |a, b| *a == b))
        .filter(|p| *p)
        .count()
}

fn gold(grid: &Grid<char>) -> usize {
    let xmas: Vec<(i64, i64)> = vec![(0, 0), (-1, -1), (1, -1), (-1, 1), (1, 1)];
    grid.points()
        .map(move |p| {
            xmas.iter()
                .map(|&d| grid.move_pos(p, d.into(), 1).and_then(|p| grid.at(p)))
                .collect::<Option<Vec<_>>>()
        })
        .flatten()
        .map(|cs| {
            vec!["AMSMS", "AMMSS", "ASMSM", "ASSMM"]
                .iter()
                .map(|x| cs.iter().eq_by(x.chars(), |&&a, b| a == b))
                .any(|p| p)
        })
        .filter(|p| *p)
        .count()
}