forked from thery/minirubik
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolve_tool.cpp
More file actions
72 lines (66 loc) · 2.3 KB
/
Copy pathsolve_tool.cpp
File metadata and controls
72 lines (66 loc) · 2.3 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
// A batch solver over the extracted proofs, used only to generate the word
// tables the solving chain needs. Nothing it prints is trusted: every word it
// produces is rechecked inside Rocq by computing what the word denotes.
//
// Input, one cube per line: a mode letter, then eight corner slots as
// "piece twist" and twelve edge slots as "piece flip", all as numbers.
// Mode "F" solves with all eighteen moves, "D" with only the ten the second
// phase may use. Output is the move codes of a solution, or "FAIL".
#include "rubik.h"
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
namespace {
std::vector<std::uint64_t> codes(const List::list<move> &p) {
std::vector<std::uint64_t> out;
const List::list<move> *cur = &p;
List::list<move> hold;
while (std::holds_alternative<List::list<move>::Cons>(cur->v())) {
const auto &cons = std::get<List::list<move>::Cons>(cur->v());
out.push_back(Viewer::move_code(cons.a));
if (!cons.l) break;
hold = *cons.l;
cur = &hold;
}
return out;
}
} // namespace
int main() {
const auto t1 = Phase1::build_tables1(std::monostate{});
const auto t2 = Phase2::build_tables2(std::monostate{});
std::string line;
while (std::getline(std::cin, line)) {
if (line.empty()) continue;
std::istringstream in(line);
std::string mode;
in >> mode;
cube c{};
corner_slot *cs[8] = {&c.xURF, &c.xUFL, &c.xULB, &c.xUBR,
&c.xDFR, &c.xDLF, &c.xDBL, &c.xDRB};
edge_slot *es[12] = {&c.yUR, &c.yUF, &c.yUL, &c.yUB, &c.yDR, &c.yDF,
&c.yDL, &c.yDB, &c.yFR, &c.yFL, &c.yBL, &c.yBR};
for (auto *slot : cs) {
int p = 0, t = 0;
in >> p >> t;
*slot = corner_slot{static_cast<Corner>(p), static_cast<Twist>(t)};
}
for (auto *slot : es) {
int p = 0, f = 0;
in >> p >> f;
*slot = edge_slot{static_cast<Edge>(p), static_cast<Flip>(f)};
}
const auto answer = mode == "D" ? Phase2::phase2(t2, 30, c)
: Solve::two_phase(t1, t2, 20, 30, c);
if (!answer) {
std::cout << "FAIL\n";
} else {
const auto out = codes(*answer);
for (std::size_t i = 0; i < out.size(); ++i)
std::cout << (i ? " " : "") << out[i];
std::cout << "\n";
}
std::cout.flush();
}
return 0;
}