--- /dev/null
+use std::error::Error;
+use std::collections::HashMap;
+
+struct Puzzle {
+ start: (usize, usize),
+ map: HashMap<(usize, usize), (char, bool)>, // bool to store if key has been visited already
+}
+
+impl Puzzle {
+ fn new(input: &str) -> Self {
+ let mut start = (0, 0);
+ let mut map = HashMap::new();
+ input.lines().enumerate()
+ .for_each(|(i, l)| {
+ l.chars().enumerate()
+ .for_each(|(j, c)| {
+ if c == 'S' {
+ start = (i, j);
+ }
+ map.insert((i, j), (c, false)); });
+ });
+ Puzzle { start, map }
+ }
+
+ fn part1(&mut self) -> u64 {
+ let mut splitters = 0;
+ let mut beam: Vec<(usize, usize)> = Vec::new();
+ beam.push((self.start.0 + 1, self.start.1));
+ while let Some(pos) = beam.pop() {
+ if self.map.contains_key(&pos) {
+ let mut location = self.map.get_mut(&pos).unwrap();
+ if location.1 {
+ continue;
+ }
+ location.1 = true;
+ match location.0 {
+ '.' => { beam.push((pos.0 + 1, pos.1)); },
+ '^' => {
+ splitters += 1;
+ beam.push((pos.0, pos.1 - 1));
+ beam.push((pos.0, pos.1 + 1));
+ },
+ _ => {},
+ }
+ }
+ }
+ splitters
+ }
+}
+
+pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
+ let mut p = Puzzle::new(input);
+ println!("part1: {}", p.part1());
+ Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ static TEST_INPUT: &str = "\
+.......S.......
+...............
+.......^.......
+...............
+......^.^......
+...............
+.....^.^.^.....
+...............
+....^.^...^....
+...............
+...^.^...^.^...
+...............
+..^...^.....^..
+...............
+.^.^.^.^.^...^.
+...............
+";
+
+ #[test]
+ fn test_part1() {
+ assert_eq!(21, Puzzle::new(TEST_INPUT).part1());
+ }
+}
pub mod day04;
pub mod day05;
pub mod day06;
+pub mod day07;
fn main() {
let args: Vec<String> = env::args().collect();
"day04" => day04::run(&input)?,
"day05" => day05::run(&input)?,
"day06" => day06::run(&input)?,
+ "day07" => day07::run(&input)?,
_ => return Err(format!("unknown or unimplemented day \"{day}\"").into()),
}
Ok(())