Browse Source

perf: builder of group cases

master
Dnomd343 5 days ago
parent
commit
b1bb7da561
  1. 327
      src/core/group/internal/group.cc
  2. 26
      src/core/main.cc

327
src/core/group/internal/group.cc

@ -70,26 +70,51 @@ static RangesUnion extend_demo(Group group, RawCode seed, size_t reserve) { // T
cases.emplace(code, mask);
codes.emplace_back(code); // new case
auto kk = code.to_horizontal_mirror();
// if (const auto match = cases.find(kk.unwrap()); match != cases.end()) {
// return;
// }
// cases.emplace(kk, 0);
if (kk != code && cases.try_emplace(kk.unwrap(), 0).second) {
mirror_codes.emplace_back(kk);
auto k1 = code.to_horizontal_mirror();
if (k1 != code) {
bool ret = cases.try_emplace(k1.unwrap(), 0).second;
if (!ret) {
std::cout << "!!! get unexpect case" << std::endl; // TODO: can we confirm it?
} else {
mirror_codes.emplace_back(k1);
}
}
// auto k2 = code.to_vertical_mirror();
// if (k2 != code && cases.try_emplace(k2.unwrap(), 0).second) {
// mirror_codes.emplace_back(k2);
// }
// auto k3 = k2.to_horizontal_mirror();
// if (k3 != code && cases.try_emplace(k3.unwrap(), 0).second) {
// mirror_codes.emplace_back(k3);
// }
});
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without mask
auto pp = seed.to_horizontal_mirror();
if (pp != seed) {
mirror_codes.emplace_back(seed.to_horizontal_mirror());
cases.emplace(seed.to_horizontal_mirror(), 0);
auto p1 = seed.to_horizontal_mirror();
if (p1 != seed) {
mirror_codes.emplace_back(p1);
cases.emplace(p1, 0);
}
std::cout << std::format("{} vs {}\n", codes.size(), mirror_codes.size());
// auto p2 = seed.to_vertical_mirror();
// if (p2 != seed) {
// mirror_codes.emplace_back(p2);
// cases.emplace(p2, 0);
// }
// auto p3 = p2.to_horizontal_mirror();
// if (p3 != p2) {
// mirror_codes.emplace_back(p3);
// cases.emplace(p3, 0);
// }
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
@ -107,13 +132,262 @@ static RangesUnion extend_demo(Group group, RawCode seed, size_t reserve) { // T
return result;
}
static RangesUnion extend_type_common(RawCode seed, size_t reserve) {
std::vector<RawCode> codes;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
cases.reserve(reserve * 1.56);
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint
return;
}
codes.emplace_back(code); // new case
});
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint
while (offset != codes.size()) {
auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second);
}
RangesUnion result {};
// TODO: how to reserve
for (auto raw_code : codes) { // TODO: using `std::views::concat` in new std library
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
return result;
}
static RangesUnion extend_type_hor(RawCode seed, size_t reserve) {
std::vector<RawCode> codes;
std::vector<RawCode> mirrors;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
mirrors.reserve(reserve); // TODO: cal max size-coff
cases.reserve(reserve * 1.56);
auto core = MaskMover([&codes, &cases, &mirrors](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint
return;
}
codes.emplace_back(code); // new case
const auto k1 = code.to_horizontal_mirror();
if (k1 != code) {
cases.emplace(k1, 0); // TODO: contain check
mirrors.emplace_back(k1);
}
});
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint
const auto p1 = seed.to_horizontal_mirror();
if (p1 != seed) {
mirrors.emplace_back(p1);
cases.emplace(p1, 0);
}
while (offset != codes.size()) {
auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second);
}
RangesUnion result {};
// TODO: how to reserve
for (auto raw_code : codes) { // TODO: using `std::views::concat` in new std library
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
for (auto raw_code : mirrors) {
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
return result;
}
static RangesUnion extend_type_ver(RawCode seed, size_t reserve) {
std::vector<RawCode> codes;
std::vector<RawCode> mirrors;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
mirrors.reserve(reserve); // TODO: cal max size-coff
cases.reserve(reserve * 1.56);
auto core = MaskMover([&codes, &cases, &mirrors](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint
return;
}
codes.emplace_back(code); // new case
const auto k1 = code.to_vertical_mirror();
if (k1 != code) {
cases.emplace(k1, 0); // TODO: contain check
mirrors.emplace_back(k1);
}
});
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint
const auto p1 = seed.to_vertical_mirror();
if (p1 != seed) {
mirrors.emplace_back(p1);
cases.emplace(p1, 0);
}
while (offset != codes.size()) {
auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second);
}
RangesUnion result {};
// TODO: how to reserve
for (auto raw_code : codes) { // TODO: using `std::views::concat` in new std library
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
for (auto raw_code : mirrors) {
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
return result;
}
static RangesUnion extend_type_diag(RawCode seed, size_t reserve) {
std::vector<RawCode> codes;
std::vector<RawCode> mirrors;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
mirrors.reserve(reserve); // TODO: cal max size-coff
cases.reserve(reserve * 1.56);
auto core = MaskMover([&codes, &cases, &mirrors](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint
return;
}
codes.emplace_back(code); // new case
const auto k1 = code.to_vertical_mirror().to_horizontal_mirror();
if (k1 != code) {
cases.emplace(k1, 0); // TODO: contain check
mirrors.emplace_back(k1);
}
});
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint
const auto p1 = seed.to_vertical_mirror().to_horizontal_mirror();
if (p1 != seed) {
mirrors.emplace_back(p1);
cases.emplace(p1, 0);
}
while (offset != codes.size()) {
auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second);
}
RangesUnion result {};
// TODO: how to reserve
for (auto raw_code : codes) { // TODO: using `std::views::concat` in new std library
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
for (auto raw_code : mirrors) {
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
return result;
}
static RangesUnion extend_type_x(RawCode seed, size_t reserve) {
std::vector<RawCode> codes;
std::vector<RawCode> mirrors;
phmap::flat_hash_map<RawCode, uint64_t> cases; // <code, hint>
codes.reserve(reserve);
mirrors.reserve(reserve); // TODO: cal max size-coff
cases.reserve(reserve * 1.56);
auto core = MaskMover([&codes, &cases, &mirrors](RawCode code, uint64_t hint) {
if (const auto [iter, ret] = cases.try_emplace(code, hint); !ret) {
iter->second |= hint; // update hint
return;
}
codes.emplace_back(code); // new case
const auto k1 = code.to_vertical_mirror();
mirrors.emplace_back(k1);
cases.emplace(k1, 0);
const auto k2 = code.to_horizontal_mirror();
if (k2 != code) {
mirrors.emplace_back(k2);
cases.emplace(k2, 0);
const auto p3 = k1.to_horizontal_mirror();
mirrors.emplace_back(p3);
cases.emplace(p3, 0);
}
});
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without hint
const auto p1 = seed.to_vertical_mirror();
mirrors.emplace_back(p1);
cases.emplace(p1, 0);
const auto p2 = seed.to_horizontal_mirror();
if (p2 != seed) {
mirrors.emplace_back(p2);
cases.emplace(p2, 0);
const auto p3 = p1.to_horizontal_mirror();
mirrors.emplace_back(p3);
cases.emplace(p3, 0);
}
while (offset != codes.size()) {
auto curr = codes[offset++];
core.next_cases(curr, cases.find(curr)->second);
}
RangesUnion result {};
// TODO: how to reserve
for (auto raw_code : codes) { // TODO: using `std::views::concat` in new std library
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
for (auto raw_code : mirrors) {
const auto code = raw_code.to_common_code().unwrap();
result.ranges(code >> 32).emplace_back(static_cast<uint32_t>(code));
}
return result;
}
// TODO: maybe we can perf with mirror cases
RangesUnion Group::cases() const {
// TODO: add white list for single-group unions
// return GroupUnion::cases directly
auto seed = CommonCode::unsafe_create(PATTERN_DATA[flat_id()] >> 23);
auto seed = CommonCode::unsafe_create(PATTERN_DATA[flat_id()] >> 23).to_raw_code();
// NOTE: convert as RawCode directly
if (toward_ == Toward::B) {
@ -125,10 +399,33 @@ RangesUnion Group::cases() const {
seed = seed.to_vertical_mirror().to_horizontal_mirror();
}
// std::cout << seed << std::endl;
auto data = extend_demo(*this, seed.to_raw_code(), size());
// auto data = extend_type_hor(seed, size());
// auto data = extend_type_ver(seed, size());
// auto data = extend_type_diag(seed, size());
// auto data = extend_type_x(seed, size());
RangesUnion data;
if (mirror_type() == MirrorType::Full) {
data = extend_type_x(seed, size());
} else if (mirror_type() == MirrorType::Horizontal) {
data = extend_type_hor(seed, size());
} else if (mirror_type() == MirrorType::Vertical) {
data = extend_type_ver(seed, size());
} else if (mirror_type() == MirrorType::Centro) {
data = extend_type_diag(seed, size());
} else {
data = extend_type_common(seed, size());
}
// auto raw_data = Group_extend_for_cases(seed, size());
// RangesUnion data {};
// for (auto raw_code : raw_data) {
// auto common_code = raw_code.to_common_code().unwrap();
// data.ranges(common_code >> 32).emplace_back(static_cast<uint32_t>(common_code));
// }
for (int head = 0; head < 16; ++head) {
std::stable_sort(data.ranges(head).begin(), data.ranges(head).end());
std::stable_sort(data.ranges(head).begin(), data.ranges(head).end()); // TODO: maybe using quick_sort
}
return data;
}

26
src/core/main.cc

@ -52,6 +52,25 @@ int main() {
// TODO: maybe we can support `std::format`
// auto group = Group::create(169, 0, Group::Toward::C).value();
// auto group = Group::create(82, 68, Group::Toward::C).value();
// auto group = Group::create(189, 279, Group::Toward::A).value();
// auto kk = group.cases();
// std::cout << kk.size() << std::endl;
for (int type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
for (auto group : GroupUnion::unsafe_create(type_id).groups()) {
// if (group.is_horizontal_mirror()) {
// if (group.is_vertical_mirror()) {
// if (group.mirror_type() == Group::MirrorType::Centro) {
// if (group.mirror_type() == Group::MirrorType::Full) {
// std::cout << group.to_string() << std::endl;
volatile auto kk = group.cases();
// std::cout << group.size() << std::endl;
// }
}
}
// const auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
// const auto solve_1 = CommonCode::unsafe_create(0xDAAF4CC00).to_raw_code();
// const auto solve_2 = CommonCode::unsafe_create(0xDAA7F3000).to_raw_code();
@ -62,13 +81,13 @@ int main() {
// std::cout << backtrack.size() << std::endl;
// std::cout << backtrack[0].size() << ", " << backtrack[81].size() << std::endl;
const auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
// const auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
// const auto code = CommonCode::unsafe_create(0x4FEA13400).to_raw_code();
FastCal fc {code};
// FastCal fc {code};
// std::cout << fc.solve().value() << std::endl;
std::cout << fc.backtrack(fc.solve().value()).size() << std::endl;
// std::cout << fc.backtrack(fc.solve().value()).size() << std::endl;
// for (const auto x : fc.solve_multi()) {
// std::cout << x.to_common_code() << std::endl;
@ -178,6 +197,7 @@ int main() {
// std::cout << (int)gp.mirror_type() << std::endl;
#if defined(__clang__)
// std::cerr << (std::chrono::system_clock::now() - start).count() << "us" << std::endl;
std::cerr << (std::chrono::system_clock::now() - start).count() / 1000 << "ms" << std::endl;
#elif defined(__GNUC__)
std::cerr << (std::chrono::system_clock::now() - start).count() / 1000000 << "ms" << std::endl;

Loading…
Cancel
Save