-
Notifications
You must be signed in to change notification settings - Fork 0
/
Merlin's Magic using A* search.cpp
105 lines (85 loc) · 3.09 KB
/
Merlin's Magic using A* search.cpp
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
#include <bits/stdc++.h>
using namespace std;
// Function to calculate the heuristic value
int calculateHeuristic(const string& state, const string& target) {
int heuristic = 0;
for (size_t i = 0; i < state.size(); ++i) {
if (state[i] != target[i])
heuristic++;
}
return heuristic;
}
// Function to perform a group operation on the state
void performGroupOperation(string& state, const vector<vector<int>>& operation) {
for (size_t i = 0; i < state.size(); ++i) {
int element = state[i] - '0';
state[i] = operation[element][0] + '0';
}
}
// Function to solve the Merlin's Magic puzzle using A* search
bool solveMerlinsMagicPuzzle(const string& initial, const string& target,
const vector<vector<vector<int>>>& operations) {
auto cmp = [](const pair<string, int>& a, const pair<string, int>& b) {
return a.second > b.second;
};
priority_queue<pair<string, int>, vector<pair<string, int>>, decltype(cmp)> pq(cmp);
unordered_map<string, int> gScore;
unordered_map<string, string> cameFrom;
unordered_map<string, bool> visited;
pq.push({initial, 0});
gScore[initial] = 0;
while (!pq.empty()) {
string current = pq.top().first;
pq.pop();
if (current == target)
return true;
visited[current] = true;
for (const auto& operation : operations) {
string next = current;
performGroupOperation(next, operation);
int tentativeGScore = gScore[current] + 1;
if (!visited[next] || tentativeGScore < gScore[next]) {
cameFrom[next] = current;
gScore[next] = tentativeGScore;
int fScore = tentativeGScore + calculateHeuristic(next, target);
pq.push({next, fScore});
}
}
}
return false;
}
// Function to reconstruct the path from the initial state to the target state
vector<string> reconstructPath(const string& initial, const string& target,
const unordered_map<string, string>& cameFrom) {
vector<string> path;
string current = target;
while (current != initial) {
path.push_back(current);
current = cameFrom.at(current);
}
path.push_back(initial);
reverse(path.begin(), path.end());
return path;
}
int main() {
string initial = "012102201";
string target = "000000000";
vector<vector<vector<int>>> operations = {
{{0, 1, 2}, {1, 2, 0}, {2, 0, 1}},
{{1, 0, 2}, {0, 2, 1}, {2, 1, 0}},
{{2, 1, 0}, {1, 0, 2}, {0, 2, 1}}
};
if (solveMerlinsMagicPuzzle(initial, target, operations)) {
cout << "Merlin's Magic puzzle solved!" << endl;
unordered_map<string, string> cameFrom;
vector<string> path = reconstructPath(initial, target, cameFrom);
cout << "Path: ";
for (const string& state : path) {
cout << state << " -> ";
}
cout << "Goal" << endl;
} else {
cout << "No solution found for the Merlin's Magic puzzle." << endl;
}
return 0;
}