Skip to content

Instantly share code, notes, and snippets.

@zid

zid/2011-day13.c Secret

Last active December 13, 2022 19:34
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 zid/7d8250030d0de949407614b5ec033308 to your computer and use it in GitHub Desktop.
Save zid/7d8250030d0de949407614b5ec033308 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum TYPE
{
NUM,
SET
};
struct set
{
int count;
struct set *parent;
struct node *n[32];
};
struct node
{
int type;
union {
int num;
struct set *set;
};
};
static void set_add_set(struct set *s, struct set *n)
{
int i;
i = s->count++;
s->n[i] = malloc(sizeof (struct node));
s->n[i]->type = SET;
s->n[i]->set = n;
}
static void set_add_num(struct set *s, int n)
{
int i;
i = s->count++;
s->n[i] = malloc(sizeof (struct node));
s->n[i]->type = NUM;
s->n[i]->num = n;
}
static struct set *parse(char **s, struct set *parent)
{
struct set *n;
n = calloc(1, sizeof (struct set));
n->count = 0;
n->parent = parent;
while(**s && **s != '\n')
{
if(**s == ']')
{
(*s)++;
break;
}
if(**s == '[')
{
(*s)++;
set_add_set(n, parse(s, n));
continue;
}
if(**s == ',')
{
(*s)++;
continue;
}
if(**s >= '0' && **s <= '9')
{
set_add_num(n, strtol(*s, s, 10));
}
}
return n;
}
static void dump_set(struct set *s);
static void dump_node(struct node *n)
{
if(n->type == NUM)
{
printf("%d", n->num);
} else {
dump_set(n->set);
}
}
static void dump_set(struct set *s)
{
int i = 0;
struct node *n;
putchar('[');
for(i = 0; i < s->count; i++)
{
dump_node(s->n[i]);
if(s->n[i+1])
printf(", ");
}
putchar(']');
}
static int compare(struct set *s1, struct set *s2)
{
int i;
int left, right;
i = 0;
if(!s1)
return 1;
if(!s2)
return 0;
printf("s1: %d, s2: %d\n", s1->count, s2->count);
while(1)
{
if(i >= s1->count)
break;
if(i >= s2->count)
return 0;
if(s1->n[i]->type == NUM && s2->n[i]->type == NUM)
{
printf("Comparing %d vs %d\n", s1->n[i]->num, s2->n[i]->num);
if(s1->n[i]->num > s2->n[i]->num)
return 0;
}
else if(s1->n[i]->type == SET && s2->n[i]->type)
{
if(compare(s1->n[i]->set, s2->n[i]->set) == 0)
{
return 0;
}
}
else if(s1->n[i]->type == NUM && s2->n[i]->type == SET)
{
if(!s2->n[i]->set->count || s2->n[i]->set->n[0]->type == SET)
{
if(compare(s1, s2->n[i]->set) == 0)
return 0;
}else
if(s1->n[i]->num > s2->n[i]->set->n[0]->num)
return 0;
}
else if(s1->n[i]->type == SET && s2->n[i]->type == NUM)
{
if(!s1->n[i]->set->count || s1->n[i]->set->n[0]->type == SET)
{
if(compare(s1->n[i]->set, s2) == 0)
return 0;
} else
if(s1->n[i]->set->n[0]->num > s2->n[i]->num)
return 0;
}
i++;
}
return 1;
}
int main(void)
{
char line1[1024], line2[1024];
FILE *f;
f = fopen("day13.txt", "r");
int i = 1;
int sum = 0;
while(1)
{
struct set *set1, *set2;
char *p1, *p2;
if(!fgets(line1, 1024, f))
break;
fgets(line2, 1024, f);
line1[strlen(line1)-1] = 0;
line2[strlen(line2)-1] = 0;
p1 = line1;
p2 = line2;
set1 = parse(&p1, NULL);
set2 = parse(&p2, NULL);
dump_set(set1);
putchar('\n');
dump_set(set2);
putchar('\n');
int r = compare(set1, set2);
printf("\t\tResult: %d\n", r);
if(r)
sum += i;
i++;
/* Eat the newline between pairs */
if(!fgets(line1, 1024, f))
break;
}
printf("sum: %d\n", sum);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment