Table of content

What is this :grey_question:

The rules of the game are explained in my original.

91st Challenge

Challenge

Today I did day16. advent of code. This one was easier than yesterday.

Solution

use pathfinding::{
    directed::dijkstra::dijkstra,
    prelude::{astar_bag},
};

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct Pos(i32, i32);

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct ReindeerArena {
    legal: Vec<Pos>,
    illegal: Vec<Pos>,
    end: Pos,
    start: Pos,
}

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct Vector {
    pos: Pos,
    dir: Pos,
}

impl ReindeerArena {
    fn is_legal(&self, pos: &Pos) -> bool {
        self.legal.contains(pos) && !self.illegal.contains(pos)
    }
}

fn successors(
    v: &Vector,
    arena: &ReindeerArena,
) -> Vec<(Vector, i32)> {
    let Pos(x, y) = v.pos;
    let directions = vec![Pos(1, 0), Pos(-1, 0), Pos(0, 1), Pos(0, -1)];

    directions
        .into_iter()
        .filter_map(|d| {
            let new_pos = Pos(x + d.0, y + d.1);
            let new_dir = Pos(d.0, d.1);
            let new_v = Vector {
                pos: new_pos,
                dir: new_dir,
            };
            if arena.is_legal(&new_v.pos) {
                let score = if &d == &v.dir { 1} else { 1001 };
                Some((new_v, score))
            } else {
                None
            }
        })
        .collect()
}

fn main() {
    let input = include_str!("input.txt");

    let mut x = 0;
    let mut y = 0;

    let arena = input.chars().fold(
        ReindeerArena {
            legal: vec![],
            illegal: vec![],
            end: Pos(0, 0),
            start: Pos(0, 0),
        },
        |mut arena, c| {
            match c {
                '.' => {
                    arena.legal.push(Pos(x, y));
                    x += 1;
                }
                '#' => {
                    arena.illegal.push(Pos(x, y));
                    x += 1;
                }
                '\n' => {
                    x = 0;
                    y += 1;
                }
                'S' => {
                    arena.start = Pos(x, y);
                    arena.legal.push(Pos(x, y));
                    x += 1;
                }
                'E' => {
                    arena.end = Pos(x, y);
                    arena.legal.push(Pos(x, y));
                    x += 1;
                }
                _ => (),
            }
            arena
        },
    );

    let result = dijkstra(
        &Vector{pos: arena.start.clone(), dir: Pos(0, 0)},
        |v| successors(v, &arena),
        |v| v.pos == arena.end,
    );

    match result {
        Some((_, cost)) => {
            println!("{:?}", cost);
        }
        None => {
            println!("No path found.");
        }
    }

    let result = astar_bag(
        &Vector{pos: arena.start.clone(), dir: Pos(0, 0)},
        |v| successors(v, &arena),
        |_| x,
        |v| v.pos == arena.end,
    );
    let mut seats :Vec<Pos>= vec![];
    match result {
        Some((path, _)) => {
            for p in path {
                seats.extend(p.iter().map(|v| v.pos.clone()).collect::<Vec<Pos>>());
            }
        }
        None => {
            println!("No path found.");
        }
    }
    seats.sort();
    seats.dedup();
    println!("{:?}", seats.len());
}