-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
83 lines (69 loc) · 2.08 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use std::cmp::max;
use std::collections::HashSet;
type P = (i64, i64);
fn check_guard_path(walls: &HashSet<P>, mut pos: P, size: P) -> Option<HashSet<P>> {
let (maxx, maxy) = size;
let directions = [(0, -1), (1, 0), (0, 1), (-1, 0)];
let mut direction = 0;
let mut visited: HashSet<(usize, P)> = HashSet::new();
loop {
let (curx, cury) = pos;
if curx <0 || cury < 0 || curx > maxx || cury > maxy {
break;
}
let is_new = visited.insert((direction, pos));
if !is_new {
return None
}
let (dx, dy) = directions[direction];
let (nx, ny) = (curx + dx, cury + dy);
let newpos = (nx, ny);
if walls.contains(&newpos) {
direction += 1;
} else{
pos = newpos;
}
direction %= directions.len();
}
let visited= visited.iter().map(|x| x.1).collect();
Some(visited)
}
fn main() {
let mut pos: P = (0, 0);
let mut walls: HashSet<P> = HashSet::new();
let mut maxx = 0;
let mut maxy = 0;
include_str!("./input.txt")
.trim()
.split('\n')
.enumerate()
.for_each(|(y, s)| {
s.trim().chars().enumerate().for_each(|(x, c)| {
let x = x as i64;
let y = y as i64;
maxx = max(maxx, x);
maxy = max(maxy, y);
match c {
'^' => pos = (x, y),
'#' => {
walls.insert((x,y));
()
}
_ => (),
}
})
});
let part1 = check_guard_path(&walls, pos, (maxx, maxy)).unwrap();
println!("part1: {}", part1.len());
let mut part2 = 0;
// try to lock each pos and check loop
for (x, y) in part1 {
walls.insert((x,y));
let res = check_guard_path(&walls, pos, (maxx, maxy));
if res.is_none() {
part2 += 1;
}
walls.remove(&(x, y));
}
println!("part2: {}", part2);
}