diff --git a/Cargo.lock b/Cargo.lock index 801aea1..d7eab34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,7 @@ name = "aoc-2024" version = "0.1.0" dependencies = [ "advent_derive", + "gcd", "itertools", "quote", "regex", @@ -79,6 +80,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + [[package]] name = "ident_case" version = "1.0.1" @@ -87,9 +94,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] @@ -102,18 +109,18 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -155,9 +162,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -166,6 +173,6 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" diff --git a/Cargo.toml b/Cargo.toml index d6151b3..fa10221 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] -itertools = "0.13" +itertools = "0.14" regex = "1.11" syn = "2.0" quote = "1.0" advent_derive = { path = "advent_derive/"} +gcd = "2.3" diff --git a/resources/input8.txt b/resources/input8.txt new file mode 100644 index 0000000..976616d --- /dev/null +++ b/resources/input8.txt @@ -0,0 +1,50 @@ +........5..................................e..3... +.......q...........m................e............. +....m.......................................e..... +.........................................C........ +.u.m........................8..................... +...........7......9.......8...........F...s....... +6...q..............................s.............. +.................................................. +.................................................. +.................................................. +..........9....................F.................. +.................................M....D........... +.........U........................................ +..q................................8.............. +.......9.......................................... +0....6.....................e..Qs...............F.. +.................................Q...D............ +.0.u....................................2......... +.................................................. +........u................Q........................ +.....E........1................................... +...n....v....................................3.... +......u..0................N....................... +............................................z..... +.........7....U.........4.....Z...Q.....D.....V... +..............n1.........f.................2...... +E.............................f..............z.... +...E........1.Z.......U......................D.... +.......n...v....7Z...N............................ +..........7..N.....Zf...........................3. +................................b............V.... +............4..................................9.. +..n...v........................5................2. +.........v.................5.........S............ +..........................s....................... +.....U.........4..C.....................S..V...... +.................................................. +......................c........b............M..... +...........4.Wc....d.......1.....b.....S.......... +..E........c............................5......z.. +..............w..C....................SM.2........ +........................d......................... +...............c......C3.......................... +...............w....W............................. +.................................................. +.........d.......B....w........................... +....B.....W.......dw..........................M... +...............W......................N...V....... +.B................................................ +....................B...............b............. \ No newline at end of file diff --git a/src/days/day8.rs b/src/days/day8.rs new file mode 100644 index 0000000..5e5684b --- /dev/null +++ b/src/days/day8.rs @@ -0,0 +1,126 @@ +use std::{collections::HashMap, path::Path}; + +use advent_derive::advent_day; +use itertools::Itertools; +use gcd::Gcd; +use super::*; + +use crate::{error::AdventError, input::get_lines}; + + +struct Part1{ + antennas: HashMap>, + width: i32, + height: i32, +} +type Part2 = Part1; + +type Coord = (i32, i32); + +impl Part1 { + fn new() -> Self { + Self{ + antennas: HashMap::>::new(), + width: 0, + height: 0 + } + } +} + +impl Part2 { +} + + +fn read_input_part1(part1: &mut Part1, path: &Path) -> Result<(), AdventError> { + for (y, line) in get_lines(path).enumerate() { + for (x, c) in line?.chars().enumerate() { + if c != '.' { + if part1.antennas.contains_key(&c) { + part1.antennas.get_mut(&c).expect("This should never happen").push((x as i32, y as i32)); + } + else { + part1.antennas.insert(c, vec![(x as i32, y as i32)]); + } + } + part1.width = (x + 1) as i32; + } + part1.height = (y + 1) as i32; + + } + Ok(()) +} + +fn add(left: &Coord, right: &Coord) -> Coord { + (left.0 + right.0, left.1 + right.1) +} + +fn sub(left: &Coord, right: &Coord) -> Coord { + (left.0 - right.0, left.1 - right.1) +} + +fn gen_anti_nodes(left: &Coord, right: &Coord) -> Vec { + let diff = sub(left, right); + let mut antis = vec![sub(right, &diff), add(left, &diff)]; + if diff.0.rem_euclid(3) == 0 && diff.1.rem_euclid(3) == 0 { + antis.push((left.0 - diff.0 / 3, left.1 - diff.1 / 3)); + antis.push((left.0 - diff.0 / 3 * 2, left.1 - diff.1 / 3 * 2)); + } + antis +} + +fn gen_anti_nodes2(left: &Coord, right: &Coord, part2: &Part2) -> Vec { + let diff = sub(left, right); + let gcd = diff.0.unsigned_abs().gcd(diff.1.unsigned_abs()); + let node_distance = (diff.0 / (gcd as i32), diff.1 / (gcd as i32)); + let mut antis = vec![*left]; + for i in 1.. { + let d = (node_distance.0 * i, node_distance.1 * i); + let n1 = sub(left, &d); + let n2 = add(left, &d); + let b1 = in_bounds(&n1, part2); + let b2 = in_bounds(&n2, part2); + if b1 { + antis.push(n1); + } + if b2 { + antis.push(n2); + } + if !b1 && !b2 { + break; + } + } + antis +} + +fn in_bounds(coord: &Coord, part1: &Part1) -> bool { + coord.0 >= 0 && coord.0 < part1.width && coord.1 >= 0 && coord.1 < part1.height +} + +fn solve_part1(part1: &mut Part1) -> Result { + Ok(part1.antennas.iter().map(|(_, coords)| { + coords.iter().enumerate().map(|(i, coord1)| { + coords[i+1..].iter().map(|coord2| { + let antis = gen_anti_nodes(coord1, coord2); + antis + }) + }).flatten().flatten().filter(|coord| in_bounds(coord, part1)) + }).flatten().unique().count().to_string()) +} + +fn read_input_part2(part2: &mut Part2, path: &Path) -> Result<(), AdventError> { + read_input_part1(part2, path) +} + +fn solve_part2(part2: &mut Part2) -> Result { + Ok(part2.antennas.iter().map(|(_, coords)| { + coords.iter().enumerate().map(|(i, coord1)| { + coords[i+1..].iter().map(|coord2| { + let antis = gen_anti_nodes2(coord1, coord2, part2); + antis + }) + }).flatten().flatten() + }).flatten().collect::>().iter().unique().count().to_string()) +} + +#[advent_day(Part1, Part2)] +struct Day8; \ No newline at end of file diff --git a/src/days/mod.rs b/src/days/mod.rs index b3fbafc..d84a80c 100644 --- a/src/days/mod.rs +++ b/src/days/mod.rs @@ -22,23 +22,48 @@ pub mod day4; pub mod day5; pub mod day6; pub mod day7; +pub mod day8; pub mod day14; /* -fn read_input_part1(part1: &mut Day5Part1, path: &Path) -> Result<(), AdventError> { +use std::path::Path; + +use crate::error::AdventError; + + +struct Part1{} +struct Part2{} + +impl Part1 { + fn new() -> Self { + Self{} + } +} + +impl Part2 { + fn new() -> Self{ + Self{} + } +} + + +fn read_input_part1(part1: &mut Part1, path: &Path) -> Result<(), AdventError> { Ok(()) } -fn solve_part1(part1: &mut Day5Part1) -> Result { - Ok(0) +fn solve_part1(part1: &mut Part1) -> Result { + Ok("0".to_string()) } -fn read_input_part2(part2: &mut Day5Part2, path: &Path) -> Result<(), AdventError> { +fn read_input_part2(part2: &mut Part2, path: &Path) -> Result<(), AdventError> { Ok(()) } -fn solve_part2(part2: &mut Day5Part2) -> Result { - Ok(0) +fn solve_part2(part2: &mut Part2) -> Result { + Ok("0".to_string()) } + +#[advent_day(Part1, Part2)] +struct Day8; */ \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a18ebcd..4480e36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,10 +11,12 @@ use day4::Day4; use day5::Day5; use day6::Day6; use day7::Day7; +use day8::Day8; use day14::Day14; + use crate::error::AdventError; -use crate::days::*; +pub use crate::days::*; struct DummyDay { @@ -46,7 +48,7 @@ fn main() -> Result<(), AdventError> { Box::new(Day5::new()), Box::new(Day6::new()), Box::new(Day7::new()), - Box::new(DummyDay::new()), + Box::new(Day8::new()), Box::new(DummyDay::new()), Box::new(DummyDay::new()), Box::new(DummyDay::new()),