Skip to content

Instantly share code, notes, and snippets.

@erning
Created January 27, 2014 07:26
Show Gist options
  • Save erning/8644403 to your computer and use it in GitHub Desktop.
Save erning/8644403 to your computer and use it in GitHub Desktop.
//
// $ 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