Skip to content

Instantly share code, notes, and snippets.

@kashi
Created November 23, 2013 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kashi/7611514 to your computer and use it in GitHub Desktop.
Save kashi/7611514 to your computer and use it in GitHub Desktop.
/*
http://nabetani.sakura.ne.jp/codeiq/tetromino_bingo/
*/
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 1024
/*
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
*/
#define P(x) (1L << (x))
#define R(x) (P((x)*5)|P((x)*5+1)|P((x)*5+2)|P((x)*5+3)|P((x)*5+4))
#define SHIFT_UP(x) ((x) >> 5)
#define SHIFT_LEFT(x) (((((x)&R(0))>>1)&R(0))|((((x)&R(1))>>1)&R(1))|((((x)&R(2))>>1)&R(2))|((((x)&R(3))>>1)&R(3))|((((x)&R(4))>>1)&R(4)))
#define SHIFT_RIGHT(x) (((((x)&R(0))<<1)&R(0))|((((x)&R(1))<<1)&R(1))|((((x)&R(2))<<1)&R(2))|((((x)&R(3))<<1)&R(3))|((((x)&R(4))<<1)&R(4)))
#define SHIFT_DOWN(x) (((x) << 5) & (R(0)|R(1)|R(2)|R(3)|R(4)))
char tetname[] = { 'I', 'L', 'O', 'S', 'T' };
long tetorig[][4] = {
/* name, width, height, mask */
/* I */
{ 0, 1, 4, P(0)|P(5)|P(10)|P(15) },
{ 0, 4, 1, P(0)|P(1)|P(2)|P(3) },
/* L */
{ 1, 2, 3, P(0)|P(5)|P(10)|P(11) },
{ 1, 3, 2, P(2)|P(5)|P(6)|P(7) },
{ 1, 2, 3, P(0)|P(1)|P(6)|P(11) },
{ 1, 3, 2, P(0)|P(1)|P(2)|P(5) },
/* L(J) */
{ 1, 2, 3, P(1)|P(6)|P(10)|P(11) },
{ 1, 3, 2, P(0)|P(5)|P(6)|P(7) },
{ 1, 2, 3, P(0)|P(1)|P(5)|P(10) },
{ 1, 3, 2, P(0)|P(1)|P(2)|P(7) },
/* O */
{ 2, 2, 2, P(0)|P(1)|P(5)|P(6) },
/* S */
{ 3, 2, 3, P(1)|P(5)|P(6)|P(10) },
{ 3, 3, 2, P(0)|P(1)|P(6)|P(7) },
/* Z(S) */
{ 3, 2, 3, P(0)|P(5)|P(6)|P(11) },
{ 3, 3, 2, P(1)|P(2)|P(5)|P(6) },
/* T */
{ 4, 3, 2, P(0)|P(1)|P(2)|P(6) },
{ 4, 2, 3, P(0)|P(5)|P(6)|P(10) },
{ 4, 3, 2, P(1)|P(5)|P(6)|P(7) },
{ 4, 2, 3, P(1)|P(5)|P(6)|P(11) },
{ -1, 0, 0, 0}
};
int balls[100], numball, numcard;
struct cardpos {
int card;
int pos;
struct cardpos *next;
};
struct cardpos *cphead[100], *cptail[100];
struct tettest {
int name;
long mask;
long negmask;
struct tettest *next;
};
struct tettest *tethead, *tettail;
void readdata()
{
FILE *fin;
char buf[BUFSIZE], *p;
int i, x;
fin = fopen("data.txt", "rt");
if (fin == NULL) {
fprintf(stderr, "data.txt not found\n");
exit(1);
}
/* read balls */
numball = 0;
x = 0;
fgets(buf, BUFSIZE, fin);
p = buf;
while (!0) {
if ('0' <= *p && *p <= '9') {
x = x * 10 + *p - '0';
} else if (x > 0) {
balls[numball++] = x;
x = 0;
}
if (*p == '\0') break;
p++;
}
if (x > 0) balls[numball++] = x;
/* read cards */
numcard = 0;
fgets(buf, BUFSIZE, fin);
while (!feof(fin)) {
i = 0;
x = 0;
p = buf;
while (!0) {
if ('0' <= *p && *p <= '9') {
x = x * 10 + *p - '0';
} else if (x > 0) {
if (cphead[x] == NULL) {
cphead[x] = cptail[x] = (struct cardpos *)malloc(sizeof(struct cardpos));
} else {
cptail[x]->next = (struct cardpos *)malloc(sizeof(struct cardpos));
cptail[x] = cptail[x]->next;
}
cptail[x]->card = numcard;
cptail[x]->pos = i;
cptail[x]->next = NULL;
i++;
x = 0;
}
if (*p == '\0') break;
p++;
}
numcard++;
fgets(buf, BUFSIZE, fin);
}
}
void init()
{
int i, j, k;
long x, x0, negx;
for (i=0; i<100; i++) cphead[i] = cptail[i] = NULL;
readdata();
/* init test masks */
tethead = tettail = NULL;
for (i=0; tetorig[i][0] != -1; i++) {
x0 = tetorig[i][3];
for (j=0; j<=5-tetorig[i][2]; j++) {
x = x0;
for (k=0; k<=5-tetorig[i][1]; k++) {
if (tethead == NULL) {
tethead = tettail = (struct tettest *)malloc(sizeof(struct tettest));
} else {
tettail->next = (struct tettest *)malloc(sizeof(struct tettest));
tettail = tettail->next;
}
tettail->name = tetorig[i][0];
tettail->mask = x;
negx = SHIFT_UP(x)|SHIFT_LEFT(x)|SHIFT_RIGHT(x)|SHIFT_DOWN(x);
tettail->negmask = (negx & ~x & (R(0)|R(1)|R(2)|R(3)|R(4)));
tettail->next = NULL;
x = SHIFT_RIGHT(x);
}
x0 = SHIFT_DOWN(x0);
}
}
}
int main()
{
int i, counter[5];
long *card;
struct cardpos *pcp;
struct tettest *ptt;
init();
card = (long *)malloc(numcard * sizeof(long));
for (i=0; i<5; i++) counter[i] = 0;
for (i=0; i<numball; i++) {
pcp = cphead[balls[i]];
while (pcp != NULL) {
if (card[pcp->card] != -1) {
card[pcp->card] |= P(pcp->pos);
ptt = tethead;
while (ptt != NULL) {
if (((card[pcp->card] & ptt->mask) == ptt->mask)
&& (card[pcp->card] & ptt->negmask) == 0) {
counter[ptt->name]++;
card[pcp->card] = -1;
break;
}
ptt = ptt->next;
}
}
pcp = pcp->next;
}
}
for (i=0; i<5; i++) {
printf("%c:%d\n", tetname[i], counter[i]);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment