114 lines
2.9 KiB
C
114 lines
2.9 KiB
C
|
|
#include <stdint.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <omp.h>
|
||
|
|
|
||
|
|
#define CHARS_MAX 1024
|
||
|
|
#define MAX_EQUATIONS 32*1024
|
||
|
|
#define MAX_EQUATION_VALUES 128
|
||
|
|
|
||
|
|
typedef struct equation {
|
||
|
|
uint64_t result;
|
||
|
|
uint64_t *values;
|
||
|
|
int values_count;
|
||
|
|
} equation_t;
|
||
|
|
|
||
|
|
int solvable(equation_t, int);
|
||
|
|
|
||
|
|
int main() {
|
||
|
|
char *p, *buf, c;
|
||
|
|
|
||
|
|
buf = calloc(CHARS_MAX, sizeof(char));
|
||
|
|
p = buf;
|
||
|
|
|
||
|
|
equation_t *equations = calloc(MAX_EQUATIONS, sizeof(equations[0]));
|
||
|
|
int equation_count = 0;
|
||
|
|
|
||
|
|
while ((c = getchar()) != EOF) {
|
||
|
|
*p++ = c;
|
||
|
|
if (c != '\n') {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
p = buf;
|
||
|
|
|
||
|
|
sscanf(p, "%lu", &equations[equation_count].result);
|
||
|
|
while (*p++ != ':');
|
||
|
|
|
||
|
|
equations[equation_count].values = calloc(MAX_EQUATION_VALUES, sizeof(equations[0].values[0]));
|
||
|
|
do {
|
||
|
|
p++;
|
||
|
|
sscanf(p, "%lu", &equations[equation_count].values[equations[equation_count].values_count]);
|
||
|
|
equations[equation_count].values_count++;
|
||
|
|
while(*p != ' ' && *p != '\n') p++;
|
||
|
|
} while (*p != '\n');
|
||
|
|
|
||
|
|
memset(buf, 0, CHARS_MAX);
|
||
|
|
p = buf;
|
||
|
|
equation_count++;
|
||
|
|
}
|
||
|
|
|
||
|
|
free(buf);
|
||
|
|
|
||
|
|
uint64_t count = 0;
|
||
|
|
uint64_t count2 = 0;
|
||
|
|
#pragma omp parallel for
|
||
|
|
for (int i = 0; i < equation_count; i++) {
|
||
|
|
if (solvable(equations[i], 0))
|
||
|
|
#pragma omp critical
|
||
|
|
{
|
||
|
|
count += equations[i].result;
|
||
|
|
}
|
||
|
|
if (solvable(equations[i], 1))
|
||
|
|
#pragma omp critical
|
||
|
|
{
|
||
|
|
count2 += equations[i].result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int i = 0; i < equation_count; i++) {
|
||
|
|
free(equations[i].values);
|
||
|
|
}
|
||
|
|
free(equations);
|
||
|
|
|
||
|
|
printf("%lu\n", count);
|
||
|
|
printf("%lu\n", count2);
|
||
|
|
}
|
||
|
|
|
||
|
|
int solvable(equation_t equation, int concat_allowed) {
|
||
|
|
uint64_t sum = equation.values[0] + equation.values[1];
|
||
|
|
uint64_t product = equation.values[0] * equation.values[1];
|
||
|
|
uint64_t concat;
|
||
|
|
// Concat
|
||
|
|
char buf[128];
|
||
|
|
sprintf(buf, "%lu%lu", equation.values[0], equation.values[1]);
|
||
|
|
sscanf(buf, "%lu", &concat);
|
||
|
|
if (equation.values_count == 2) {
|
||
|
|
return (sum == equation.result) || (product == equation.result) || (concat == equation.result);
|
||
|
|
}
|
||
|
|
|
||
|
|
uint64_t *values_tmp = calloc(equation.values_count - 1, sizeof(values_tmp[0]));
|
||
|
|
|
||
|
|
// Add
|
||
|
|
values_tmp[0] = sum;
|
||
|
|
memcpy(values_tmp + 1, equation.values + 2, (equation.values_count - 2) * sizeof(values_tmp[0]));
|
||
|
|
equation_t tmp = {
|
||
|
|
.result = equation.result,
|
||
|
|
.values_count = equation.values_count - 1,
|
||
|
|
.values = values_tmp,
|
||
|
|
};
|
||
|
|
|
||
|
|
int solvable_sum = solvable(tmp, concat_allowed);
|
||
|
|
|
||
|
|
// Multiply
|
||
|
|
values_tmp[0] = product;
|
||
|
|
int solvable_product = solvable(tmp, concat_allowed);
|
||
|
|
|
||
|
|
// Concat
|
||
|
|
values_tmp[0] = concat;
|
||
|
|
int solvable_concat = concat_allowed ? solvable(tmp, 1) : 0;
|
||
|
|
|
||
|
|
free(values_tmp);
|
||
|
|
return solvable_sum || solvable_product || solvable_concat;
|
||
|
|
}
|