|  |  | @ -1,6 +1,15 @@ | 
			
		
	
		
			
				
					|  |  |  | #include <queue> | 
			
		
	
		
			
				
					|  |  |  | #include <iostream> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | //#include <map>
 | 
			
		
	
		
			
				
					|  |  |  | //#include <unordered_map>
 | 
			
		
	
		
			
				
					|  |  |  | //#include <boost/unordered_map.hpp>
 | 
			
		
	
		
			
				
					|  |  |  | //#include <ankerl/unordered_dense.h>
 | 
			
		
	
		
			
				
					|  |  |  | #include "absl/container/flat_hash_map.h" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | #include "group.h" | 
			
		
	
		
			
				
					|  |  |  | #include "common.h" | 
			
		
	
		
			
				
					|  |  |  | #include "core.h" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | namespace klotski { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -44,6 +53,61 @@ Group::block_num_t Group::block_num(const CommonCode &common_code) { | 
			
		
	
		
			
				
					|  |  |  |     return result; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | //struct custom_hash_simple {
 | 
			
		
	
		
			
				
					|  |  |  | //
 | 
			
		
	
		
			
				
					|  |  |  | //    using is_avalanching = void;
 | 
			
		
	
		
			
				
					|  |  |  | //
 | 
			
		
	
		
			
				
					|  |  |  | //    auto operator()(uint64_t const& x) const noexcept -> uint64_t {
 | 
			
		
	
		
			
				
					|  |  |  | //        return ankerl::unordered_dense::detail::wyhash::hash(static_cast<uint64_t>(x));
 | 
			
		
	
		
			
				
					|  |  |  | //    }
 | 
			
		
	
		
			
				
					|  |  |  | //};
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | uint32_t Group::demo(const RawCode &seed) { | 
			
		
	
		
			
				
					|  |  |  |     struct group_cal_t { | 
			
		
	
		
			
				
					|  |  |  |         uint64_t code; | 
			
		
	
		
			
				
					|  |  |  |         uint64_t mask; | 
			
		
	
		
			
				
					|  |  |  |     }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     std::queue<group_cal_t*> cache; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | //    std::map<uint64_t, group_cal_t> cases;
 | 
			
		
	
		
			
				
					|  |  |  | //    std::unordered_map<uint64_t, group_cal_t> cases;
 | 
			
		
	
		
			
				
					|  |  |  | //    boost::unordered_map<uint64_t, group_cal_t> cases;
 | 
			
		
	
		
			
				
					|  |  |  | //    ankerl::unordered_dense::map<uint64_t, group_cal_t> cases;
 | 
			
		
	
		
			
				
					|  |  |  |     absl::flat_hash_map<uint64_t, group_cal_t> cases; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     cases.reserve(65535 * 8); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     cache.emplace(&cases.emplace(seed.unwrap(), group_cal_t { | 
			
		
	
		
			
				
					|  |  |  |         .code = seed.unwrap(), | 
			
		
	
		
			
				
					|  |  |  |         .mask = 0, | 
			
		
	
		
			
				
					|  |  |  |     }).first->second); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     auto core = Core( | 
			
		
	
		
			
				
					|  |  |  |         [&cases, &cache](auto &&code, auto &&mask) { | 
			
		
	
		
			
				
					|  |  |  |             auto current = cases.find(code); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             if (current != cases.end()) { // find existed case
 | 
			
		
	
		
			
				
					|  |  |  |                 current->second.mask |= mask; // update mask info
 | 
			
		
	
		
			
				
					|  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             cache.emplace(&cases.emplace(code, group_cal_t { | 
			
		
	
		
			
				
					|  |  |  |                 .code = code, | 
			
		
	
		
			
				
					|  |  |  |                 .mask = mask, | 
			
		
	
		
			
				
					|  |  |  |             }).first->second); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     ); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     while (!cache.empty()) { | 
			
		
	
		
			
				
					|  |  |  |         core.next_cases(cache.front()->code, cache.front()->mask); | 
			
		
	
		
			
				
					|  |  |  |         cache.pop(); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | //    std::cout << cases.size() << std::endl;
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     return cases.size(); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | } // namespace klotski
 | 
			
		
	
	
		
			
				
					|  |  | 
 |