-
-
Save zid/8c560010fc3a3b9dd478996019f02b5e 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> | |
#include <ctype.h> | |
#define S 140 | |
struct node | |
{ | |
int x, y; | |
int n[2]; | |
struct node *next; | |
}; | |
struct row | |
{ | |
char c[S+3]; | |
}; | |
struct map | |
{ | |
struct row r[S+2]; | |
}; | |
static struct map m; | |
static struct node *list; | |
static void push(int num, int x, int y) | |
{ | |
struct node **t, *n; | |
for(t = &list; *t; t = &(*t)->next) | |
{ | |
if((*t)->x != x || (*t)->y != y) | |
continue; | |
if((*t)->n[0] == 0) | |
{ | |
(*t)->n[0] = num; | |
return; | |
} | |
else if((*t)->n[1] == 0) | |
{ | |
(*t)->n[1] = num; | |
return; | |
} | |
} | |
n = malloc(sizeof *n); | |
n->x = x; | |
n->y = y; | |
n->n[0] = num; | |
n->n[1] = 0; | |
n->next = list; | |
list = n; | |
} | |
static int ispuncty(int c) | |
{ | |
const char t[] = "*+$@/#&%=-"; | |
size_t i; | |
for(i = 0; i < sizeof t; i++) | |
if(c == t[i]) | |
return 1; | |
return 0; | |
} | |
static int ispuncty2(int c) | |
{ | |
return c == '*'; | |
} | |
#define D m.r[y+1].c[x+1] | |
const int xo[] = {-1, 0, 1, -1, 1, -1, 0, 1}; | |
const int yo[] = {-1, -1, -1, 0, 0, 1, 1, 1}; | |
static unsigned long part1_check_row(int y) | |
{ | |
int x = 0, num = 0, flag = 0; | |
unsigned long total = 0; | |
while(x <= S) | |
{ | |
if(!isdigit(D) && num) | |
{ | |
if(flag) | |
total += num; | |
flag = 0; | |
num = 0; | |
} | |
else if(D == '.') | |
; | |
else if(isdigit(D)) | |
{ | |
int i; | |
num *= 10; | |
num += D - '0'; | |
for(i = 0; i < 8; i++) | |
if(ispuncty(m.r[y+1+yo[i]].c[x+1+xo[i]])) | |
flag = 1; | |
} | |
x++; | |
} | |
return total; | |
} | |
static unsigned long part1(void) | |
{ | |
int y; | |
unsigned long total = 0; | |
for(y = 0; y < S; y++) | |
{ | |
total += part1_check_row(y); | |
} | |
return total; | |
} | |
static unsigned long part2_sum(void) | |
{ | |
struct node *n; | |
unsigned long sum = 0; | |
for(n = list; n; n = n->next) | |
if(n->n[0] && n->n[1]) | |
sum += (n->n[0] * n->n[1]); | |
return sum; | |
} | |
static void part2_check_row(int y) | |
{ | |
int x = 0, fx = 0, fy = 0, flag = 0, num = 0; | |
while(x <= S) | |
{ | |
if(!isdigit(D) && num) | |
{ | |
if(flag) | |
push(num, fx, fy); | |
flag = 0; | |
num = 0; | |
} | |
else if(D == '.') | |
; | |
else if(isdigit(D)) | |
{ | |
int i; | |
num *= 10; | |
num += D - '0'; | |
for(i = 0; i < 8; i++) | |
{ | |
if(ispuncty2(m.r[y+1+yo[i]].c[x+1+xo[i]])) | |
{ | |
flag = 1; fx = x+1+xo[i]; fy = y+1+yo[i]; | |
} | |
} | |
} | |
x++; | |
} | |
} | |
static unsigned long part2(void) | |
{ | |
int y; | |
for(y = 0; y < S; y++) | |
part2_check_row(y); | |
return part2_sum(); | |
} | |
int main(void) | |
{ | |
FILE *f; | |
unsigned long total = 0; | |
f = fopen(__FILE__ ".txt", "rb"); | |
if(!f) | |
{ | |
fprintf(stderr, "idiot\n"); | |
return 0; | |
} | |
memset(&m, '.', sizeof (struct map)); | |
while(1) | |
{ | |
char buf[256]; | |
static int i; | |
if(!fgets(buf, 256, f)) | |
break; | |
if(buf[0] == '\n' || buf[0] == '\r') | |
break; | |
*strchr(buf, '\r') = 0; | |
memcpy(&m.r[i+1].c[1], buf, S); | |
i++; | |
} | |
total = part1(); | |
printf("Part 1: %lu\n", total); | |
total = part2(); | |
printf("Part 2: %lu\n", total); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment