Created
January 27, 2014 07:26
-
-
Save erning/8644403 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// $ gcc -std=c99 glowpz.c -o glowpz | |
// | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
const uint32_t ORIGIN = 0x0CCCC; // 0 1100 1100 1100 1100 | |
const uint32_t TARGET = 0x05A5A; // 0 0101 1010 0101 1010 | |
const char DIRECTION[] = {'U', 'R', 'D', 'L'}; | |
typedef struct node { | |
uint32_t v; | |
uint8_t d; | |
struct node *p; | |
struct node *next; | |
} node_t; | |
node_t* visited[16][65536]; | |
int display(uint32_t v) { | |
uint16_t t = v & 0xFFFF; | |
uint8_t s = v >> 16; | |
uint32_t b = 1; | |
for (int i = 0; i < 16; i++) { | |
char c = (i == s) ? '.' : (t & b) ? 'X' : 'O'; | |
printf(" %c", c); | |
if (i % 4 == 3) { | |
printf("\n"); | |
} | |
b <<= 1; | |
} | |
printf("\n"); | |
return 0; | |
} | |
uint32_t swap(uint8_t d, uint32_t v) { | |
uint16_t t = v & 0xFFFF; | |
uint8_t s = v >> 16; | |
uint16_t b; | |
if (d == 0 && s > 3) { | |
s -= 4; | |
b = (t & (1 << s)) << 4; | |
} else if (d == 1 && s % 4 < 3) { | |
s += 1; | |
b = (t & (1 << s)) >> 1; | |
} else if (d == 2 && s < 12) { | |
s += 4; | |
b = (t & (1 << s)) >> 4; | |
} else if (d == 3 && s % 4 > 0) { | |
s -= 1; | |
b = (t & (1 << s)) << 1; | |
} else { | |
return 0; | |
} | |
t |= b; | |
b = ~(1 << s); | |
t &= b; | |
return (s << 16) | t; | |
} | |
void display_nodes(node_t *node) { | |
node_t *head = node; | |
int s = 0; | |
while (node) { | |
s++; | |
display(node->v); | |
node = node->p; | |
} | |
char *r = malloc(s); | |
r += s - 1; | |
*r = 0; | |
node = head; | |
while (node->p) { | |
r--; | |
*r = DIRECTION[node->d]; | |
node = node->p; | |
} | |
printf("%s\n", r); | |
free(r); | |
} | |
void bfs(node_t *node) { | |
node_t *head = malloc(sizeof(node_t)); | |
head->next = 0; | |
node_t *tail = head; | |
while (node) { | |
if (node->v == TARGET) { | |
display_nodes(node); | |
return; | |
} | |
for (int d = 0; d < 4; d++) { | |
uint32_t v = swap(d, node->v); | |
if (v == 0) { | |
continue; | |
} | |
uint16_t t = v & 0xFFFF; | |
uint8_t s = v >> 16; | |
if (visited[s][t]) { | |
continue; | |
} | |
tail->next = malloc(sizeof(node_t)); | |
visited[s][t] = tail->next; | |
tail = tail->next; | |
tail->v = v; | |
tail->d = d; | |
tail->p = node; | |
tail->next = 0; | |
} | |
node = node->next; | |
} | |
bfs(head->next); | |
free(head); | |
} | |
int main(int argc, const char * argv[]) { | |
node_t *node = malloc(sizeof(node_t)); | |
node->v = ORIGIN; | |
node->d = 0; | |
node->next = 0; | |
bfs(node); | |
free(node); | |
for (int i = 0; i < 16; i++) { | |
for (int j = 0; j < 65535; j++) { | |
if (visited[i][j]) { | |
free(visited[i][j]); | |
} | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment