Added Day 14 and some dummy days for the main
This commit is contained in:
154
src/days/day14.rs
Normal file
154
src/days/day14.rs
Normal file
@@ -0,0 +1,154 @@
|
||||
|
||||
use std::{cmp::{self, max}, path::Path, str::FromStr};
|
||||
|
||||
use crate::input::read_into_vec;
|
||||
|
||||
use super::*;
|
||||
|
||||
use advent_derive::advent_day;
|
||||
use regex::Regex;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Robot {
|
||||
p: (u32, u32),
|
||||
v: (i32, i32)
|
||||
}
|
||||
|
||||
impl Robot {
|
||||
fn apply(&mut self, lx: usize, ly: usize) {
|
||||
self.p.0 = (((self.p.0 as i32) + self.v.0 + (lx as i32)) % (lx as i32)) as u32;
|
||||
self.p.1 = (((self.p.1 as i32) + self.v.1 + (ly as i32)) % (ly as i32)) as u32;
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Robot {
|
||||
type Err = AdventError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let regex = Regex::new(r"p=(\d+),(\d+) v=(-?\d+),(-?\d+)").unwrap();
|
||||
let (_, [px, py, vx, vy]) = regex.captures(s).unwrap().extract();
|
||||
return Ok(Robot {
|
||||
p: (px.parse::<u32>()?, py.parse::<u32>()?),
|
||||
v: (vx.parse::<i32>()?, vy.parse::<i32>()?)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Day14Part1 {
|
||||
width: usize,
|
||||
height: usize,
|
||||
robots: Vec<Robot>
|
||||
}
|
||||
|
||||
impl Day14Part1 {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
width: 101,
|
||||
height: 103,
|
||||
robots: vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Day14Part2 {
|
||||
width: usize,
|
||||
height: usize,
|
||||
robots: Vec<Robot>
|
||||
}
|
||||
|
||||
impl Day14Part2 {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
width: 101,
|
||||
height: 103,
|
||||
robots: vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_input_part1(part1: &mut Day14Part1, path: &Path) -> Result<(), AdventError> {
|
||||
part1.robots = read_into_vec(path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn solve_part1(part1: &mut Day14Part1) -> Result<u64, AdventError> {
|
||||
let mut counts : (u64, u64, u64 ,u64) = (0, 0, 0, 0);
|
||||
|
||||
let left_half: u32 = (part1.width / 2) as u32;
|
||||
let right_half: u32 = (part1.width / 2) as u32;
|
||||
let top_half: u32 = (part1.height / 2) as u32;
|
||||
let bottom_half: u32 = (part1.height / 2) as u32;
|
||||
|
||||
for robot in part1.robots.iter_mut() {
|
||||
for _ in 0 .. 100 {
|
||||
robot.apply(part1.width, part1.height)
|
||||
}
|
||||
|
||||
if robot.p.0 < left_half && robot.p.1 < top_half {
|
||||
counts.0 += 1;
|
||||
}
|
||||
|
||||
if robot.p.0 > right_half && robot.p.1 < top_half {
|
||||
counts.1 += 1;
|
||||
}
|
||||
|
||||
if robot.p.0 < left_half && robot.p.1 > bottom_half {
|
||||
counts.2 += 1;
|
||||
}
|
||||
|
||||
if robot.p.0 > right_half && robot.p.1 > bottom_half {
|
||||
counts.3 += 1;
|
||||
}
|
||||
}
|
||||
Ok(counts.0 * counts.1 * counts.2 * counts.3)
|
||||
}
|
||||
|
||||
fn read_input_part2(part2: &mut Day14Part2, path: &Path) -> Result<(), AdventError> {
|
||||
part2.robots = read_into_vec(path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn suspected_image(part2: &mut Day14Part2, required_cons: u32) -> bool {
|
||||
let mut clone = part2.robots.clone();
|
||||
clone.sort_by(|l, r| {
|
||||
match l.p.1.cmp(&r.p.1) {
|
||||
cmp::Ordering::Equal => l.p.0.cmp(&r.p.0),
|
||||
x => x
|
||||
}
|
||||
});
|
||||
let mut current_cons = 1u32;
|
||||
let mut last_x = (part2.width + 1) as u32;
|
||||
let mut last_y = (part2.height + 1) as u32;
|
||||
|
||||
for robot in clone.iter() {
|
||||
if robot.p.1 == last_y && robot.p.0 == last_x + 1 {
|
||||
current_cons += 1;
|
||||
} else {
|
||||
current_cons = 1
|
||||
}
|
||||
last_x = robot.p.0;
|
||||
last_y = robot.p.1;
|
||||
|
||||
if current_cons >= required_cons {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn solve_part2(part2: &mut Day14Part2) -> Result<u64, AdventError> {
|
||||
for i in 0 .. u64::MAX {
|
||||
if suspected_image(part2, 10) {
|
||||
return Ok(i);
|
||||
}
|
||||
for robot in part2.robots.iter_mut() {
|
||||
robot.apply(part2.width, part2.height);
|
||||
}
|
||||
}
|
||||
Err(AdventError("This should never happen.".to_string()))
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[advent_day(Day14Part1, Day14Part2)]
|
||||
struct Day14;
|
||||
@@ -19,4 +19,6 @@ pub mod day1;
|
||||
pub mod day2;
|
||||
pub mod day3;
|
||||
pub mod day4;
|
||||
pub mod day5;
|
||||
pub mod day5;
|
||||
|
||||
pub mod day14;
|
||||
32
src/main.rs
32
src/main.rs
@@ -5,6 +5,7 @@ mod input;
|
||||
|
||||
use std::env;
|
||||
use day1::Day1;
|
||||
use day14::Day14;
|
||||
use day2::Day2;
|
||||
use day3::Day3;
|
||||
use day4::Day4;
|
||||
@@ -13,6 +14,26 @@ use day5::Day5;
|
||||
use crate::error::AdventError;
|
||||
use crate::days::*;
|
||||
|
||||
struct DummyDay {
|
||||
|
||||
}
|
||||
|
||||
impl DummyDay {
|
||||
fn new() -> Self {
|
||||
Self{}
|
||||
}
|
||||
}
|
||||
|
||||
impl AdventDay for DummyDay {
|
||||
fn puzzle1(&mut self) -> Result<u64, AdventError> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn puzzle2(&mut self) -> Result<u64, AdventError> {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), AdventError> {
|
||||
|
||||
let mut advent_days: Vec<Box::<dyn AdventDay>> = vec!(
|
||||
@@ -20,7 +41,16 @@ fn main() -> Result<(), AdventError> {
|
||||
Box::new(Day2::new()),
|
||||
Box::new(Day3::new()),
|
||||
Box::new(Day4::new()),
|
||||
Box::new(Day5::new())
|
||||
Box::new(Day5::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(DummyDay::new()),
|
||||
Box::new(Day14::new()),
|
||||
);
|
||||
|
||||
if env::args().len() == 1 {
|
||||
|
||||
Reference in New Issue
Block a user