92 lines
2.8 KiB
C
92 lines
2.8 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
|
|
#define LINELENGTH 150
|
|
#define NEXT(X) ((X + 3 + 1) % 3)
|
|
#define PREV(X) ((X + 3 - 1) % 3)
|
|
|
|
/* I wish I had python generator or Go coroutine... */
|
|
#define STATE_BEGIN 0
|
|
#define STATE_READING 1
|
|
#define STATE_END 2
|
|
int read_state = STATE_BEGIN;
|
|
|
|
/* Return at least 3 lines; first and last lines and first chars are all '.' */
|
|
char* readline(char* buf, int max_size) {
|
|
switch (read_state) {
|
|
case STATE_BEGIN:
|
|
memset(buf, '.', max_size);
|
|
buf[max_size - 2] = '\n';
|
|
buf[max_size - 1] = '\0';
|
|
read_state = STATE_READING;
|
|
return buf;
|
|
case STATE_READING:
|
|
buf[0] = '.';
|
|
if (!fgets(buf + 1, max_size, stdin)) {
|
|
memset(buf, '.', max_size);
|
|
buf[max_size - 2] = '\n';
|
|
buf[max_size - 1] = '\0';
|
|
read_state = STATE_END;
|
|
}
|
|
return buf;
|
|
case STATE_END:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
#define IS_STAR(buf, i, j) (buf[i][j] == '*')
|
|
#define CHECK_STAR(buf, i, j, gear1, gear2, num) \
|
|
if (IS_STAR(buf, i, j)) { \
|
|
if (gear1[i][j] && gear1[i][j] != num) { \
|
|
gear2[i][j] = num; \
|
|
} else { \
|
|
gear1[i][j] = num; \
|
|
} \
|
|
}
|
|
|
|
int main(void) {
|
|
char buf[3][LINELENGTH];
|
|
int* gear1[3][LINELENGTH];
|
|
int* gear2[3][LINELENGTH];
|
|
memset(gear1, 0, sizeof(gear1));
|
|
memset(gear2, 0, sizeof(gear2));
|
|
int sum = 0;
|
|
int* num;
|
|
|
|
readline(buf[0], LINELENGTH);
|
|
readline(buf[1], LINELENGTH);
|
|
for (int i = 1; readline(buf[NEXT(i)], LINELENGTH); i = NEXT(i)) {
|
|
|
|
for (int j = 1; buf[i][j]; j++) { // j = 0 is '.' guard
|
|
if (buf[i][j] >= '0' && buf[i][j] <= '9') {
|
|
num = num ? num : (int*) malloc(sizeof(int));
|
|
*num = *num * 10 + (buf[i][j] - '0');
|
|
CHECK_STAR(buf, i, j - 1, gear1, gear2, num);
|
|
CHECK_STAR(buf, i, j + 1, gear1, gear2, num);
|
|
CHECK_STAR(buf, PREV(i), j, gear1, gear2, num);
|
|
CHECK_STAR(buf, NEXT(i), j, gear1, gear2, num);
|
|
CHECK_STAR(buf, PREV(i), j - 1, gear1, gear2, num);
|
|
CHECK_STAR(buf, PREV(i), j + 1, gear1, gear2, num);
|
|
CHECK_STAR(buf, NEXT(i), j - 1, gear1, gear2, num);
|
|
CHECK_STAR(buf, NEXT(i), j + 1, gear1, gear2, num);
|
|
} else {
|
|
num = NULL;
|
|
}
|
|
}
|
|
|
|
for (int j = 1; buf[PREV(i)][j]; j++) {
|
|
if (gear1[PREV(i)][j] && gear2[PREV(i)][j]) {
|
|
sum += (*gear1[PREV(i)][j]) * (*gear2[PREV(i)][j]);
|
|
}
|
|
}
|
|
memset(gear1[PREV(i)], 0, sizeof(gear1[PREV(i)]));
|
|
memset(gear2[PREV(i)], 0, sizeof(gear2[PREV(i)]));
|
|
}
|
|
|
|
printf("%d\n", sum);
|
|
return 0;
|
|
}
|
|
|