Day 17 - task 1
This commit is contained in:
parent
052e381611
commit
b40956f6f7
2 changed files with 176 additions and 2 deletions
1
res/17/test-input.txt
Normal file
1
res/17/test-input.txt
Normal file
|
@ -0,0 +1 @@
|
|||
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
177
src/days/d17.rs
177
src/days/d17.rs
|
@ -1,12 +1,22 @@
|
|||
use std::fs;
|
||||
|
||||
const WIDTH: usize = 7;
|
||||
const _TOTAL_ROCK_NUM: i64 = 2022;
|
||||
|
||||
pub fn solve() {
|
||||
let path = "res/17/input.txt";
|
||||
|
||||
let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
|
||||
|
||||
// constant definition of rocks, from bottom to top
|
||||
let rocks: Vec<Vec<(u8,u8)>> = vec![
|
||||
vec![(0,0),(0,1),(0,2),(0,3)],
|
||||
vec![(0,1),(1,0),(1,1),(1,2),(2,1)],
|
||||
vec![(0,0),(0,1),(0,2),(1,2),(2,2)],
|
||||
vec![(0,0),(1,0),(2,0),(3,0)],
|
||||
vec![(0,0),(0,1),(1,0),(1,1)]
|
||||
];
|
||||
|
||||
let directions: Vec<Dir> = contents
|
||||
.chars()
|
||||
.filter(|c| *c != '\n')
|
||||
|
@ -17,11 +27,174 @@ pub fn solve() {
|
|||
})
|
||||
.collect();
|
||||
|
||||
// [width][height]
|
||||
let chamber = vec![Vec::<bool>::new(); WIDTH];
|
||||
// [height][width]
|
||||
let mut chamber = vec![vec![false;WIDTH];4];
|
||||
|
||||
let mut highest_rock = -1; // floor
|
||||
|
||||
let mut dir_iter = directions.iter();
|
||||
|
||||
let mut heights = Vec::<i64>::new();
|
||||
|
||||
|
||||
/*
|
||||
51 rocks
|
||||
|
||||
heights[50] - heights[15]
|
||||
|
||||
|
||||
(1_000_000_000_000 - 16) = 999_999_999_984
|
||||
%
|
||||
*/
|
||||
|
||||
|
||||
|
||||
for i in 0..2344 {
|
||||
// spawn new rock
|
||||
let r_index = i as usize % rocks.len(); // get current rock index
|
||||
let mut rock = Rock::new(&rocks[r_index], highest_rock);
|
||||
|
||||
|
||||
while chamber.iter().filter(|row| !row.contains(&true)).count() < 7 {
|
||||
chamber.push(vec![false;WIDTH])
|
||||
}
|
||||
|
||||
loop {
|
||||
// move to left or right
|
||||
let next_dir = dir_iter.next();
|
||||
let dir = match next_dir {
|
||||
Some(x) => { x },
|
||||
None => {
|
||||
dir_iter = directions.iter();
|
||||
dir_iter.next().unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
match *dir {
|
||||
Dir::Left => {
|
||||
if rock.left().valid_pos(&chamber) {
|
||||
rock = rock.left()
|
||||
}
|
||||
},
|
||||
Dir::Right => {
|
||||
if rock.right().valid_pos(&chamber) {
|
||||
rock = rock.right()
|
||||
}
|
||||
}
|
||||
}
|
||||
// move down
|
||||
if rock.down().valid_pos(&chamber) {
|
||||
rock = rock.down();
|
||||
} else {
|
||||
rock.pos.iter().for_each(|coord| {
|
||||
chamber[coord.0 as usize][coord.1 as usize] = true
|
||||
});
|
||||
highest_rock = match chamber
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|row| row.1.contains(&true))
|
||||
.last() {
|
||||
Some(x) => x.0 as i64,
|
||||
None => -1
|
||||
};
|
||||
// find recurring patterns in amount of rocks and height
|
||||
heights.push(highest_rock);
|
||||
//for i in 2..heights.len() {
|
||||
// test(i, &heights)
|
||||
//}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("Result 1: {}", highest_rock+1);
|
||||
}
|
||||
|
||||
fn test(n: usize, heights: &Vec<i64>) {
|
||||
if heights.len() % n == 0
|
||||
&& heights[heights.len()/n-1]*n as i64+n as i64 == heights[heights.len()-1]+1 {
|
||||
println!("{}: {}", n, heights.len()/n)
|
||||
}
|
||||
}
|
||||
|
||||
fn _print_chamber(chamber: &Vec<Vec<bool>>, curr_rock: &Rock) {
|
||||
let mut str_chamber: Vec<Vec<char>> = chamber.iter().map(|line| line.iter().map(|elem|
|
||||
match *elem {
|
||||
true => '#',
|
||||
false => '.'
|
||||
}
|
||||
).collect()).collect();
|
||||
|
||||
curr_rock.pos.iter().for_each(|pos| { str_chamber[pos.0 as usize][pos.1 as usize] = '@'; });
|
||||
|
||||
str_chamber.iter().rev().for_each(|str| println!("{}",str.iter().collect::<String>()))
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Dir {
|
||||
Right,
|
||||
Left,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Rock {
|
||||
pos: Vec<(i64,i64)>
|
||||
}
|
||||
|
||||
impl Rock {
|
||||
pub fn new(rock: &Vec<(u8,u8)>, highest_rock: i64) -> Self{
|
||||
let pos: Vec<(i64,i64)> = rock
|
||||
.iter()
|
||||
.map(|coord| {
|
||||
(coord.0 as i64 + (highest_rock + 4) as i64, coord.1 as i64 + 2)
|
||||
})
|
||||
.collect();
|
||||
Rock { pos }
|
||||
}
|
||||
|
||||
pub fn right(&self) -> Self {
|
||||
for coord in self.pos.iter() {
|
||||
if coord.1 >= (WIDTH-1) as i64 {
|
||||
return self.clone()
|
||||
}
|
||||
}
|
||||
Rock {
|
||||
pos: self.pos.iter().map(|coord| {
|
||||
(coord.0, coord.1 + 1) // move right, only check for wall !
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn left(&self) -> Self {
|
||||
for coord in self.pos.iter() {
|
||||
if coord.1 <= 0 {
|
||||
return self.clone()
|
||||
}
|
||||
}
|
||||
Rock {
|
||||
pos: self.pos.iter().map(|coord| {
|
||||
(coord.0, coord.1 - 1) // move left, only check for wall !
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn down(&self) -> Self {
|
||||
Rock {
|
||||
pos: self.pos.iter().map(|coord| {
|
||||
(coord.0 - 1, coord.1) // move down
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn valid_pos(&self, chamber: &Vec<Vec<bool>>) -> bool {
|
||||
for coord in &self.pos {
|
||||
if coord.0 < 0 || coord.1 < 0 {
|
||||
return false
|
||||
}
|
||||
if chamber[coord.0 as usize][coord.1 as usize] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue