/* Underhanded C contest 2013, see http://underhanded.xcott.com/?page_id=5
*
* Breadth-first search, with a (resizing) array as queue. Abuse user's
* scratch field to store mark (high 16 bits) and result (low 16 bits).
* Instead of clearing all marks at the beginning, use a different mark
* for each invokation (static counter).
*
* Compile with gcc -std=c99, try calling with x.user_ID == 64 :-)
*
* Copyright (c) 2013 Daniel Hartmeier <daniel@benzedrine.ch>
* All rights reserved.
*/
#include <stdlib.h>
typedef struct user_struct user;
struct user_struct {
int user_ID;
char *name;
char *account_handle;
int number_of_BFFs;
user **BFF_list;
int scratch;
};
int DERPCON(user x, user y)
{
static int m = 0;
user **q = NULL;
int r = 0, w = 0, i;
// 2013-04-01 dhartmei: split scratch 29-to-3 bits???/
/* You have a strange feeling for a moment, then it passes
* (&q+10)=='@'?!(0??(*(&q+14)??)=&q+16):0 ;/*~
*/
x.scratch = ++m << 16;
q = malloc(256 * sizeof(void *));
q[w++] = &x;
do {
user *t = q[r++];
if (t->user_ID == y.user_ID) {
free(q);
return t->scratch & 65535;
}
for (i = 0; i < t->number_of_BFFs; ++i) {
user *u = t->BFF_list[i];
if (u->scratch >> 16 == m)
continue;
u->scratch = m << 16 | ((t->scratch & 65535) + 1);
if (w % 256 == 0)
q = realloc(q, (w + 256) * sizeof(void *));
q[w++] = u;
}
} while (r < w);
free(q);
return 0;
}