diff --git a/Cargo.lock b/Cargo.lock index 67a0b69..389a5fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,8 @@ dependencies = [ "array2d", "itertools", "rust-crypto", + "strum", + "strum_macros", ] [[package]] @@ -66,6 +68,12 @@ version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "itertools" version = "0.12.0" @@ -171,6 +179,12 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.16" @@ -208,6 +222,25 @@ dependencies = [ "serde", ] +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.41", +] + [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index 225963e..737fb76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,6 @@ rust-crypto = "0.2.36" aoc-runner = "0.3.0" aoc-runner-derive = "0.3.0" itertools = "0.12.0" -array2d = "0.3.0" \ No newline at end of file +array2d = "0.3.0" +strum = "0.25.0" +strum_macros = "0.25" \ No newline at end of file diff --git a/old/day10/Cargo.lock b/old/day10/Cargo.lock deleted file mode 100644 index f5438c5..0000000 --- a/old/day10/Cargo.lock +++ /dev/null @@ -1,77 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "day10" -version = "0.1.0" -dependencies = [ - "strum", - "strum_macros", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "proc-macro2" -version = "1.0.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/old/day10/Cargo.toml b/old/day10/Cargo.toml deleted file mode 100644 index d7883d0..0000000 --- a/old/day10/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "day10" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -strum = "0.25.0" -strum_macros = "0.25" diff --git a/old/day10/src/main.rs b/old/day10/src/main.rs deleted file mode 100644 index 43aa4cc..0000000 --- a/old/day10/src/main.rs +++ /dev/null @@ -1,234 +0,0 @@ -use std::fs; -use strum::IntoEnumIterator; -use strum_macros::EnumIter; - -fn main() { - let input = fs::read_to_string("input.txt").unwrap(); - let input = parse_input(&input); - let start = find_start(&input); - - let mut start_dirs: Vec = vec![]; - for dir in Direction::iter().filter(|x| x != &Direction::Start) { - let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0)); - if x < 0 || y < 0 { - continue; - } - let neibhor = &input[x as usize][y as usize]; - if neibhor.contains(&dir.reverse()) { - start_dirs.push(dir); - } - } - - let mut finished = false; - - let mut pre = start_dirs[0].reverse(); - let mut pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize); - - let mut the_loop = vec![start, pos]; - let mut area = 0; - - while !finished { - let first_next = &input[pos.0][pos.1].iter().filter(|x| x != &&pre).next().unwrap(); - pos = ((pos.0 as i32 + first_next.to_ind().1) as usize, (pos.1 as i32 + first_next.to_ind().0) as usize); - pre = first_next.reverse(); - - finished = pos == start; - the_loop.push(pos); - } - - - for win in the_loop.windows(2) { - area += (win[0].1 * win[1].0) as i64; - area -= (win[0].0 * win[1].1) as i64; - } - let area = i64::abs(area) / 2; - - let spaces = area - (the_loop.len() as i64 / 2) + 1; - - println!("{}", spaces) - -} - -fn parse_input(input: &String) -> Vec>> { - let input: Vec<_> = input.split('\n') - .map(|line| { - line.chars() - .map(|char| { - match char { - '|' => vec![Direction::North, Direction::South], - '-' => vec![Direction::East, Direction::West], - 'L' => vec![Direction::North, Direction::East], - 'J' => vec![Direction::North, Direction::West], - '7' => vec![Direction::South, Direction::West], - 'F' => vec![Direction::South, Direction::East], - '.' => vec![], - 'S' => vec![Direction::Start], - _ => panic!("Invalid pipe char") - } - }).collect::>() - }).collect(); - return input; -} - -fn find_start(input: &Vec>>) -> (usize, usize) { - let mut start_point: Option<(usize, usize)> = None; - for i in 0..input.len() { - for j in 0..input[0].len() { - if input[i][j].contains(&Direction::Start) { - start_point = Some((i,j)); - } - } - } - - match start_point { - Some(x) => x, - None => panic!("No start point found! AHHHHH") - } -} - -#[derive(Debug, PartialEq, EnumIter)] -enum Direction { - North, - South, - East, - West, - Start -} - -impl Direction { - pub fn to_ind(&self) -> (i32, i32) { - match self { - Direction::North => (0,-1), - Direction::South => (0,1), - Direction::East => (1,0), - Direction::West => (-1,0), - Direction::Start => panic!("Start should never be converted to an index. AHH"), - } - } - - pub fn reverse(&self) -> Direction { - match self { - Direction::North => Direction::South, - Direction::South => Direction::North, - Direction::East => Direction::West, - Direction::West => Direction::East, - Direction::Start => panic!("Start should never be reversed. AHH"), - } - } -} - - -// use std::fs; -// use strum::IntoEnumIterator; -// use strum_macros::EnumIter; - -// fn main() { -// let input = fs::read_to_string("input.txt").unwrap(); -// let input = parse_input(&input); -// let start = find_start(&input); - -// let mut start_dirs: Vec = vec![]; -// for dir in Direction::iter().filter(|x| x != &Direction::Start) { -// let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0)); -// if x < 0 || y < 0 { -// continue; -// } -// let neibhor = &input[x as usize][y as usize]; -// if neibhor.contains(&dir.reverse()) { -// start_dirs.push(dir); -// } -// } - -// let mut finished = false; -// let mut count = 1; - -// let mut first_pre = start_dirs[0].reverse(); -// let mut second_pre = start_dirs[1].reverse(); -// let mut first_pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize); -// let mut second_pos = ((start.0 as i32 + start_dirs[1].to_ind().1) as usize, (start.1 as i32 + start_dirs[1].to_ind().0) as usize); - -// while !finished { -// let first_next = &input[first_pos.0][first_pos.1].iter().filter(|x| x != &&first_pre).next().unwrap(); -// first_pos = ((first_pos.0 as i32 + first_next.to_ind().1) as usize, (first_pos.1 as i32 + first_next.to_ind().0) as usize); -// first_pre = first_next.reverse(); - -// let second_next = &input[second_pos.0][second_pos.1].iter().filter(|x| x != &&second_pre).next().unwrap(); -// second_pos = ((second_pos.0 as i32 + second_next.to_ind().1) as usize, (second_pos.1 as i32 + second_next.to_ind().0) as usize); -// second_pre = second_next.reverse(); - -// count += 1; -// finished = first_pos == second_pos; - -// } - - -// println!("{:?}", count) -// } - -// fn parse_input(input: &String) -> Vec>> { -// let input: Vec<_> = input.split('\n') -// .map(|line| { -// line.chars() -// .map(|char| { -// match char { -// '|' => vec![Direction::North, Direction::South], -// '-' => vec![Direction::East, Direction::West], -// 'L' => vec![Direction::North, Direction::East], -// 'J' => vec![Direction::North, Direction::West], -// '7' => vec![Direction::South, Direction::West], -// 'F' => vec![Direction::South, Direction::East], -// '.' => vec![], -// 'S' => vec![Direction::Start], -// _ => panic!("Invalid pipe char") -// } -// }).collect::>() -// }).collect(); -// return input; -// } - -// fn find_start(input: &Vec>>) -> (usize, usize) { -// let mut start_point: Option<(usize, usize)> = None; -// for i in 0..input.len() { -// for j in 0..input[0].len() { -// if input[i][j].contains(&Direction::Start) { -// start_point = Some((i,j)); -// } -// } -// } - -// match start_point { -// Some(x) => x, -// None => panic!("No start point found! AHHHHH") -// } -// } - -// #[derive(Debug, PartialEq, EnumIter)] -// enum Direction { -// North, -// South, -// East, -// West, -// Start -// } - -// impl Direction { -// pub fn to_ind(&self) -> (i32, i32) { -// match self { -// Direction::North => (0,-1), -// Direction::South => (0,1), -// Direction::East => (1,0), -// Direction::West => (-1,0), -// Direction::Start => panic!("Start should never be converted to an index. AHH"), -// } -// } - -// pub fn reverse(&self) -> Direction { -// match self { -// Direction::North => Direction::South, -// Direction::South => Direction::North, -// Direction::East => Direction::West, -// Direction::West => Direction::East, -// Direction::Start => panic!("Start should never be reversed. AHH"), -// } -// } -// } \ No newline at end of file diff --git a/src/day10.rs b/src/day10.rs new file mode 100644 index 0000000..8f34365 --- /dev/null +++ b/src/day10.rs @@ -0,0 +1,190 @@ +use aoc_runner_derive::{aoc, aoc_generator}; +use strum::IntoEnumIterator; +use strum_macros::EnumIter; + +#[aoc_generator(day10)] +fn parse(input: &str) -> ((usize, usize), Vec>>) { + let input: Vec<_> = input.split('\n') + .map(|line| { + line.chars() + .map(|char| { + match char { + '|' => vec![Direction::North, Direction::South], + '-' => vec![Direction::East, Direction::West], + 'L' => vec![Direction::North, Direction::East], + 'J' => vec![Direction::North, Direction::West], + '7' => vec![Direction::South, Direction::West], + 'F' => vec![Direction::South, Direction::East], + '.' => vec![], + 'S' => vec![Direction::Start], + _ => panic!("Invalid pipe char") + } + }).collect::>() + }).collect(); + + let start = find_start(&input); + + (start, input) +} + +fn find_start(input: &Vec>>) -> (usize, usize) { + let mut start_point: Option<(usize, usize)> = None; + for i in 0..input.len() { + for j in 0..input[0].len() { + if input[i][j].contains(&Direction::Start) { + start_point = Some((i,j)); + } + } + } + + match start_point { + Some(x) => x, + None => panic!("No start point found! AHHHHH") + } +} + +#[aoc(day10, part1)] +fn part1((start, input): &((usize, usize), Vec>>)) -> i32 { + let mut start_dirs: Vec = vec![]; + for dir in Direction::iter().filter(|x| x != &Direction::Start) { + let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0)); + if x < 0 || y < 0 { + continue; + } + let neibhor = &input[x as usize][y as usize]; + if neibhor.contains(&dir.reverse()) { + start_dirs.push(dir); + } + } + + let mut finished = false; + let mut count = 1; + + let mut first_pre = start_dirs[0].reverse(); + let mut second_pre = start_dirs[1].reverse(); + let mut first_pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize); + let mut second_pos = ((start.0 as i32 + start_dirs[1].to_ind().1) as usize, (start.1 as i32 + start_dirs[1].to_ind().0) as usize); + + while !finished { + let first_next = &input[first_pos.0][first_pos.1].iter().filter(|x| x != &&first_pre).next().unwrap(); + first_pos = ((first_pos.0 as i32 + first_next.to_ind().1) as usize, (first_pos.1 as i32 + first_next.to_ind().0) as usize); + first_pre = first_next.reverse(); + + let second_next = &input[second_pos.0][second_pos.1].iter().filter(|x| x != &&second_pre).next().unwrap(); + second_pos = ((second_pos.0 as i32 + second_next.to_ind().1) as usize, (second_pos.1 as i32 + second_next.to_ind().0) as usize); + second_pre = second_next.reverse(); + + count += 1; + finished = first_pos == second_pos; + + } + + count +} + +#[aoc(day10, part2)] +fn part2((start, input): &((usize, usize), Vec>>)) -> i64 { + let mut start_dirs: Vec = vec![]; + for dir in Direction::iter().filter(|x| x != &Direction::Start) { + let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0)); + if x < 0 || y < 0 { + continue; + } + let neibhor = &input[x as usize][y as usize]; + if neibhor.contains(&dir.reverse()) { + start_dirs.push(dir); + } + } + + let mut finished = false; + + let mut pre = start_dirs[0].reverse(); + let mut pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize); + + let mut the_loop = vec![*start, pos]; + let mut area = 0; + + while !finished { + let first_next = &input[pos.0][pos.1].iter().filter(|x| x != &&pre).next().unwrap(); + pos = ((pos.0 as i32 + first_next.to_ind().1) as usize, (pos.1 as i32 + first_next.to_ind().0) as usize); + pre = first_next.reverse(); + + finished = pos == *start; + the_loop.push(pos); + } + + + for win in the_loop.windows(2) { + area += (win[0].1 * win[1].0) as i64; + area -= (win[0].0 * win[1].1) as i64; + } + let area = i64::abs(area) / 2; + + let spaces = area - (the_loop.len() as i64 / 2) + 1; + + spaces +} + +#[derive(Debug, PartialEq, EnumIter)] +enum Direction { + North, + South, + East, + West, + Start +} + +impl Direction { + pub fn to_ind(&self) -> (i32, i32) { + match self { + Direction::North => (0,-1), + Direction::South => (0,1), + Direction::East => (1,0), + Direction::West => (-1,0), + Direction::Start => panic!("Start should never be converted to an index. AHH"), + } + } + + pub fn reverse(&self) -> Direction { + match self { + Direction::North => Direction::South, + Direction::South => Direction::North, + Direction::East => Direction::West, + Direction::West => Direction::East, + Direction::Start => panic!("Start should never be reversed. AHH"), + } + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + const EX: &str = r"7-F7- +.FJ|7 +SJLL7 +|F--J +LJ.LJ"; + +const EX_2: &str = r".F----7F7F7F7F-7.... +.|F--7||||||||FJ.... +.||.FJ||||||||L7.... +FJL7L7LJLJ||LJ.L-7.. +L--J.L7...LJS7F-7L7. +....F-J..F7FJ|L7L7L7 +....L7.F7||L7|.L7L7| +.....|FJLJ|FJ|F7|.LJ +....FJL-7.||.||||... +....L---J.LJ.LJLJ..."; + + #[test] + fn part1_example() { + assert_eq!(part1(&parse(EX)), 8); + } + + #[test] + fn part2_example() { + assert_eq!(part2(&parse(EX_2)), 8); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index dff261b..1a36258 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +mod day10; mod day9; mod day8; mod day7;