82 lines
2.8 KiB
Rust
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;
|
|
} |