#include #include #include #include #include #include #define CHARS_MAX 64 #define MAX_MACHINES 1024 #define max(a,b) ((a) > (b) ? (a) : (b)) #define min(a,b) ((a) < (b) ? (a) : (b)) typedef struct button { uint64_t x; uint64_t y; } button_t; typedef struct machine { button_t button_A; button_t button_B; uint64_t x; uint64_t y; } machine_t; int64_t extended_euclidian(int64_t a, int64_t b, int64_t *x, int64_t *y); int main() { char *p, *buf, c; buf = calloc(CHARS_MAX, sizeof(char)); p = buf; int step = 0; machine_t *machines = calloc(MAX_MACHINES, sizeof(machines[0])); int machine_count = 0; while ((c = getchar()) != EOF) { *p++ = c; if (c != '\n') { continue; } switch (step) { case 0: p = buf; while (*p != '+') p++; p++; sscanf(p, "%lu", &machines[machine_count].button_A.x); while (*p != '+') p++; p++; sscanf(p, "%lu", &machines[machine_count].button_A.y); break; case 1: p = buf; while (*p != '+') p++; p++; sscanf(p, "%lu", &machines[machine_count].button_B.x); while (*p != '+') p++; p++; sscanf(p, "%lu", &machines[machine_count].button_B.y); break; case 2: p = buf; while (*p != '=') p++; p++; sscanf(p, "%lu", &machines[machine_count].x); while (*p != '=') p++; p++; sscanf(p, "%lu", &machines[machine_count].y); machine_count++; break; case 3: break; } step++; if (step == 4) { step = 0; } memset(buf, 0, CHARS_MAX); p = buf; } free(buf); uint64_t tokens = 0; #pragma omp parallel for for (int i = 0; i < machine_count; i++) { uint64_t least_tokens = 0; for (int j = 0; j <= 100; j++) { for (int k = 0; k <= 100; k++) { int x = machines[i].button_A.x * j + machines[i].button_B.x * k; int y = machines[i].button_A.y * j + machines[i].button_B.y * k; if (x == machines[i].x && y == machines[i].y) { uint64_t current_tokens = 3 * j + k; if (least_tokens == 0 || least_tokens > current_tokens) { least_tokens = current_tokens; } } } } #pragma omp critical { tokens += least_tokens; } } printf("%lu\n", tokens); double ttokens = 0.0; for (int i = 0; i < machine_count; i++) { machines[i].x += 10000000000000; machines[i].y += 10000000000000; //printf("%i %lu %lu %lu %lu %lu %lu\n", i, machines[i].x, machines[i].y, machines[i].button_A.x, machines[i].button_A.y, machines[i].button_B.x, machines[i].button_B.y); int64_t x, y; double a = (double)machines[i].button_A.x - (double)machines[i].button_A.y; double b = (int64_t)machines[i].button_B.x - (double)machines[i].button_B.y; double c = (double)machines[i].x - (double)machines[i].y; double k2 = ((double)machines[i].x - (double)machines[i].button_A.x * c / a) / ((double)machines[i].button_B.x - (double)machines[i].button_A.x * b / a); double k1 = (c - b * k2) / a; double tmp; double r1 = modf(k1, &tmp); double r2 = modf(k2, &tmp); if ((r1 < 0.001 || r1 > 0.999) && (r2 < 0.001 || r2 > 0.999)) { ttokens += k1 * 3.0 + k2; } } printf("%0.0f\n", ttokens); free(machines); } int64_t extended_euclidian(int64_t a, int64_t b, int64_t *x, int64_t *y) { if (a == 0) { *x = 0; *y = 1; return b; } int64_t x1, y1; int64_t gcd = extended_euclidian(b % a, a, &x1, &y1); *x = y1 - (b / a) * x1; *y = x1; return gcd; }