-
Notifications
You must be signed in to change notification settings - Fork 178
Expand file tree
/
Copy pathwaterJug.js
More file actions
137 lines (129 loc) · 2.88 KB
/
waterJug.js
File metadata and controls
137 lines (129 loc) · 2.88 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Defining constants.
const ACTION_FILL_X = -1
const ACTION_FILL_Y = -2
const ACTION_EMPTY_X = -3
const ACTION_EMPTY_Y = -4
const ACTION_POUR_FILL_X = -5
const ACTION_POUR_FILL_Y = -6
const ACTION_POUR_EMPTY_X = -7
const ACTION_POUR_EMPTY_Y = -8
function getChildren(node, m, n) {
const results = [];
const {x, y} = node.state;
if (x < m)
results.push({
x: m,
y,
action: ACTION_FILL_X
});
if (y < n)
results.push({
x,
y: n,
action: ACTION_FILL_Y
});
if (x > 0)
results.push({
x: 0,
y,
action: ACTION_EMPTY_X
});
if (y > 0)
results.push({
x,
y: 0,
action: ACTION_EMPTY_Y
});
if (x + y >= m && y > 0)
results.push({
x: m,
y: x + y - m,
action: ACTION_POUR_FILL_X
});
if (x + y >= n && x > 0)
results.push({
x: x + y - n,
y: n,
action: ACTION_POUR_FILL_Y
});
if (x + y <= m && y >= 0)
results.push({
x: x + y,
y: 0,
action: ACTION_POUR_EMPTY_Y
});
if (x + y <= n && x >= 0)
results.push({
x: 0,
y: x + y,
action: ACTION_POUR_EMPTY_X
});
return results;
}
function solve(m, n, d) {
// The final state to achieve.
const goal = { x: d, y: 0 };
// Starting from the topmost row of the matrix.
// Initiating the first state and node
const initialState = {
x: 0,
y: 0
};
const initialNode = {
state: initialState,
parent: null,
action: null,
};
// For BFS, we use a Queue data type, FIFO.
let frontier = [initialNode];
while (frontier.length != 0) {
// Getting the first node in the frontier.
const node = frontier[0];
frontier = frontier.slice(1);
// Checking if the node represents an element in the last row.
// If so, then add it to the goal state list and continue.
if (node.state.x == goal.x) {
printSolution(node);
break;
}
// If it is not the goal state, we can get certain actions we can perform.
// Get all available actions the current node have.
const children = getChildren(node, m, n);
for (let j = 0; j < children.length; j++) {
const result = children[j];
const childState = {
x: result.x,
y: result.y,
};
const child = {
state: childState,
parent: node,
action: result.action,
};
// Add this node to the frontier.
frontier.push(child);
}
}
}
function printSolution(node) {
const nodes = [];
while (node.parent != null) {
nodes.push(node);
node = node.parent;
}
nodes.push(node);
nodes.reverse();
let answer = "{";
for (let i = 0; i < nodes.length; i++) {
answer += `(${nodes[i].state.x}, ${nodes[i].state.y})`;
if (i !== nodes.length - 1)
answer += ', ';
}
answer += "}";
console.log(answer);
}
(() => {
const [m, n, d] = [4, 3, 2];
solve(m, n, d);
})();
// Demo Change