代码托管-编译期计算八皇后 + 编译期排序
/*
--- XDU-mzb
--- lisp 3.0
*/
#include <bits/stdc++.h>
namespace DSL
{
using std::endl;
using std::cout;
using std::integral_constant;
using std::ostream;
using ll = long long int;
using ull = unsigned long long int;
#define equal(typea,typeb) typename std::is_same<typea,typeb>::type
#define if_else(a,b,c) typename std::conditional<a,b,c>::type
constexpr ull stoull(const char *p,ull now = 0)
{
return *p == 0 ? now : stoull(p + 1,now * 255 + *p);
}
template<ull val>
struct string : public integral_constant<ull,val> {};
#define str(x) string<stoull(x)>
template<typename T,typename U>
struct pair
{
using car = T;
using cdr = U;
};
#define car(x) typename Car<x>::result
template<typename T>
struct Car
{
using result = typename T::car;
};
#define cdr(x) typename Cdr<x>::result
template<typename T>
struct Cdr
{
using result = typename T::cdr;
};
template<ll val>
struct number : integral_constant<ll,val> {};
#define add(x,y) typename Add<x,y>::result
template<typename T,typename U>
struct Add
{
using result = number<T::value + U::value>;
};
#define inc(x) typename Inc<x>::result
template<typename T>
struct Inc
{
using result = number<T::value + 1>;
};
#define dec(x) typename Dec<x>::result
template<typename T>
struct Dec
{
using result = number<T::value - 1>;
};
#define neg(x) typename Neg<x>::result
template<typename T>
struct Neg
{
using result = number<-T::value>;
};
#define abs(x) typename Abs<x>::result
template<typename T>
struct Abs
{
using result = if_else(T::value >= 0,T,neg(T));
};
#define logic_not(x) typename Logic_not<x>::result
template<typename T>
struct Logic_not
{
using result = number<!T::value>;
};
#define logic_or(x,y) typename Logic_or<x,y>::result
template<typename T,typename U>
struct Logic_or
{
using result = number<T::value or U::value>;
};
#define logic_and(x,y) typename Logic_and<x,y>::result
template<typename T,typename U>
struct Logic_and
{
using result = number<T::value and U::value>;
};
#define logic_xor(x,y) typename Logic_xor<x,y>::result
template<typename T,typename U>
struct Logic_xor
{
using result = number<T::value xor U::value>;
};
struct null : str("null")
{
using car = null;
using cdr = null;
};
template<template<typename...> class op,typename ...Args> // 惰性求值
struct late_op
{
using type = typename op<Args...>::result;
};
template<typename T,typename ...arg>
struct list : pair<T,list<arg...>> {};
template<typename T>
struct list<T> : pair<T,null> {};
#define at(type,pos) typename At<type,pos>::result
template<typename T,typename pos>
struct At
{
using result = at(cdr(T),dec(pos));
};
template<typename T>
struct At<T,number<0>>
{
using result = car(T);
};
#define table_find(table,value) typename Table_find<table,value>::result
template<typename list,typename key>
struct Table_find
{
using if_found = cdr(car(list));
using if_not_found = table_find(cdr(list),key);
using check_equal = equal(car(car(list)),key);
using result = if_else(check_equal::value,if_found,if_not_found);
};
template<typename key>
struct Table_find<null,key>
{
using result = null;
};
#define length(type) typename Length<type>::result
template<typename T>
struct Length
{
using result = inc(length(cdr(T)));
};
template<>
struct Length<null>
{
using result = number<0>;
};
template<ull val>
ostream& operator << (ostream& os,string<val>)
{
std::string ret;
ull now = val;
while (now)
ret.push_back(now % 255),
now /= 255;
reverse(ret.begin(),ret.end());
return os << ret;
}
template<typename T,typename U>
ostream& operator << (ostream& os,pair<T,U>)
{
return os << "(" << T() << "," << U() <<")";
}
template<typename T>
ostream& _print(ostream& os,list<T>)
{
return os << "," << T();
}
template<typename T,typename ...args>
ostream& _print(ostream& os,list<T,args...>)
{
cout << "," << T();
_print(os,list<args...>());
return os;
}
template<typename T,typename ...args>
ostream& print(ostream& os,list<T,args...>)
{
cout << T();
_print(os,list<args...>());
return os;
}
template<typename T>
ostream& print(ostream& os,list<T>)
{
cout << T();
return os;
}
template<typename ...args>
ostream& operator << (ostream& os,list<args...>)
{
os << "[";
print(os,list<args...>());
os << "]";
return os;
}
#define merge(typea,typeb) typename Merge<typea,typeb>::result
template<typename list1,typename list2>
struct Merge {};
template<typename ...args1,template<typename ...args3> class list1,
typename ...args2,template<typename ...args4> class list2
>
struct Merge<list1<args1...>,list2<args2...>>
{
using result = list<args1...,args2...>;
};
template<typename ...args1,template<typename ...args3> class list1>
struct Merge<list1<args1...>,list<null>>
{
using result = list<args1...>;
};
template<typename ...args2,template<typename ...args4> class list2>
struct Merge<list2<null>,list2<args2...>>
{
using result = list<args2...>;
};
template<typename T>
struct Merge<T,null>
{
using result = T;
};
template<typename T>
struct Merge<null,T>
{
using result = T;
};
#define update(type,pos,val) typename Update<type,pos,val>::result
template<typename T,typename pos,typename val,typename ret = list<null>>
struct Update
{
using result = typename Update<cdr(T),dec(pos),val,merge(ret,list<car(T)>)>::result;
};
template<typename T,typename val,typename ret>
struct Update<T,number<0>,val,ret>
{
using result = merge(merge(ret,list<val>),cdr(T));
};
#define sort_merge(args...) typename Sort_merge<args>::result
template<typename list1,typename list2,typename ret = list<null>>
struct Sort_merge
{
using car1 = car(list1);
using car2 = car(list2);
using ret1 = merge(ret,list<car1>);
using ret2 = merge(ret,list<car2>);
using result = if_else(car1::value <= car2::value,
sort_merge(cdr(list1),list2,ret1),
sort_merge(list1,cdr(list2),ret2));
};
template<typename list1,typename ret>
struct Sort_merge<list1,null,ret>
{
using result = merge(ret,list1);
};
template<typename list2,typename ret>
struct Sort_merge<null,list2,ret>
{
using result = merge(ret,list2);
};
#define split(args...) typename Split<args>::result
template<typename T,typename first = list<null>,typename second = list<null>>
struct Split
{
using new_first = merge(first,list<car(T)>);
using new_second = merge(second,list<car(T)>);
using len_first = length(new_first);
using len_second = length(new_second);
using result = if_else(len_first::value < len_second::value,
split(cdr(T),new_first,second),
split(cdr(T),first,new_second));
};
template<typename first,typename second>
struct Split<null,first,second>
{
using result = pair<first,second>;
};
#define sort(type) typename Sort<type>::result
template<typename T>
struct Sort
{
using left = car(split(T));
using right = cdr(split(T));
using result = sort_merge(sort(left),sort(right));
};
template<typename T>
struct Sort<list<T>>
{
using result = list<T>;
};
#define ones(n) typename Vector<n,number<1>>::result
#define zeros(n) typename Vector<n,number<0>>::result
#define vector(n,val) typename Vector<n,val>::result
template<typename n,typename val>
struct Vector
{
using result = merge(list<val>,vector(dec(n),val));
};
template<typename val>
struct Vector<number<0>,val>
{
using result = list<null>;
};
#define vector_sub(vec,star,fini) typename Vector_sub<vec,number<0>,length(vec),star,fini>::result
template<typename vec,typename init,typename end,typename star,typename fini,typename ret = list<null>>
struct Vector_sub
{
using check = number<star::value <= init::value and init::value < fini::value>;
using reta = typename Vector_sub<vec,inc(init),end,star,fini,merge(ret,list<at(vec,init)>)>::result;
using retb = typename Vector_sub<vec,inc(init),end,star,fini,ret>::result;
using result = if_else(check::value,reta,retb);
};
template<typename vec,typename end,typename star,typename fini,typename ret>
struct Vector_sub<vec,end,end,star,fini,ret>
{
using result = ret;
};
#define for_vector(args...) typename For_vector<args>::result
template<typename init,typename end,template <typename...> class op,typename ans>
struct For_vector
{
using new_val = typename op<at(ans,init)>::result;
using ret = update(ans,init,new_val);
using result = for_vector(inc(init),end,op,ret);
};
template<typename end,template <typename...> class op,typename ans>
struct For_vector<end,end,op,ans>
{
using result = ans;
};
#define vector_bit(typea,typeb,op) typename Vector_bit<typea,typeb,op>::result
template<typename T,typename U,template <typename...> class op>
struct Vector_bit
{
using val = typename op<car(T),car(U)>::result;
using result = merge(list<val>,vector_bit(cdr(T),cdr(U),op));
};
template<template <typename...> class op>
struct Vector_bit<null,null,op>
{
using result = list<null>;
};
#define vector_or(typea,typeb) typename Vector_bit<typea,typeb,Logic_or> ::result
#define vector_xor(typea,typeb) typename Vector_bit<typea,typeb,Logic_xor>::result
#define vector_and(typea,typeb) typename Vector_and<typea,typeb,Logic_and>::result
#define vector_not(typea) for_vector(number<0>,length(typea),Logic_not,typea)
#define left_shift(type) merge(cdr(type),zeros(number<1>))
#define right_shift(type) merge(zeros(number<1>),vector_sub(type,number<0>,dec(length(type))))
#define queen(n,zuo,you,has) typename Queen<n,zuo,you,has>::result
template<typename n,typename zuo,typename you,typename has>
struct Queen;
#define for_range(args...) typename For_range<args>::result
template<typename now,typename n,typename state,typename zuo,typename you,typename has,typename ret = number<0>>
struct For_range
{
using pos = update(zeros(n),now,number<1>);
using bit = at(state,now);
using t_left = vector_or(zuo,pos);
using t_right = vector_or(you,pos);
using late = late_op<Queen,n,left_shift(t_left),right_shift(t_right),vector_or(has,pos)>;
using calc = if_else(bit::value,late,number<0>)::type;
using result = for_range(inc(now),n,state,zuo,you,has,add(ret,calc));
};
template<typename end,typename state,typename zuo,typename you,typename has,typename ret>
struct For_range<end,end,state,zuo,you,has,ret>
{
using result = ret;
};
#define ans_queen(n) queen(n,zeros(n),zeros(n),zeros(n))
template<typename n,typename zuo,typename you,typename has>
struct Queen
{
using reta = vector_or(zuo,you);
using retb = vector_or(reta,has);
using state = vector_not(retb);
using result = for_range(number<0>,n,state,zuo,you,has);
};
template<typename n,typename zuo,typename you>
struct Queen<n,zuo,you,ones(n)>
{
using result = number<1>;
};
#define show(rhs) cout << #rhs << " = " << rhs() << "\n"
int main()
{
using a2 = list<number<10>,number<-1>,number<-100>,number<123>,number<-50>>;
show(a2);
using b2 = for_vector(number<0>,number<10>,Abs,a2);
show(b2);
using c2 = logic_not(number<0>);
show(c2);
using e = vector_sub(a2,number<0>,number<2>);
show(e);
cout << endl;
cout << "--------------------------------------" << endl;
cout << endl;
using b = sort(a2);
cout << b() << endl;
using table = list<pair<str("a"),str("value_a")>,
pair<str("b"),integral_constant<bool,0>>,
pair<number<10>,str("x")>
>;
using resulta = table_find(table,str("a"));
using resultb = table_find(table,number<10>);
using resultc = table_find(table,str("c"));
cout << resulta() << endl; //value_a
cout << resultb() << endl; //x
cout << resultc() << endl; //null
cout << "five queens problem : " << ans_queen(number<5>)() << endl; // 10
cout << "eight queens problem : " << ans_queen(number<8>)() << endl; // 92
return 0;
}
#undef str
#undef null
}
int main()
{
DSL::main();
return 0;
}
本文来自博客园,作者:XDU18清欢,转载请注明原文链接:https://www.cnblogs.com/XDU-mzb/p/14832089.html
浙公网安备 33010602011771号