aoc_2024/day04/src/main.rs
2024-12-05 15:49:00 -05:00

82 lines
2.8 KiB
Rust

use std::collections::HashMap;
use std::fs;
use std::env;
use crate::Dir::{North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest};
// nodes are (coord, direction) pairs.
// neighbors are step1+turnleft, step2+turnleft, step3+turnleft, step1+turnright, etc
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
enum Dir { North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest }
fn step(start: &Coord, d: Dir, steps: i32) -> Coord {
match d {
North => (start.0, start.1 - steps),
South => (start.0, start.1 + steps),
East => (start.0 + steps, start.1),
West => (start.0 - steps, start.1),
NorthEast => (start.0 + steps, start.1 - steps),
NorthWest => (start.0 - steps, start.1 - steps),
SouthEast => (start.0 + steps, start.1 + steps),
SouthWest => (start.0 - steps, start.1 + steps)
}
}
type Coord = (i32, i32);
fn main() {
println!("Hello, AoC day 04!");
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("wrong number of arguments!");
std::process::exit(1);
}
let file_path = &args[1];
let contents = fs::read_to_string(file_path).expect("Should have been able to read the file");
let mut grid: HashMap<Coord, char> = HashMap::new();
let mut x;
// build our grid!
let mut y = 0;
for line in contents.lines() {
x = 0;
for c in line.chars() {
grid.insert((x,y), c);
x += 1;
}
y += 1;
}
let mut sum = 0;
let mut xsum = 0;
let directions = vec![North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest];
for (position, _letter) in &grid {
for dir in &directions {
if check(position, &grid, *dir) { sum += 1 }
}
if xcheck(position, &grid) { xsum += 1 }
}
println!("there are {sum} xmases");
println!("there are {xsum} x-mases");
}
fn check(position: &Coord, grid: &HashMap<Coord, char>, direction: Dir) -> bool {
if grid.get(&step(position, direction, 0)) != Some(&'X') { return false; }
if grid.get(&step(position, direction, 1)) != Some(&'M') { return false; }
if grid.get(&step(position, direction, 2)) != Some(&'A') { return false; }
if grid.get(&step(position, direction, 3)) != Some(&'S') { return false; }
return true;
}
fn xcheck(position: &Coord, grid: &HashMap<Coord, char>) -> bool {
if grid.get(position) != Some(&'A') { return false; }
let a = (grid.get(&step(position, NorthEast, 1)), grid.get(&step(position, SouthWest, 1)));
let b = (grid.get(&step(position, SouthEast, 1)), grid.get(&step(position, NorthWest, 1)));
if a != (Some(&'M'), Some(&'S')) && a != (Some(&'S'), Some(&'M')) { return false; }
if b != (Some(&'M'), Some(&'S')) && b != (Some(&'S'), Some(&'M')) { return false; }
return true;
}