diff --git a/.gitignore b/.gitignore index e8ba747..9f3b813 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ node_modules/ *.hi *.o *.exe +target/ input.txt diff --git a/2016/Cargo.lock b/2016/Cargo.lock new file mode 100644 index 0000000..f8888e2 --- /dev/null +++ b/2016/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aoc2016" +version = "0.1.0" diff --git a/2016/Cargo.toml b/2016/Cargo.toml new file mode 100644 index 0000000..bd1aeac --- /dev/null +++ b/2016/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aoc2016" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/2016/src/bin/day1.rs b/2016/src/bin/day1.rs new file mode 100644 index 0000000..c21168c --- /dev/null +++ b/2016/src/bin/day1.rs @@ -0,0 +1,89 @@ +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; +use std::collections::HashSet; + +#[derive(PartialEq, Clone, Copy)] +enum Direction { + North, + East, + South, + West +} + +fn turn(dir: &str, curr: &Direction) -> Direction { + let dirs = [Direction::North, Direction::East, Direction::South, Direction::West]; + let index = dirs.iter().position(|s| s == curr).unwrap(); + + match dir { + "R" => { dirs[(index + 1) % 4] } + "L" => { dirs[(4 + index - 1) % 4] }, + _ => panic!("Tried to turn unknown direction {}", dir) + } +} + +fn move_dist(loc: (i32, i32), dir: &Direction, dist: i32, visited: &mut HashSet<(i32, i32)>) -> ((i32, i32), Option<(i32, i32)>) { + let (x, y) = loc; + + let (new_x, new_y) = match *dir { + Direction::North => { (x, y + dist) }, + Direction::East => { (x + dist, y) }, + Direction::South => { (x, y - dist) }, + Direction::West => { (x - dist, y) } + }; + + let mut already_visited = None; + + for i in 1..dist { + let curr = (x + ((new_x - x) / dist) * i, y + ((new_y - y) / dist) * i); + + if visited.contains(&curr) && already_visited.is_none() { + already_visited = Some(curr); + } + else { + visited.insert(curr); + } + } + + ((new_x, new_y), already_visited) +} + +fn manhattan_dist(loc: (i32, i32)) -> i32 { + return loc.0.abs() + loc.1.abs(); +} + +fn main() { + let path = Path::new("input.txt"); + let display = path.display(); + + let mut file = match File::open(&path) { + Err(why) => panic!("couldn't open {}: {}", display, why), + Ok(file) => file, + }; + + let mut s = String::new(); + file.read_to_string(&mut s).unwrap(); + + let parts = s.trim().split(", "); + + let mut loc = (0, 0); + let mut dir = Direction::North; + let mut visited = HashSet::new(); + let mut already_visited = None; + + for p in parts { + let (first, rest) = p.split_at(1); + let distance = rest.parse::().unwrap(); + + dir = turn(first, &dir); + let result = move_dist(loc, &dir, distance, &mut visited); + loc = result.0; + + if already_visited.is_none() && result.1.is_some() { + already_visited = result.1; + } + } + + println!("part 1 {}", manhattan_dist(loc)); + println!("part 2 {}", manhattan_dist(already_visited.unwrap())); +} \ No newline at end of file