2023 - Day 18
This commit is contained in:
152
2023/src/bin/day18.rs
Normal file
152
2023/src/bin/day18.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
#![feature(test)]
|
||||
use std::{
|
||||
collections::{HashSet, VecDeque},
|
||||
fmt::Pointer,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use aoc::Solver;
|
||||
|
||||
// -- Runners --
|
||||
fn main() -> Result<()> {
|
||||
Day::solve()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn part1_test1() -> Result<()> {
|
||||
Day::test(Day::part1, "test-1", 62)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_solution() -> Result<()> {
|
||||
Day::test(Day::part1, "input", 95356)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_test1() -> Result<()> {
|
||||
Day::test(Day::part2, "test-1", 952408144115)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_solution() -> Result<()> {
|
||||
Day::test(Day::part2, "input", 92291468914147)
|
||||
}
|
||||
|
||||
// Benchmarks
|
||||
extern crate test;
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn part1_bench(b: &mut test::Bencher) {
|
||||
Day::benchmark(Day::part1, b)
|
||||
}
|
||||
#[bench]
|
||||
#[ignore]
|
||||
fn part2_bench(b: &mut test::Bencher) {
|
||||
Day::benchmark(Day::part2, b)
|
||||
}
|
||||
}
|
||||
|
||||
// -- Solution --
|
||||
pub struct Day;
|
||||
impl aoc::Solver for Day {
|
||||
type Output1 = usize;
|
||||
type Output2 = usize;
|
||||
|
||||
fn day() -> u8 {
|
||||
18
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> Self::Output1 {
|
||||
let instructions: Vec<_> = input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let (direction, rest) = line.split_once(' ').unwrap();
|
||||
let direction = direction.chars().next().unwrap();
|
||||
let (distance, _) = rest.split_once(" (#").unwrap();
|
||||
let distance: usize = distance.parse().unwrap();
|
||||
|
||||
(direction, distance)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut location = (0_isize, 0_isize);
|
||||
let mut points = Vec::new();
|
||||
let mut boundary = 0;
|
||||
|
||||
for (direction, distance) in &instructions {
|
||||
for _ in 0..*distance {
|
||||
match direction {
|
||||
'U' => location.1 -= 1,
|
||||
'D' => location.1 += 1,
|
||||
'L' => location.0 -= 1,
|
||||
'R' => location.0 += 1,
|
||||
_ => unreachable!("Invalid input"),
|
||||
}
|
||||
}
|
||||
boundary += distance;
|
||||
points.push(location);
|
||||
}
|
||||
|
||||
let mut area = 0;
|
||||
for i in 0..points.len() as isize {
|
||||
let n_min = (i - 1).rem_euclid(points.len() as isize);
|
||||
let n_plus = (i + 1).rem_euclid(points.len() as isize);
|
||||
|
||||
area += points[i as usize].1 * (points[n_min as usize].0 - points[n_plus as usize].0);
|
||||
}
|
||||
let area = area as usize / 2;
|
||||
let interior = area - boundary / 2 + 1;
|
||||
|
||||
interior + boundary
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> Self::Output2 {
|
||||
let instructions: Vec<_> = input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let (_, rest) = line.split_once(' ').unwrap();
|
||||
let (_, rest) = rest.split_once(" (#").unwrap();
|
||||
|
||||
let (distance, direction) = rest.split_at(5);
|
||||
let distance = usize::from_str_radix(distance, 16).unwrap();
|
||||
let direction = direction.chars().next().unwrap();
|
||||
|
||||
(direction, distance)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut location = (0_isize, 0_isize);
|
||||
let mut points = Vec::new();
|
||||
let mut boundary = 0;
|
||||
|
||||
for (direction, distance) in &instructions {
|
||||
for _ in 0..*distance {
|
||||
match direction {
|
||||
'3' => location.1 -= 1,
|
||||
'1' => location.1 += 1,
|
||||
'2' => location.0 -= 1,
|
||||
'0' => location.0 += 1,
|
||||
_ => unreachable!("Invalid input"),
|
||||
}
|
||||
}
|
||||
boundary += distance;
|
||||
points.push(location);
|
||||
}
|
||||
|
||||
let mut area = 0;
|
||||
for i in 0..points.len() as isize {
|
||||
let n_min = (i - 1).rem_euclid(points.len() as isize);
|
||||
let n_plus = (i + 1).rem_euclid(points.len() as isize);
|
||||
|
||||
area += points[i as usize].1 * (points[n_min as usize].0 - points[n_plus as usize].0);
|
||||
}
|
||||
let area = area as usize / 2;
|
||||
let interior = area - boundary / 2 + 1;
|
||||
|
||||
interior + boundary
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user