1
2pub struct DFS<
3 'a,
4 C,
5 O: Copy,
6 T: FnOnce(&mut C, O),
7 U: FnMut(&mut C, O),
8 V: FnOnce(&C) -> bool,
9 W: FnOnce(&C) -> X,
10 X: IntoIterator<Item = O>,
11> {
12 status: &'a mut C,
13 forward: T,
14 back_tracking: U,
15 check: V,
16 get_all_ops: W,
17 op: O,
18}
19impl<
20 'a,
21 C: std::fmt::Debug,
22 O: Copy,
23 T: Copy + FnOnce(&mut C, O),
24 U: Copy + FnMut(&mut C, O),
25 V: Copy + FnOnce(&C) -> bool,
26 W: Copy + FnOnce(&C) -> X,
29 X: IntoIterator<Item = O>,
30 > DFS<'a, C, O, T, U, V, W, X>
31{
32 pub fn new(
33 status: &'a mut C,
34 forward: T,
35 back_tracking: U,
36 check: V,
37 get_all_ops: W,
38 op: O,
39 ) -> Self {
40 Self {
41 status,
42 forward,
43 back_tracking,
44 check,
45 get_all_ops,
46 op,
47 }
48 }
49 pub fn dfs<'b>(&'b mut self)
50 where
51 'a: 'b,
52 {
53 if (self.check)(self.status) {
54 return;
55 }
56 for op in (self.get_all_ops)(self.status) {
57 let mut next = self.forward(op);
58 next.op = op;
59 next.dfs();
60 }
61 }
62 pub fn dfs_early_stop<'b>(&'b mut self) -> bool
63 where
64 'a: 'b,
65 {
66 if (self.check)(self.status) {
67 return true;
68 }
69 for op in (self.get_all_ops)(self.status) {
70 let mut next = self.forward(op);
71 next.op = op;
72 if next.dfs_early_stop() {
73 return true;
74 }
75 }
76 false
77 }
78 pub fn forward<'b: 'c, 'c>(&'b mut self, op: O) -> DFS<'b, C, O, T, U, V, W, X>
79 where
80 'b: 'c,
81 {
82 (self.forward)(self.status, op);
83 DFS {
84 status: self.status,
85 forward: self.forward,
86 back_tracking: self.back_tracking,
87 check: self.check,
88 get_all_ops: self.get_all_ops,
89 op,
90 }
91 }
92}
93impl<
94 'a,
95 C,
96 O: Copy,
97 T: FnOnce(&mut C, O),
98 U: FnMut(&mut C, O),
99 V: FnOnce(&C) -> bool,
100 W: FnOnce(&C) -> X,
101 X: IntoIterator<Item = O>,
102 > Drop for DFS<'a, C, O, T, U, V, W, X>
103{
104 fn drop(&mut self) {
105 (self.back_tracking)(self.status, self.op)
106 }
107}
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn it_works() {
114 const N: usize = 3;
115 {
116 let mut s = [0; 2 * N + 1];
117 s[0] = N as i32;
118 let mut a = DFS::new(
119 &mut s,
120 |s: &mut [i32; 2 * N + 1], op: (i32, i32)| {
121 s[op.1 as usize] = op.0;
122 s[(1 + op.0 + op.1) as usize] = op.0;
123 s[0] -= 1;
124 },
125 |s: &mut [i32; 2 * N + 1], op: (i32, i32)| {
126 s[op.1 as usize] = 0;
127 s[(1 + op.0 + op.1) as usize] = 0;
128 s[0] += 1
129 },
130 |s: &[i32; 2 * N + 1]| {
131 if s[0] == 0 {
132 eprintln!("{s:?}");
133 true
134 } else {
135 false
136 }
137 },
138 |s: &[i32; 2 * N + 1]| {
139 let a = s[0];
140 (1..2 * N as i32 - a)
141 .filter_map(move |x| {
142 if s[x as usize] + s[(1 + a + x) as usize] == 0 {
143 Some((a, x))
144 } else {
145 None
146 }
147 })
148 .collect::<Vec<_>>()
149 },
150 (1, 0),
151 );
152 a.dfs();
153 a.dfs_early_stop();
154 }
155 }
156}