Finished day 14 advent of code
This commit is contained in:
150
advent_of_code/2022/14/src/main.rs
Normal file
150
advent_of_code/2022/14/src/main.rs
Normal file
@@ -0,0 +1,150 @@
|
||||
use std::{cmp::min, cmp::max, collections::{HashSet, HashMap}};
|
||||
use nom::{
|
||||
IResult,
|
||||
multi::separated_list1,
|
||||
character::complete::{self, multispace1},
|
||||
sequence::separated_pair,
|
||||
bytes::complete::tag,
|
||||
};
|
||||
|
||||
fn parse_input(input: &str) -> IResult<&str, Vec<Vec<(u32, u32)>>> {
|
||||
let (input, result) = separated_list1(
|
||||
multispace1,
|
||||
separated_list1(
|
||||
tag(" -> "),
|
||||
separated_pair(complete::u32, tag(","), complete::u32)
|
||||
)
|
||||
)(input)?;
|
||||
|
||||
Ok((input, result))
|
||||
}
|
||||
|
||||
fn print_coords(coords: &Vec<Vec<(u32, u32)>>) {
|
||||
for line in coords {
|
||||
for (c1, c2) in line {
|
||||
print!("{c1},{c2} -> ");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
fn coords_to_map(coords: &Vec<Vec<(u32, u32)>>) -> (HashSet<(u32, u32)>, u32) {
|
||||
let mut result = HashSet::new();
|
||||
let mut lowest_tile = 0;
|
||||
|
||||
for rock in coords {
|
||||
for i in 0..rock.len() - 1 {
|
||||
let start = rock[i];
|
||||
let end = rock[i+1];
|
||||
|
||||
lowest_tile = max(max(lowest_tile, start.1), end.1);
|
||||
|
||||
if start.0 == end.0 {
|
||||
let x = start.0;
|
||||
|
||||
let y_start = min(start.1, end.1);
|
||||
let y_end = max(start.1, end.1);
|
||||
|
||||
for y in y_start..=y_end {
|
||||
result.insert((x, y));
|
||||
}
|
||||
} else {
|
||||
let y = start.1;
|
||||
|
||||
let x_start = min(start.0, end.0);
|
||||
let x_end = max(start.0, end.0);
|
||||
|
||||
for x in x_start..=x_end {
|
||||
result.insert((x,y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(result, lowest_tile)
|
||||
}
|
||||
|
||||
fn fill_cave(cave_map: &mut HashSet<(u32, u32)>, lowest_tile: u32) -> bool {
|
||||
let mut cur = (500, 0);
|
||||
|
||||
loop {
|
||||
if cur.1 > lowest_tile {
|
||||
return false;
|
||||
}
|
||||
|
||||
if !cave_map.contains(&(cur.0, cur.1 + 1)) {
|
||||
cur = (cur.0, cur.1 + 1);
|
||||
continue;
|
||||
}
|
||||
else if !cave_map.contains(&(cur.0 - 1, cur.1 + 1)) {
|
||||
cur = (cur.0 - 1, cur.1 + 1);
|
||||
continue;
|
||||
}
|
||||
else if !cave_map.contains(&(cur.0 + 1, cur.1 + 1)) {
|
||||
cur = (cur.0 + 1, cur.1 + 1);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
cave_map.insert(cur);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fill_cave_with_floor(cave_map: &mut HashSet<(u32, u32)>, lowest_tile: u32) -> (u32, u32) {
|
||||
let mut cur = (500, 0);
|
||||
|
||||
loop {
|
||||
if cur.1 == lowest_tile + 1 {
|
||||
cave_map.insert(cur);
|
||||
return cur;
|
||||
}
|
||||
else if !cave_map.contains(&(cur.0, cur.1 + 1)) {
|
||||
cur = (cur.0, cur.1 + 1);
|
||||
continue;
|
||||
}
|
||||
else if !cave_map.contains(&(cur.0 - 1, cur.1 + 1)) {
|
||||
cur = (cur.0 - 1, cur.1 + 1);
|
||||
continue;
|
||||
}
|
||||
else if !cave_map.contains(&(cur.0 + 1, cur.1 + 1)) {
|
||||
cur = (cur.0 + 1, cur.1 + 1);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
cave_map.insert(cur);
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let input_text = include_str!("../input.txt");
|
||||
let (_rest, coord_lines) = parse_input(input_text).unwrap();
|
||||
|
||||
// Test parsing
|
||||
// print_coords(&coord_lines);
|
||||
|
||||
let (mut cave_map, lowest_tile) = coords_to_map(&coord_lines);
|
||||
|
||||
let mut units_of_sand = 0;
|
||||
loop {
|
||||
if !fill_cave(&mut cave_map, lowest_tile) {
|
||||
break;
|
||||
}
|
||||
units_of_sand += 1;
|
||||
}
|
||||
|
||||
println!("Units of sand needed: {units_of_sand}");
|
||||
|
||||
units_of_sand = 1;
|
||||
let (mut cave_map, _) = coords_to_map(&coord_lines);
|
||||
loop {
|
||||
if fill_cave_with_floor(&mut cave_map, lowest_tile) == (500, 0) {
|
||||
break;
|
||||
}
|
||||
units_of_sand += 1;
|
||||
}
|
||||
|
||||
println!("Units of sand needed with infinite length floor: {units_of_sand}");
|
||||
}
|
||||
Reference in New Issue
Block a user