From b99474d071b452251a2cab1d556b660360df7bf9 Mon Sep 17 00:00:00 2001 From: Adrian Groh Date: Sat, 14 Dec 2024 10:13:58 +0100 Subject: [PATCH] Add day14 --- day14/Cargo.lock | 61 +++++++++++++++++++++++ day14/Cargo.toml | 8 +++ day14/src/main.rs | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 day14/Cargo.lock create mode 100644 day14/Cargo.toml create mode 100644 day14/src/main.rs diff --git a/day14/Cargo.lock b/day14/Cargo.lock new file mode 100644 index 0000000..230f69b --- /dev/null +++ b/day14/Cargo.lock @@ -0,0 +1,61 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "day14" +version = "0.1.0" +dependencies = [ + "glam", + "regex", +] + +[[package]] +name = "glam" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" diff --git a/day14/Cargo.toml b/day14/Cargo.toml new file mode 100644 index 0000000..af014a8 --- /dev/null +++ b/day14/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day14" +version = "0.1.0" +edition = "2021" + +[dependencies] +glam = "0.29.2" +regex = "1.11.1" diff --git a/day14/src/main.rs b/day14/src/main.rs new file mode 100644 index 0000000..05b6308 --- /dev/null +++ b/day14/src/main.rs @@ -0,0 +1,121 @@ +use glam::IVec2; +use regex::Regex; + +#[derive(Debug, Clone, Eq, PartialEq)] +struct Robot { + position: IVec2, + velocity: IVec2, +} + +#[rustfmt::skip] +fn parse(input: &str) -> Vec { + let re = Regex::new(r"-?\d+").unwrap(); + input.lines().map(|l| { + let mut captures = re.captures_iter(l); + Robot { + position: IVec2 { + x: captures.next().unwrap().get(0).unwrap().as_str().parse().unwrap(), + y: captures.next().unwrap().get(0).unwrap().as_str().parse().unwrap(), + }, + velocity: IVec2 { + x: captures.next().unwrap().get(0).unwrap().as_str().parse().unwrap(), + y: captures.next().unwrap().get(0).unwrap().as_str().parse().unwrap(), + } + } + }).collect() +} + +fn get_pos_after_steps(robot: &Robot, steps: &i32, dimensions: &IVec2) -> IVec2 { + let p = robot.position + steps * robot.velocity; + let mut res = IVec2::new(0, 0); + if p.x >= 0 { + res.x = p.x % dimensions.x; + } else { + let diff = p.x.abs() % dimensions.x; + if diff == 0 { + res.x = 0; + } else { + res.x = dimensions.x - diff; + } + } + if p.y >= 0 { + res.y = p.y % dimensions.y; + } else { + let diff = p.y.abs() % dimensions.y; + if diff == 0 { + res.y = 0; + } else { + res.y = dimensions.y - diff; + } + } + res +} + +fn part1(input: &[Robot], dimensions: &IVec2) -> usize { + input + .iter() + .fold([0, 0, 0, 0], |mut acc, curr| { + let p = get_pos_after_steps(curr, &100, dimensions); + if p.x < (dimensions.x / 2) && p.y < (dimensions.y / 2) { + acc[0] += 1; + } + if p.x > (dimensions.x / 2) && p.y < (dimensions.y / 2) { + acc[1] += 1; + } + if p.x < (dimensions.x / 2) && p.y > (dimensions.y / 2) { + acc[2] += 1 + } + if p.x > (dimensions.x / 2) && p.y > (dimensions.y / 2) { + acc[3] += 1; + } + acc + }) + .iter() + .product() +} + +// fn print_map(robots: &[Robot], dimensions: &IVec2) -> String { +// let mut res = String::new(); +// for y in 0..dimensions.x { +// for x in 0..dimensions.y { +// if robots +// .iter() +// .map(|r| (r.position.x, r.position.y)) +// .any(|p| p == (x, y)) +// { +// res.push('#'); +// } else { +// res.push(' '); +// } +// } +// res.push('\n'); +// } +// res +// } + +fn has_tree(robots: &[Robot]) -> bool { + let check: Vec<_> = (0..8).map(|i| IVec2::new(i, 0)).collect(); + robots.iter().any(|p| { + check + .iter() + .all(|c| robots.iter().any(|p2| p2.position == p.position + c)) + }) +} + +fn part2(robots: &mut [Robot], dimensions: &IVec2) -> i32 { + for i in 0.. { + if has_tree(robots) { + return i; + } + robots + .iter_mut() + .for_each(|r| r.position = get_pos_after_steps(r, &1, dimensions)) + } + unreachable!() +} + +fn main() { + let mut input = parse(include_str!("../input.txt")); + println!("{}", part1(&input, &IVec2::new(101, 103))); + println!("{}", part2(&mut input, &IVec2::new(101, 103))); +}