Day13
This commit is contained in:
BIN
day13/c/day13
Executable file
BIN
day13/c/day13
Executable file
Binary file not shown.
149
day13/c/day13.c
Normal file
149
day13/c/day13.c
Normal file
@@ -0,0 +1,149 @@
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <omp.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
1279
day13/input.txt
Normal file
1279
day13/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
15
day13/sample.txt
Normal file
15
day13/sample.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
Button A: X+94, Y+34
|
||||
Button B: X+22, Y+67
|
||||
Prize: X=8400, Y=5400
|
||||
|
||||
Button A: X+26, Y+66
|
||||
Button B: X+67, Y+21
|
||||
Prize: X=12748, Y=12176
|
||||
|
||||
Button A: X+17, Y+86
|
||||
Button B: X+84, Y+37
|
||||
Prize: X=7870, Y=6450
|
||||
|
||||
Button A: X+69, Y+23
|
||||
Button B: X+27, Y+71
|
||||
Prize: X=18641, Y=10279
|
||||
Reference in New Issue
Block a user