代码托管-编译期计算八皇后 + 编译期排序

/*
--- 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;
  }
posted @ 2021-05-31 16:45  XDU18清欢  阅读(90)  评论(0)    收藏  举报