| 
						
						
						
					 | 
				
				 | 
				
					@ -1,8 +1,12 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <future> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <thread> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <unordered_set> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "common.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "raw_code.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "all_cases.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "tiny_pool.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "gtest/gtest.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "range_split.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define SHOULD_PANIC(FUNC) \ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    try { \ | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -13,6 +17,8 @@ using klotski::RawCode; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using klotski::AllCases; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using klotski::CommonCode; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using klotski::ALL_CASES_SIZE; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using klotski::ALL_CASES_SIZE_SUM; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					using klotski::Common::range_reverse; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const static uint64_t TEST_CODE = 0x0603'EDF5'CAFF'F5E2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -201,3 +207,64 @@ TEST(RawCode, horizontal_mirror_global) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (auto &t : threads) { t.join(); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/// NOTE: for RawCode global test
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					uint64_t raw_code_convert(uint64_t common_code) { // try to convert as raw code
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto code = C_2x2 << (common_code >> 32) * 3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto range = range_reverse((uint32_t)common_code); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int addr = 0; range; range >>= 2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        while ((code >> addr) & 0b111 && addr < 60) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            addr += 3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (addr >= 60) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        switch (range & 0b11) { // match low 2-bits
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            case 0b01: // 1x2 block
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                code |= C_1x2 << addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            case 0b10: // 2x1 block
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                code |= C_2x1 << addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            case 0b11: // 1x1 block
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                code |= C_1x1 << addr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            case 0b00: // space
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                addr += 3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return code; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					TEST(RawCode, DISABLED_global) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto search = [](uint64_t start, uint64_t end) -> std::vector<uint64_t> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::vector<uint64_t> archive; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (uint64_t common_code = start; common_code < end; ++common_code) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (RawCode::check(raw_code_convert(common_code))) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                archive.emplace_back(common_code); // valid layout
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return archive; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto pool = TinyPool(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<std::future<std::vector<uint64_t>>> tasks; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (const auto &range : range_split(0, 0x10'0000'0000, 0x10'0000)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        tasks.emplace_back( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            pool.submit(search, range.first, range.second) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        ); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    pool.boot(); // running tasks
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<uint64_t> result; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (auto &tmp : tasks) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto ret = tmp.get(); // release data
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        result.insert(result.end(), ret.begin(), ret.end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    pool.join(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto all_cases = AllCases::release(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (uint32_t i = 0; i < ALL_CASES_SIZE_SUM; ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        EXPECT_EQ(all_cases[i], result[i]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
				 | 
				
					
  |