-
-
Save zid/7d8250030d0de949407614b5ec033308 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
#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