-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopen_the_lock_752.rs
executable file
·103 lines (86 loc) · 2.76 KB
/
open_the_lock_752.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::collections::HashSet;
use std::collections::VecDeque;
use crate::Solution;
impl Solution {
pub fn open_lock(deadends: Vec<String>, target: String) -> i32 {
//wait lets get our starting state first actually:
let mut state = Lock::new("0000");
let target = Lock::new(target.as_str());
let mut ignore: HashSet<Lock> = deadends.iter().map(|dead| Lock::new(dead)).collect();
let mut visited: HashSet<Lock> = HashSet::new();
if ignore.contains(&target) || ignore.contains(&state) {
return -1;
}
if target == state {
return 0;
}
let mut q: VecDeque<(Lock, i32)> = VecDeque::new();
q.push_back((state, 0));
while !q.is_empty() {
let cur = q.pop_front().unwrap();
if visited.contains(&cur.0) {
continue;
}
visited.insert(cur.0.clone());
if cur.0 == target {
//for elem in visited{
// println!("{:?}", elem);
//}
return cur.1;
}
for nxt in cur.0.next() {
if !visited.contains(&nxt) && !ignore.contains(&nxt) {
q.push_back((nxt, cur.1 + 1));
}
if ignore.contains(&nxt) {
}
}
}
//Constraints say that starting state could be a deadend
-1
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
struct Lock {
//let me cook
state: [i8; 4],
}
impl Lock {
fn new(state: &str) -> Self {
//RAHHHHHH I LOVE ITERATORS RAHHHHHHHHHHH
//for i in state.parse().unwrap().into_iter() {
// lock.state[i] = i;
//} nvm
let state = state.as_bytes();
return Lock {
state: [
(state[0] - '0' as u8) as i8,
(state[1] - '0' as u8) as i8,
(state[2] - '0' as u8) as i8,
(state[3] - '0' as u8) as i8,
],
};
}
fn default() -> Self {
Lock { state: [0; 4] }
}
/// Returns the next possible states of the lock
fn next(&self) -> Vec<Lock> {
let mut out = Vec::new();
for i in 0..4 {
let mut next = self.clone();
next.state[i] = (next.state[i] + 1) % 10;
out.push(next);
//consider the inverse (going down by 1)
let mut next = self.clone();
if next.state[i] - 1 < 0 {
next.state[i] = 9;
} else {
next.state[i] -= 1;
}
//we get all instances now forward and back spinning of the wheel
out.push(next);
}
out
}
}