Skip to content

Commit

Permalink
Merge pull request #113 from ephemient/rs/day14
Browse files Browse the repository at this point in the history
Day 14: Restroom Redoubt
  • Loading branch information
ephemient authored Dec 17, 2024
2 parents 767479d + ad793c3 commit eba76c4
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Development occurs in language-specific directories:
|[Day11.hs](hs/src/Day11.hs)|[Day11.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day11.kt)|[day11.py](py/aoc2024/day11.py)|[day11.rs](rs/src/day11.rs)|
|[Day12.hs](hs/src/Day12.hs)|[Day12.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day12.kt)|[day12.py](py/aoc2024/day12.py)|[day12.rs](rs/src/day12.rs)|
|[Day13.hs](hs/src/Day13.hs)|[Day13.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day13.kt)|[day13.py](py/aoc2024/day13.py)|[day13.rs](rs/src/day13.rs)|
|[Day14.hs](hs/src/Day14.hs)|[Day14.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day14.kt)|[day14.py](py/aoc2024/day14.py)||
|[Day14.hs](hs/src/Day14.hs)|[Day14.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day14.kt)|[day14.py](py/aoc2024/day14.py)|[day14.rs](rs/src/day14.rs)|
|[Day15.hs](hs/src/Day15.hs)|[Day15.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day15.kt)|[day15.py](py/aoc2024/day15.py)||
|[Day16.hs](hs/src/Day16.hs)|[Day16.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day16.kt)|[day16.py](py/aoc2024/day16.py)||
|[Day17.hs](hs/src/Day17.hs)|[Day17.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day17.kt)|||
10 changes: 9 additions & 1 deletion rs/benches/criterion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use aoc2024::{day1, day10, day11, day12, day13, day2, day3, day4, day5, day6, day7, day8, day9};
use aoc2024::{
day1, day10, day11, day12, day13, day14, day2, day3, day4, day5, day6, day7, day8, day9,
};
use criterion::{black_box, Criterion};
use std::env;
use std::fs;
Expand Down Expand Up @@ -92,6 +94,12 @@ fn aoc2024_bench(c: &mut Criterion) -> io::Result<()> {
g.bench_function("part 2", |b| b.iter(|| day13::part2(black_box(&data))));
g.finish();

let data = get_day_input(14)?;
let mut g = c.benchmark_group("day 14");
g.bench_function("part 1", |b| b.iter(|| day14::part1(black_box(&data))));
g.bench_function("part 2", |b| b.iter(|| day14::part2(black_box(&data))));
g.finish();

Ok(())
}

Expand Down
95 changes: 95 additions & 0 deletions rs/src/day14.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use std::cmp::Ordering;

use itertools::Itertools;

const WIDTH: isize = 101;
const HEIGHT: isize = 103;

#[derive(Clone, Copy, Debug)]
struct Robot {
x0: isize,
y0: isize,
vx: isize,
vy: isize,
}

fn parse(data: &str) -> impl Iterator<Item = Robot> + use<'_> {
data.lines().filter_map(|line| {
let (p, v) = line.split_once(' ')?;
let (x0, y0) = p.strip_prefix("p=")?.split_once(',')?;
let (vx, vy) = v.strip_prefix("v=")?.split_once(',')?;
Some(Robot {
x0: x0.parse().ok()?,
y0: y0.parse().ok()?,
vx: vx.parse().ok()?,
vy: vy.parse().ok()?,
})
})
}

pub fn part1(data: &str) -> usize {
part1_(data, WIDTH, HEIGHT)
}

fn part1_(data: &str, width: isize, height: isize) -> usize {
let (mut q1, mut q2, mut q3, mut q4) = (0, 0, 0, 0);
for Robot { x0, y0, vx, vy } in parse(data) {
let x = (x0 + vx * 100).rem_euclid(width);
let y = (y0 + vy * 100).rem_euclid(height);
match ((width / 2).cmp(&x), (height / 2).cmp(&y)) {
(Ordering::Less, Ordering::Less) => q1 += 1,
(Ordering::Less, Ordering::Greater) => q2 += 1,
(Ordering::Greater, Ordering::Less) => q3 += 1,
(Ordering::Greater, Ordering::Greater) => q4 += 1,
_ => {}
}
}
q1 * q2 * q3 * q4
}

pub fn part2(data: &str) -> Option<usize> {
let robots = parse(data).collect::<Vec<_>>();
(0..WIDTH * HEIGHT)
.max_by_key(|t| {
robots
.iter()
.map(|Robot { x0, y0, vx, vy }| {
(
(x0 + vx * t).rem_euclid(WIDTH),
(y0 + vy * t).rem_euclid(HEIGHT),
)
})
.sorted()
.tuple_windows()
.filter(|((x, y), next)| (*x, y + 1) == *next)
.count()
})
.and_then(|t| t.try_into().ok())
}

#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
use pretty_assertions::assert_eq;

static EXAMPLE: &str = indoc! {"
p=0,4 v=3,-3
p=6,3 v=-1,-3
p=10,3 v=-1,2
p=2,0 v=2,-1
p=0,0 v=1,3
p=3,0 v=-2,-2
p=7,6 v=-1,-3
p=3,0 v=-1,-2
p=9,3 v=2,3
p=7,3 v=-1,2
p=2,4 v=2,-3
p=9,5 v=-3,-3
"};

#[test]
fn part1_examples() {
assert_eq!(12, part1_(EXAMPLE, 11, 7));
}
}
1 change: 1 addition & 0 deletions rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod day10;
pub mod day11;
pub mod day12;
pub mod day13;
pub mod day14;
pub mod day2;
pub mod day3;
pub mod day4;
Expand Down
12 changes: 11 additions & 1 deletion rs/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use anyhow::anyhow;
use aoc2024::{day1, day10, day11, day12, day13, day2, day3, day4, day5, day6, day7, day8, day9};
use aoc2024::{
day1, day10, day11, day12, day13, day14, day2, day3, day4, day5, day6, day7, day8, day9,
};
use std::collections::HashSet;
use std::env;
use std::fs;
Expand Down Expand Up @@ -121,5 +123,13 @@ fn main() -> anyhow::Result<()> {
println!();
}

if args.is_empty() || args.contains("14") {
println!("Day 14");
let data = get_day_input(14)?;
println!("{:?}", day14::part1(&data));
println!("{:?}", day14::part2(&data).ok_or(anyhow!("None"))?);
println!();
}

Ok(())
}

0 comments on commit eba76c4

Please sign in to comment.