[TASK] Solved Day 17 pt 1
This commit is contained in:
1
input/day17.txt
Normal file
1
input/day17.txt
Normal file
File diff suppressed because one or more lines are too long
1
input/day17_example.txt
Normal file
1
input/day17_example.txt
Normal file
@@ -0,0 +1 @@
|
||||
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||
148
src/day17.rs
Normal file
148
src/day17.rs
Normal file
@@ -0,0 +1,148 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
use lazy_static::lazy_static;
|
||||
use crate::day_solver::DaySolver;
|
||||
use crate::util::{Coord, Grid};
|
||||
|
||||
use super::util;
|
||||
|
||||
pub struct Day17 {
|
||||
jet_pattern: Vec<char>
|
||||
}
|
||||
|
||||
impl Day17 {
|
||||
|
||||
pub fn create() -> Self {
|
||||
// let lines = util::read_file("input/day17_example.txt");
|
||||
let lines = util::read_file("input/day17.txt");
|
||||
|
||||
// Put the input into the day struct
|
||||
return Day17 {
|
||||
jet_pattern: lines.first().unwrap().chars().collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn rock_can_occupy_pos(&self, rock: &Grid<bool>, pos: &Coord<usize>, grid: &Grid<CaveCell>) -> bool {
|
||||
|
||||
if rock.width + pos.x > grid.width {
|
||||
return false;
|
||||
}
|
||||
|
||||
for y in 0..rock.height() {
|
||||
for x in 0..rock.width {
|
||||
if rock.get(&x, &y) == &true && grid.get(&(x + pos.x), &(pos.y + y)) == &CaveCell::Rock {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl DaySolver for Day17 {
|
||||
|
||||
|
||||
fn solve_part1(&mut self) -> String {
|
||||
|
||||
let mut cave = Grid {
|
||||
data: vec![CaveCell::Empty; 7 * 2022 * 4],
|
||||
width: 7
|
||||
};
|
||||
|
||||
let mut cur_spawn_height = 3;
|
||||
let mut jet_iter = self.jet_pattern.iter().cycle();
|
||||
for i in 0..2022 {
|
||||
// Spawn the rock
|
||||
let Some(rock) = ROCK_SHAPES.get(i % ROCK_SHAPES.len()) else { panic!("Can't find rock {}", i % ROCK_SHAPES.len())};
|
||||
// The rock_pos is the bottom-left corner of the rock
|
||||
let mut rock_pos = Coord::new(2, cur_spawn_height);
|
||||
loop {
|
||||
match jet_iter.next() {
|
||||
Some('>') => {
|
||||
let next_pos = Coord::new(rock_pos.x + 1, rock_pos.y);
|
||||
if self.rock_can_occupy_pos(rock, &next_pos, &cave) {
|
||||
rock_pos = next_pos;
|
||||
}
|
||||
}
|
||||
Some('<') => {
|
||||
if rock_pos.x > 0 {
|
||||
let next_pos = Coord::new(rock_pos.x - 1, rock_pos.y);
|
||||
if self.rock_can_occupy_pos(rock, &next_pos, &cave) {
|
||||
rock_pos = next_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
m => { panic!("Unknown rock movement: {}...", m.unwrap_or(&'?')); }
|
||||
}
|
||||
|
||||
// Now we move the rock down
|
||||
if rock_pos.y == 0 {
|
||||
break;
|
||||
}
|
||||
let next_pos = Coord::new(rock_pos.x, rock_pos.y - 1);
|
||||
if self.rock_can_occupy_pos(rock, &next_pos, &cave) {
|
||||
rock_pos = next_pos;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// place the rock
|
||||
for y in 0..rock.height() {
|
||||
for x in 0..rock.width {
|
||||
if rock.get(&x, &y) == &true {
|
||||
cave.set(&(rock_pos.x + x), &(rock_pos.y + y), CaveCell::Rock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_spawn_height = cur_spawn_height.max(rock_pos.y + rock.height() + 3);
|
||||
|
||||
}
|
||||
cave.print_range(0, 7, 0, 40);
|
||||
return (cur_spawn_height-3).to_string();
|
||||
}
|
||||
|
||||
fn solve_part2(&mut self) -> String {
|
||||
return 0.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref ROCK_SHAPES: Vec<Grid<bool>> = vec![
|
||||
Grid { data: vec![
|
||||
true, true, true, true],
|
||||
width: 4},
|
||||
Grid { data: vec![
|
||||
false, true, false,
|
||||
true, true, true,
|
||||
false, true, false],
|
||||
width: 3},
|
||||
Grid {data: vec![
|
||||
true, true, true,
|
||||
false, false, true,
|
||||
false, false, true,
|
||||
], width: 3},
|
||||
Grid { data: vec![
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true], width: 1},
|
||||
Grid { data: vec![
|
||||
true, true,
|
||||
true, true],
|
||||
width: 2 },
|
||||
];
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
enum CaveCell {
|
||||
Rock, Empty
|
||||
}
|
||||
|
||||
impl Display for CaveCell {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
CaveCell::Rock => write!(f, "#"),
|
||||
CaveCell::Empty => write!(f, ".")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
extern crate core;
|
||||
|
||||
use std::time::Instant;
|
||||
use crate::day1::Day1;
|
||||
use crate::day2::Day2;
|
||||
@@ -15,6 +17,7 @@ use crate::day13::Day13;
|
||||
use crate::day14::Day14;
|
||||
use crate::day15::Day15;
|
||||
use crate::day16::Day16;
|
||||
use crate::day17::Day17;
|
||||
use crate::day_solver::DaySolver;
|
||||
|
||||
mod util;
|
||||
@@ -35,8 +38,9 @@ mod day13;
|
||||
mod day14;
|
||||
mod day15;
|
||||
mod day16;
|
||||
mod day17;
|
||||
|
||||
const MAX_DAY: u8 = 15;
|
||||
const MAX_DAY: u8 = 17;
|
||||
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
|
||||
|
||||
fn main() {
|
||||
@@ -116,6 +120,7 @@ fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
|
||||
14 => Some(Box::new(Day14::create())),
|
||||
15 => Some(Box::new(Day15::create())),
|
||||
16 => Some(Box::new(Day16::create())),
|
||||
17 => Some(Box::new(Day17::create())),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,12 @@ pub struct Coord<T> where T: Sized {
|
||||
pub y: T
|
||||
}
|
||||
|
||||
impl<T> Coord<T> where T: Sized {
|
||||
pub(crate) fn new(x: T, y: T) -> Self {
|
||||
Coord { x, y }
|
||||
}
|
||||
}
|
||||
|
||||
impl <T> Coord<T> where T: Integer + Copy {
|
||||
pub fn manhattan_dist(&self, other: &Coord<T>) -> T {
|
||||
self.x.max(other.x).sub(self.x.min(other.x)) + self.y.max(other.y).sub(self.y.min(other.y))
|
||||
|
||||
Reference in New Issue
Block a user