| 
						
						
							
								
							
						
						
					 | 
					@ -2,6 +2,9 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "raw_code.h" | 
					 | 
					 | 
					#include "raw_code.h" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#include "core_demo.h" | 
					 | 
					 | 
					#include "core_demo.h" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					int cache_size; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					cache_t cache[16]; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					#define release_1x1(filter_dir) {\ | 
					 | 
					 | 
					#define release_1x1(filter_dir) {\ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    cache_t next_case = { \ | 
					 | 
					 | 
					    cache_t next_case = { \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        .code = code & ~(F_1x1 << addr) | (C_1x1 << next_addr), \ | 
					 | 
					 | 
					        .code = code & ~(F_1x1 << addr) | (C_1x1 << next_addr), \ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -12,23 +15,17 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    cache_insert(next_case); \ | 
					 | 
					 | 
					    cache_insert(next_case); \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					int cache_size; | 
					 | 
					 | 
					#define release_1x2(filter_dir) {\ | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					cache_t cache[16]; | 
					 | 
					 | 
					    cache_t next_case = { \ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .code = code & ~(F_1x2 << addr) | (C_1x2 << next_addr), \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .mask = (uint64_t)0b111 << next_addr, \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .filter = filter_dir, \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .addr = next_addr \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    cache_insert(next_case); \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					inline bool cache_insert(cache_t &new_item) { | 
					 | 
					 | 
					inline bool cache_insert(cache_t &new_item) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    // TODO: try closed hashing
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    auto volatile hash = new_item.code;
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    printf("%016lX -> ", hash); // 64-bits
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    hash ^= hash >> 32;
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    printf("%08lX -> ", hash & 0xFFFFFFFF); // 32-bits
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    hash ^= hash >> 16;
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    printf("%04lX -> ", hash & 0xFFFF); // 16-bits
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    hash ^= hash >> 8;
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    printf("%02lX -> ", hash & 0xFF); // 8-bits
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    hash ^= hash >> 4;
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    printf("%01lX\n", hash & 0xF); // 4-bits
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    auto *p = cache; | 
					 | 
					 | 
					    auto *p = cache; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    for (; p < cache + cache_size; ++p) { | 
					 | 
					 | 
					    for (; p < cache + cache_size; ++p) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if (p->code == new_item.code) { | 
					 | 
					 | 
					        if (p->code == new_item.code) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -42,12 +39,11 @@ inline bool cache_insert(cache_t &new_item) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					void move_1x1(uint64_t code, int addr) { | 
					 | 
					 | 
					void move_1x1(uint64_t code, int addr) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    cache_size = 1; | 
					 | 
					 | 
					    cache_size = 1; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    cache[0].code = code; // load into queue
 | 
					 | 
					 | 
					    cache[0].code = code; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    cache[0].addr = addr; | 
					 | 
					 | 
					    cache[0].addr = addr; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    cache[0].filter = 0; // filter unset
 | 
					 | 
					 | 
					    cache[0].filter = 0; // filter unset
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    int current = 0; | 
					 | 
					 | 
					    int current = 0; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    while (current != cache_size) { // start bfs search
 | 
					 | 
					 | 
					    while (current != cache_size) { // start bfs search
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        code = cache[current].code; | 
					 | 
					 | 
					        code = cache[current].code; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        addr = cache[current].addr; | 
					 | 
					 | 
					        addr = cache[current].addr; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -55,16 +51,45 @@ void move_1x1(uint64_t code, int addr) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        int filter = cache[current++].filter; // case filter
 | 
					 | 
					 | 
					        int filter = cache[current++].filter; // case filter
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if (filter != UP && addr >= 4 * 3 && !(code >> (next_addr = addr + UP) & F_1x1)) { | 
					 | 
					 | 
					        if (filter != UP && addr >= 4 * 3 && !(code >> (next_addr = addr + UP) & F_1x1)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            release_1x1(-UP); // block can move up
 | 
					 | 
					 | 
					            release_1x1(-UP); // 1x1 block can move up
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if (filter != DOWN && addr <= 15 * 3 && !(code >> (next_addr = addr + DOWN) & F_1x1)) { | 
					 | 
					 | 
					        if (filter != DOWN && addr <= 15 * 3 && !(code >> (next_addr = addr + DOWN) & F_1x1)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            release_1x1(-DOWN); // block can move down
 | 
					 | 
					 | 
					            release_1x1(-DOWN); // 1x1 block can move down
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if (filter != LEFT && (addr & 3) != 0 && !(code >> (next_addr = addr + LEFT) & F_1x1)) { | 
					 | 
					 | 
					        if (filter != LEFT && (addr & 3) != 0 && !(code >> (next_addr = addr + LEFT) & F_1x1)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            release_1x1(-LEFT); // block can move left
 | 
					 | 
					 | 
					            release_1x1(-LEFT); // 1x1 block can move left
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if (filter != RIGHT && (addr & 3) != 1 && !(code >> (next_addr = addr + RIGHT) & F_1x1)) { | 
					 | 
					 | 
					        if (filter != RIGHT && (addr & 3) != 1 && !(code >> (next_addr = addr + RIGHT) & F_1x1)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            release_1x1(-RIGHT); // block can move right
 | 
					 | 
					 | 
					            release_1x1(-RIGHT); // 1x1 block can move right
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					void move_1x2(uint64_t code, int addr) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    cache_size = 1; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    cache[0].code = code; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    cache[0].addr = addr; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    cache[0].filter = 0; // filter unset
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    int current = 0; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    while (current != cache_size) { // start bfs search
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        code = cache[current].code; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        addr = cache[current].addr; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        int next_addr; // address after block moved
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        int filter = cache[current++].filter; // case filter
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (filter != UP && addr >= 4 * 3 && !(code >> (next_addr = addr + UP) & F_1x2)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            release_1x2(-UP); // 1x2 block can move up
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (filter != DOWN && addr <= 14 * 3 && !(code >> (next_addr = addr + DOWN) & F_1x2)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            release_1x2(-DOWN); // 1x2 block can move down
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (filter != LEFT && (addr & 3) != 0 && !(code >> (next_addr = addr + LEFT) & F_1x1)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            release_1x2(-LEFT); // 1x2 block can move left
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (filter != RIGHT && (addr & 3) != 2 && !(code >> (next_addr = addr + RIGHT) & F_1x1_R)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            release_1x2(-RIGHT); // 1x2 block can move right
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -72,16 +97,49 @@ void move_1x1(uint64_t code, int addr) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					void next_step(uint64_t raw_code, uint64_t mask) { | 
					 | 
					 | 
					void next_step(uint64_t raw_code, uint64_t mask) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					//    int addr = 17;
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					//    raw_code = RawCode(CommonCode("4fea134")).unwrap();
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					//    move_1x1(raw_code, addr * 3);
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					//    int addr = 9;
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					//    raw_code = RawCode(CommonCode("1003")).unwrap();
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					//    move_1x1(raw_code, addr * 3);
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    int addr = 9; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    raw_code = RawCode(CommonCode("1001")).unwrap(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    move_1x2(raw_code, addr * 3); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    std::cout << RawCode(raw_code).dump_case();
 | 
					 | 
					 | 
					//    std::cout << RawCode(raw_code).dump_case();
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					//    printf("mask -> %016lX\n", mask);
 | 
					 | 
					 | 
					//    printf("mask -> %016lX\n", mask);
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    for (int i = 0; i < 1000000000; ++i) { | 
					 | 
					 | 
					//    for (int i = 0; i < 1000000000; ++i) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        move_1x1(raw_code, 17 * 3); | 
					 | 
					 | 
					//        move_1x1(raw_code, addr * 3);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    } | 
					 | 
					 | 
					//    }
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    std::cout << cache_size << std::endl; | 
					 | 
					 | 
					    for (int i = 0; i < cache_size; ++i) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    std::cout << RawCode(cache[0].code).dump_case() << std::endl; | 
					 | 
					 | 
					        std::cout << "=======" << std::endl; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    std::cout << RawCode(cache[1].code).dump_case() << std::endl; | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    std::cout << RawCode(cache[2].code).dump_case() << std::endl; | 
					 | 
					 | 
					        std::cout << RawCode(cache[i].code).dump_case(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (i != 0) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            auto _mask = cache[i].mask; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            std::cout << std::endl; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            for (int n = 0; n < 20; ++n, _mask >>= 3) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (_mask & 0b111) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    std::cout << "+ "; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                } else { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    std::cout << ". "; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if ((n & 0b11) == 0b11) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    std::cout << std::endl; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        std::cout << "=======" << std::endl << std::endl; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					
  |