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
|
// Java Solution class
import java.util.*;
public class Solution {
private static class State {
boolean farmer, sheep, cabbage, wolf;
State(boolean f, boolean s, boolean c, boolean w) {
farmer = f; sheep = s; cabbage = c; wolf = w;
}
@Override public boolean equals(Object o) {
if (!(o instanceof State)) return false;
State s = (State) o;
return farmer == s.farmer && sheep == s.sheep && cabbage == s.cabbage && wolf == s.wolf;
}
@Override public int hashCode() {
int v = 0;
v |= (farmer ? 1 : 0);
v |= (sheep ? 2 : 0);
v |= (cabbage ? 4 : 0);
v |= (wolf ? 8 : 0);
return v;
}
}
public List<String> solve() {
State start = new State(false, false, false, false);
State goal = new State(true, true, true, true);
List<String> path = new ArrayList<>();
Set<Integer> visited = new HashSet<>();
dfs(start, goal, path, visited);
return path;
}
private boolean safe(State s) {
if (s.sheep == s.cabbage && s.sheep != s.farmer) return false;
if (s.sheep == s.wolf && s.sheep != s.farmer) return false;
return true;
}
private int encode(State s) {
int v = 0;
if (s.farmer) v |= 1;
if (s.sheep) v |= 2;
if (s.cabbage) v |= 4;
if (s.wolf) v |= 8;
return v;
}
private boolean dfs(State cur, State goal, List<String> path, Set<Integer> visited) {
if (cur.equals(goal)) return true;
int key = encode(cur);
if (visited.contains(key)) return false;
visited.add(key);
// farmer crosses alone
State next = new State(!cur.farmer, cur.sheep, cur.cabbage, cur.wolf);
if (safe(next)) {
path.add("boatman");
if (dfs(next, goal, path, visited)) return true;
path.remove(path.size() - 1);
}
// farmer crosses with each item that's on same side
if (cur.sheep == cur.farmer) {
State n = new State(!cur.farmer, !cur.sheep, cur.cabbage, cur.wolf);
if (safe(n)) {
path.add("sheep");
if (dfs(n, goal, path, visited)) return true;
path.remove(path.size() - 1);
}
}
if (cur.cabbage == cur.farmer) {
State n = new State(!cur.farmer, cur.sheep, !cur.cabbage, cur.wolf);
if (safe(n)) {
path.add("cabbage");
if (dfs(n, goal, path, visited)) return true;
path.remove(path.size() - 1);
}
}
if (cur.wolf == cur.farmer) {
State n = new State(!cur.farmer, cur.sheep, cur.cabbage, !cur.wolf);
if (safe(n)) {
path.add("wolf");
if (dfs(n, goal, path, visited)) return true;
path.remove(path.size() - 1);
}
}
return false;
}
}
|