diff --git a/res/17/test-input.txt b/res/17/test-input.txt new file mode 100644 index 0000000..fb5d89e --- /dev/null +++ b/res/17/test-input.txt @@ -0,0 +1 @@ +>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>> \ No newline at end of file diff --git a/src/days/d17.rs b/src/days/d17.rs index 312a143..719662d 100644 --- a/src/days/d17.rs +++ b/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![ + 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 = contents .chars() .filter(|c| *c != '\n') @@ -17,11 +27,174 @@ pub fn solve() { }) .collect(); - // [width][height] - let chamber = vec![Vec::::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::::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) { + 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>, curr_rock: &Rock) { + let mut str_chamber: Vec> = 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::())) +} + +#[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>) -> 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 + } +} \ No newline at end of file