Skip to content

Instantly share code, notes, and snippets.

@TommyJSWu
Last active June 27, 2022 01:47
Show Gist options
  • Save TommyJSWu/9c2274c07e9810adf299a8399f09a97a to your computer and use it in GitHub Desktop.
Save TommyJSWu/9c2274c07e9810adf299a8399f09a97a to your computer and use it in GitHub Desktop.
Compile-time solving 8-Queens Problem
#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