|  |  | @ -1,11 +1,6 @@ | 
			
		
	
		
			
				
					|  |  |  | #include "fast_cal/fast_cal.h" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | #include <iostream> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | #include <parallel_hashmap/phmap.h> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | #include "mover/mover.h" | 
			
		
	
		
			
				
					|  |  |  | #include "group/group.h" | 
			
		
	
		
			
				
					|  |  |  | #include "fast_cal/fast_cal.h" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | using klotski::codec::RawCode; | 
			
		
	
		
			
				
					|  |  |  | using klotski::codec::CommonCode; | 
			
		
	
	
		
			
				
					|  |  | @ -16,8 +11,8 @@ using klotski::cases::GroupUnion; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | using klotski::fast_cal::FastCalPro; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | static KLSK_INLINE bool is_solved(uint64_t raw_code) { | 
			
		
	
		
			
				
					|  |  |  |     return ((raw_code >> 39) & 0b111) == 0b100; | 
			
		
	
		
			
				
					|  |  |  | static KLSK_INLINE bool is_solved(RawCode raw_code) { | 
			
		
	
		
			
				
					|  |  |  |     return ((raw_code.unwrap() >> 39) & 0b111) == 0b100; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | std::optional<RawCode> FastCalPro::solve() { | 
			
		
	
	
		
			
				
					|  |  | @ -26,9 +21,9 @@ std::optional<RawCode> FastCalPro::solve() { | 
			
		
	
		
			
				
					|  |  |  |     // }
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     uint64_t solution = 0; | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this, &solution](uint64_t code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this, &solution](RawCode code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  |         if (try_emplace(code, mask) && is_solved(code)) { | 
			
		
	
		
			
				
					|  |  |  |             solution = code; | 
			
		
	
		
			
				
					|  |  |  |             solution = code.unwrap(); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |     while (!codes_.is_ending()) { | 
			
		
	
	
		
			
				
					|  |  | @ -44,9 +39,9 @@ std::optional<RawCode> FastCalPro::search(std::function<bool(RawCode)> &&match) | 
			
		
	
		
			
				
					|  |  |  |     // TODO: check root case
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     uint64_t target = 0; | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this, &target, match = std::move(match)](uint64_t code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  |         if (try_emplace(code, mask) && match(RawCode::unsafe_create(code))) { | 
			
		
	
		
			
				
					|  |  |  |             target = code; | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this, &target, match = std::move(match)](RawCode code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  |         if (try_emplace(code, mask) && match(code)) { | 
			
		
	
		
			
				
					|  |  |  |             target = code.unwrap(); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |     while (!codes_.is_ending()) { | 
			
		
	
	
		
			
				
					|  |  | @ -64,17 +59,16 @@ std::vector<RawCode> FastCalPro::solve_multi() { | 
			
		
	
		
			
				
					|  |  |  |     bool stop_flag = false; | 
			
		
	
		
			
				
					|  |  |  |     std::vector<RawCode> results {}; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this, &stop_flag, &results](uint64_t code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this, &stop_flag, &results](RawCode code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  |         if (try_emplace(code, mask) && is_solved(code)) { | 
			
		
	
		
			
				
					|  |  |  |             stop_flag = true; | 
			
		
	
		
			
				
					|  |  |  |             results.emplace_back(RawCode::unsafe_create(code)); | 
			
		
	
		
			
				
					|  |  |  |             results.emplace_back(code); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     while (!codes_.is_ending()) { | 
			
		
	
		
			
				
					|  |  |  |         spawn_next(mover); | 
			
		
	
		
			
				
					|  |  |  |         if (codes_.is_new_layer() && stop_flag) { | 
			
		
	
		
			
				
					|  |  |  |             // TODO: fix when solutions at last layer
 | 
			
		
	
		
			
				
					|  |  |  |         if (stop_flag && (codes_.is_new_layer() || codes_.is_ending())) { | 
			
		
	
		
			
				
					|  |  |  |             return results; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -82,26 +76,30 @@ std::vector<RawCode> FastCalPro::solve_multi() { | 
			
		
	
		
			
				
					|  |  |  |     return {}; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | std::vector<RawCode> FastCalPro::furthest() { | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this](uint64_t code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  | void FastCalPro::build() { | 
			
		
	
		
			
				
					|  |  |  |     auto mover = MaskMover([this](RawCode code, uint64_t mask) { | 
			
		
	
		
			
				
					|  |  |  |         try_emplace(code, mask); | 
			
		
	
		
			
				
					|  |  |  |     }); | 
			
		
	
		
			
				
					|  |  |  |     while (true) { | 
			
		
	
		
			
				
					|  |  |  |     while (!codes_.is_ending()) { | 
			
		
	
		
			
				
					|  |  |  |         spawn_next(mover); | 
			
		
	
		
			
				
					|  |  |  |         if (codes_.is_ending()) { | 
			
		
	
		
			
				
					|  |  |  |             return codes_.last_layer(); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | std::vector<RawCode> FastCalPro::furthest() { | 
			
		
	
		
			
				
					|  |  |  |     if (!codes_.is_ending()) { | 
			
		
	
		
			
				
					|  |  |  |         build(); | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     return codes_.last_layer(); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | std::vector<RawCode> FastCalPro::backtrack(RawCode code) const { | 
			
		
	
		
			
				
					|  |  |  |     if (const auto match = cases_.find(code.unwrap()); match == cases_.end()) { | 
			
		
	
		
			
				
					|  |  |  |     if (const auto match = cases_.find(code); match == cases_.end()) { | 
			
		
	
		
			
				
					|  |  |  |         return {}; // case not found
 | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     std::vector<RawCode> path; | 
			
		
	
		
			
				
					|  |  |  |     while (code != 0) { | 
			
		
	
		
			
				
					|  |  |  |         path.emplace_back(code); | 
			
		
	
		
			
				
					|  |  |  |         code = RawCode::unsafe_create(cases_.find(code.unwrap())->second.back); | 
			
		
	
		
			
				
					|  |  |  |         code = cases_.find(code)->second.back; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     std::reverse(path.begin(), path.end()); | 
			
		
	
		
			
				
					|  |  |  |     return path; |