1
0

Compare commits

..

4 Commits

Author SHA1 Message Date
8157a9bf7e clippy 2024-12-06 06:36:58 +01:00
53854a13f4 day 6 part 2 2024-12-06 06:30:02 +01:00
f632977666 day 6 part 1 2024-12-06 06:20:41 +01:00
8cf59c3725 prepare day 6 2024-12-05 19:14:31 +01:00
3 changed files with 139 additions and 0 deletions

137
src/day06.rs Normal file
View File

@@ -0,0 +1,137 @@
use std::{
collections::{HashMap, HashSet},
fs::read_to_string,
};
pub fn day_main() {
let input = read_to_string("input/day06.txt").unwrap();
let input = input.trim();
println!(" part1: {}", part1(input));
println!(" part2: {}", part2(input));
}
type RiddleResult = usize;
type Point = (i32, i32);
fn part1(input: &str) -> RiddleResult {
let (m, mut pos, _) = parse(input);
let mut dir = '^';
let mut visited = HashSet::new();
while m.contains_key(&pos) {
let (x, y) = pos;
visited.insert(pos);
let next = match dir {
'^' => (x, y - 1),
'v' => (x, y + 1),
'<' => (x - 1, y),
'>' => (x + 1, y),
_ => unreachable!(),
};
if let Some('#') = m.get(&next) {
dir = match dir {
'^' => '>',
'v' => '<',
'<' => '^',
'>' => 'v',
_ => unreachable!("asdf"),
};
} else {
pos = next;
}
}
visited.len()
}
fn part2(input: &str) -> RiddleResult {
let (m, pos, opens) = parse(input);
let dir = '^';
opens
.into_iter()
.filter(|open| {
let mut m = m.clone();
m.insert(*open, '#');
is_loop(m, pos, dir)
})
.count()
}
fn parse(input: &str) -> (HashMap<Point, char>, Point, HashSet<Point>) {
let mut m = HashMap::new();
let mut pos = None;
let mut opens = HashSet::new();
input.lines().enumerate().for_each(|(y, line)| {
line.char_indices().for_each(|(x, c)| {
let x = x as i32;
let y = y as i32;
if c == '^' {
pos = Some((x, y));
m.insert((x, y), '.');
} else {
m.insert((x, y), c);
}
if c == '.' {
opens.insert((x, y));
}
});
});
(m, pos.unwrap(), opens)
}
fn is_loop(m: HashMap<Point, char>, mut pos: Point, mut dir: char) -> bool {
let mut visited = HashSet::new();
while m.contains_key(&pos) {
let (x, y) = pos;
if visited.contains(&(pos, dir)) {
return true;
}
visited.insert((pos, dir));
let next = match dir {
'^' => (x, y - 1),
'v' => (x, y + 1),
'<' => (x - 1, y),
'>' => (x + 1, y),
_ => unreachable!(),
};
if let Some('#') = m.get(&next) {
dir = match dir {
'^' => '>',
'v' => '<',
'<' => '^',
'>' => 'v',
_ => unreachable!("asdf"),
};
} else {
pos = next;
}
}
false
}
#[cfg(test)]
mod test {
use super::{part1, part2};
const TEST_INPUT: &str = r"....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...
";
#[test]
fn test1() {
assert_eq!(part1(TEST_INPUT), 41);
}
#[test]
fn test2() {
assert_eq!(part2(TEST_INPUT), 6);
}
}

View File

@@ -3,3 +3,4 @@ pub mod day02;
pub mod day03;
pub mod day04;
pub mod day05;
pub mod day06;

View File

@@ -10,6 +10,7 @@ fn main() {
(3, day03::day_main),
(4, day04::day_main),
(5, day05::day_main),
(6, day06::day_main),
]);
let day: Option<u8> = args().nth(1).and_then(|a| a.parse().ok());
let Some(day) = day else {