update day10
This commit is contained in:
190
src/day10.rs
Normal file
190
src/day10.rs
Normal file
@@ -0,0 +1,190 @@
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
#[aoc_generator(day10)]
|
||||
fn parse(input: &str) -> ((usize, usize), Vec<Vec<Vec<Direction>>>) {
|
||||
let input: Vec<_> = input.split('\n')
|
||||
.map(|line| {
|
||||
line.chars()
|
||||
.map(|char| {
|
||||
match char {
|
||||
'|' => vec![Direction::North, Direction::South],
|
||||
'-' => vec![Direction::East, Direction::West],
|
||||
'L' => vec![Direction::North, Direction::East],
|
||||
'J' => vec![Direction::North, Direction::West],
|
||||
'7' => vec![Direction::South, Direction::West],
|
||||
'F' => vec![Direction::South, Direction::East],
|
||||
'.' => vec![],
|
||||
'S' => vec![Direction::Start],
|
||||
_ => panic!("Invalid pipe char")
|
||||
}
|
||||
}).collect::<Vec<_>>()
|
||||
}).collect();
|
||||
|
||||
let start = find_start(&input);
|
||||
|
||||
(start, input)
|
||||
}
|
||||
|
||||
fn find_start(input: &Vec<Vec<Vec<Direction>>>) -> (usize, usize) {
|
||||
let mut start_point: Option<(usize, usize)> = None;
|
||||
for i in 0..input.len() {
|
||||
for j in 0..input[0].len() {
|
||||
if input[i][j].contains(&Direction::Start) {
|
||||
start_point = Some((i,j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match start_point {
|
||||
Some(x) => x,
|
||||
None => panic!("No start point found! AHHHHH")
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc(day10, part1)]
|
||||
fn part1((start, input): &((usize, usize), Vec<Vec<Vec<Direction>>>)) -> i32 {
|
||||
let mut start_dirs: Vec<Direction> = vec![];
|
||||
for dir in Direction::iter().filter(|x| x != &Direction::Start) {
|
||||
let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0));
|
||||
if x < 0 || y < 0 {
|
||||
continue;
|
||||
}
|
||||
let neibhor = &input[x as usize][y as usize];
|
||||
if neibhor.contains(&dir.reverse()) {
|
||||
start_dirs.push(dir);
|
||||
}
|
||||
}
|
||||
|
||||
let mut finished = false;
|
||||
let mut count = 1;
|
||||
|
||||
let mut first_pre = start_dirs[0].reverse();
|
||||
let mut second_pre = start_dirs[1].reverse();
|
||||
let mut first_pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize);
|
||||
let mut second_pos = ((start.0 as i32 + start_dirs[1].to_ind().1) as usize, (start.1 as i32 + start_dirs[1].to_ind().0) as usize);
|
||||
|
||||
while !finished {
|
||||
let first_next = &input[first_pos.0][first_pos.1].iter().filter(|x| x != &&first_pre).next().unwrap();
|
||||
first_pos = ((first_pos.0 as i32 + first_next.to_ind().1) as usize, (first_pos.1 as i32 + first_next.to_ind().0) as usize);
|
||||
first_pre = first_next.reverse();
|
||||
|
||||
let second_next = &input[second_pos.0][second_pos.1].iter().filter(|x| x != &&second_pre).next().unwrap();
|
||||
second_pos = ((second_pos.0 as i32 + second_next.to_ind().1) as usize, (second_pos.1 as i32 + second_next.to_ind().0) as usize);
|
||||
second_pre = second_next.reverse();
|
||||
|
||||
count += 1;
|
||||
finished = first_pos == second_pos;
|
||||
|
||||
}
|
||||
|
||||
count
|
||||
}
|
||||
|
||||
#[aoc(day10, part2)]
|
||||
fn part2((start, input): &((usize, usize), Vec<Vec<Vec<Direction>>>)) -> i64 {
|
||||
let mut start_dirs: Vec<Direction> = vec![];
|
||||
for dir in Direction::iter().filter(|x| x != &Direction::Start) {
|
||||
let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0));
|
||||
if x < 0 || y < 0 {
|
||||
continue;
|
||||
}
|
||||
let neibhor = &input[x as usize][y as usize];
|
||||
if neibhor.contains(&dir.reverse()) {
|
||||
start_dirs.push(dir);
|
||||
}
|
||||
}
|
||||
|
||||
let mut finished = false;
|
||||
|
||||
let mut pre = start_dirs[0].reverse();
|
||||
let mut pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize);
|
||||
|
||||
let mut the_loop = vec![*start, pos];
|
||||
let mut area = 0;
|
||||
|
||||
while !finished {
|
||||
let first_next = &input[pos.0][pos.1].iter().filter(|x| x != &&pre).next().unwrap();
|
||||
pos = ((pos.0 as i32 + first_next.to_ind().1) as usize, (pos.1 as i32 + first_next.to_ind().0) as usize);
|
||||
pre = first_next.reverse();
|
||||
|
||||
finished = pos == *start;
|
||||
the_loop.push(pos);
|
||||
}
|
||||
|
||||
|
||||
for win in the_loop.windows(2) {
|
||||
area += (win[0].1 * win[1].0) as i64;
|
||||
area -= (win[0].0 * win[1].1) as i64;
|
||||
}
|
||||
let area = i64::abs(area) / 2;
|
||||
|
||||
let spaces = area - (the_loop.len() as i64 / 2) + 1;
|
||||
|
||||
spaces
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, EnumIter)]
|
||||
enum Direction {
|
||||
North,
|
||||
South,
|
||||
East,
|
||||
West,
|
||||
Start
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
pub fn to_ind(&self) -> (i32, i32) {
|
||||
match self {
|
||||
Direction::North => (0,-1),
|
||||
Direction::South => (0,1),
|
||||
Direction::East => (1,0),
|
||||
Direction::West => (-1,0),
|
||||
Direction::Start => panic!("Start should never be converted to an index. AHH"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reverse(&self) -> Direction {
|
||||
match self {
|
||||
Direction::North => Direction::South,
|
||||
Direction::South => Direction::North,
|
||||
Direction::East => Direction::West,
|
||||
Direction::West => Direction::East,
|
||||
Direction::Start => panic!("Start should never be reversed. AHH"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const EX: &str = r"7-F7-
|
||||
.FJ|7
|
||||
SJLL7
|
||||
|F--J
|
||||
LJ.LJ";
|
||||
|
||||
const EX_2: &str = r".F----7F7F7F7F-7....
|
||||
.|F--7||||||||FJ....
|
||||
.||.FJ||||||||L7....
|
||||
FJL7L7LJLJ||LJ.L-7..
|
||||
L--J.L7...LJS7F-7L7.
|
||||
....F-J..F7FJ|L7L7L7
|
||||
....L7.F7||L7|.L7L7|
|
||||
.....|FJLJ|FJ|F7|.LJ
|
||||
....FJL-7.||.||||...
|
||||
....L---J.LJ.LJLJ...";
|
||||
|
||||
#[test]
|
||||
fn part1_example() {
|
||||
assert_eq!(part1(&parse(EX)), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example() {
|
||||
assert_eq!(part2(&parse(EX_2)), 8);
|
||||
}
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
mod day10;
|
||||
mod day9;
|
||||
mod day8;
|
||||
mod day7;
|
||||
|
Reference in New Issue
Block a user