Last active
June 27, 2022 01:47
-
-
Save TommyJSWu/9c2274c07e9810adf299a8399f09a97a to your computer and use it in GitHub Desktop.
Compile-time solving 8-Queens Problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <array> | |
#include <type_traits> | |
#include <iterator> | |
template<int... ns> | |
struct mylist | |
{ | |
constexpr static std::array<int, sizeof...(ns)> value{ns...}; | |
}; | |
template<typename...> | |
struct mylist_cat; | |
template<int... ns1, int... ns2> | |
struct mylist_cat<mylist<ns1...>, mylist<ns2...>> | |
{ | |
using type = mylist<ns1..., ns2...>; | |
}; | |
template<typename first, typename... rests> | |
struct mylist_cat<first, rests...> : mylist_cat< | |
first, | |
typename mylist_cat<rests...>::type | |
> | |
{}; | |
template<int mc, int md1, int md2> | |
struct pos_check | |
{ | |
template<int c> | |
struct conflict_c : std::bool_constant<((1 << c) & mc) != 0> {}; | |
template<int r, int c> | |
struct conflict_d1 : std::bool_constant<((1 << (r + c)) & md1) != 0> {}; | |
template<int r, int c> | |
struct conflict_d2 : std::bool_constant<((1 << (r - c + 8)) & md2) != 0> {}; | |
template<int r, int c> | |
constexpr static bool conflict_v = std::disjunction_v< | |
conflict_c<c>, conflict_d1<r, c>, conflict_d2<r, c> | |
>; | |
template<int r, int c> | |
struct put_queen | |
{ | |
using type = pos_check< | |
(1 << c) | mc, | |
(1 << (r + c)) | md1, | |
(1 << (r - c + 8)) | md2 | |
>; | |
}; | |
}; | |
struct invalid_board | |
{ | |
using type = mylist<>; | |
}; | |
template<int r, typename mask, int sol> | |
struct solve_queen; | |
template<int r, int c, typename mask, int sol> | |
struct try_put : | |
std::conditional_t<mask::template conflict_v<r, c>, | |
invalid_board, | |
solve_queen<r + 1, typename mask::template put_queen<r, c>::type, sol * 10 + c> | |
> | |
{ | |
}; | |
template<int r, int c, typename mask, int sol> | |
using try_put_t = typename try_put<r, c, mask, sol>::type; | |
template<int r, typename mask, int sol> | |
struct solve_queen : mylist_cat< | |
try_put_t<r, 1, mask, sol>, | |
try_put_t<r, 2, mask, sol>, | |
try_put_t<r, 3, mask, sol>, | |
try_put_t<r, 4, mask, sol>, | |
try_put_t<r, 5, mask, sol>, | |
try_put_t<r, 6, mask, sol>, | |
try_put_t<r, 7, mask, sol>, | |
try_put_t<r, 8, mask, sol>> | |
{ | |
}; | |
template<typename mask, int sol> | |
struct solve_queen<9, mask, sol> | |
{ | |
using type = mylist<sol>; | |
}; | |
int main() | |
{ | |
auto sols = solve_queen<1, pos_check<0, 0, 0>, 0>::type::value; | |
std::ostream_iterator<int> out_it{std::cout, "\n"}; | |
std::copy(sols.begin(), sols.end(), out_it); | |
} | |
// Compiled by clang 10.0.0 on MacOS | |
// g++ ct_queen.cpp -std=c++20; ./a.out |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment