Day19
This commit is contained in:
30
day19/input.txt
Normal file
30
day19/input.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 12 clay. Each geode robot costs 4 ore and 19 obsidian.
|
||||||
|
Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 11 clay. Each geode robot costs 4 ore and 12 obsidian.
|
||||||
|
Blueprint 3: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 2 ore and 11 obsidian.
|
||||||
|
Blueprint 4: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 4 ore and 20 obsidian.
|
||||||
|
Blueprint 5: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 4 ore and 17 obsidian.
|
||||||
|
Blueprint 6: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 19 clay. Each geode robot costs 2 ore and 12 obsidian.
|
||||||
|
Blueprint 7: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 9 clay. Each geode robot costs 2 ore and 10 obsidian.
|
||||||
|
Blueprint 8: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 7 obsidian.
|
||||||
|
Blueprint 9: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 4 ore and 8 obsidian.
|
||||||
|
Blueprint 10: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 2 ore and 15 obsidian.
|
||||||
|
Blueprint 11: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 2 ore and 19 obsidian.
|
||||||
|
Blueprint 12: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 16 clay. Each geode robot costs 3 ore and 20 obsidian.
|
||||||
|
Blueprint 13: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 3 ore and 14 obsidian.
|
||||||
|
Blueprint 14: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 15 obsidian.
|
||||||
|
Blueprint 15: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 3 ore and 12 obsidian.
|
||||||
|
Blueprint 16: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 3 ore and 19 obsidian.
|
||||||
|
Blueprint 17: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 4 ore and 9 obsidian.
|
||||||
|
Blueprint 18: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 6 clay. Each geode robot costs 3 ore and 16 obsidian.
|
||||||
|
Blueprint 19: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 6 clay. Each geode robot costs 2 ore and 14 obsidian.
|
||||||
|
Blueprint 20: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 11 clay. Each geode robot costs 3 ore and 15 obsidian.
|
||||||
|
Blueprint 21: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 4 ore and 19 obsidian.
|
||||||
|
Blueprint 22: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||||
|
Blueprint 23: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 5 clay. Each geode robot costs 2 ore and 10 obsidian.
|
||||||
|
Blueprint 24: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 10 clay. Each geode robot costs 2 ore and 14 obsidian.
|
||||||
|
Blueprint 25: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 4 ore and 13 obsidian.
|
||||||
|
Blueprint 26: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||||
|
Blueprint 27: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 2 ore and 19 obsidian.
|
||||||
|
Blueprint 28: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 10 clay. Each geode robot costs 2 ore and 7 obsidian.
|
||||||
|
Blueprint 29: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 7 obsidian.
|
||||||
|
Blueprint 30: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 4 ore and 18 obsidian.
|
||||||
BIN
day19/robot
Executable file
BIN
day19/robot
Executable file
Binary file not shown.
206
day19/robot.c
Normal file
206
day19/robot.c
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
#include <endian.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 256
|
||||||
|
#define MAX_BLUEPRINT 128
|
||||||
|
#define MAX_TIME 24
|
||||||
|
#define PART_TWO_NUM 3
|
||||||
|
#define PART_TWO_TIME 32
|
||||||
|
|
||||||
|
#define max(a,b) (a >= b ? a : b)
|
||||||
|
|
||||||
|
typedef struct blueprint {
|
||||||
|
int ore_cost;
|
||||||
|
int clay_cost;
|
||||||
|
int obsidian_cost[2];
|
||||||
|
int geode_cost[2];
|
||||||
|
} BLUEPRINT;
|
||||||
|
|
||||||
|
int bestGeode(BLUEPRINT, int[], int[], int, int);
|
||||||
|
|
||||||
|
int bestMax = 0;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char buf[BUFFER_SIZE], *p, c;
|
||||||
|
memset(buf, 0, BUFFER_SIZE);
|
||||||
|
p = buf;
|
||||||
|
BLUEPRINT blueprints[MAX_BLUEPRINT];
|
||||||
|
int blueprint_count = 0;
|
||||||
|
|
||||||
|
while ((c = getchar()) != EOF) {
|
||||||
|
*p++ = c;
|
||||||
|
if (c == '\n') {
|
||||||
|
sscanf(buf, "Blueprint %*i: Each ore robot costs %i ore. Each clay robot costs %i ore. Each obsidian robot costs %i ore and %i clay. Each geode robot costs %i ore and %i obsidian.", &blueprints[blueprint_count].ore_cost, &blueprints[blueprint_count].clay_cost, &blueprints[blueprint_count].obsidian_cost[0], &blueprints[blueprint_count].obsidian_cost[1], &blueprints[blueprint_count].geode_cost[0], &blueprints[blueprint_count].geode_cost[1]);
|
||||||
|
blueprint_count++;
|
||||||
|
memset(buf, 0, BUFFER_SIZE);
|
||||||
|
p = buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int *quality_levels = (int*)malloc(blueprint_count * sizeof(int));
|
||||||
|
memset(quality_levels, 0, blueprint_count * sizeof(int));
|
||||||
|
// Check each blueprint
|
||||||
|
for (int i = 0; i < blueprint_count; i++) {
|
||||||
|
bestMax = 0;
|
||||||
|
int stash[4] = {0,0,0,0};
|
||||||
|
int robots[4] = {1,0,0,0};
|
||||||
|
|
||||||
|
|
||||||
|
quality_levels[i] = bestGeode(blueprints[i], stash, robots, 0, MAX_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < blueprint_count; i++) {
|
||||||
|
sum += (i+1) * quality_levels[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%i\n", sum);
|
||||||
|
free(quality_levels);
|
||||||
|
|
||||||
|
|
||||||
|
unsigned product = 1;
|
||||||
|
for (int i = 0; i < PART_TWO_NUM; i++) {
|
||||||
|
bestMax = 0;
|
||||||
|
int stash[4] = {0,0,0,0};
|
||||||
|
int robots[4] = {1,0,0,0};
|
||||||
|
|
||||||
|
product *= bestGeode(blueprints[i], stash, robots, 0, PART_TWO_TIME);
|
||||||
|
}
|
||||||
|
printf("%u\n", product);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bestGeode(BLUEPRINT blueprint, int stash[], int robots[], int sum, int time) {
|
||||||
|
if (time <= 0) {
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pompom = 0;
|
||||||
|
for (int i = 1; i <= time; i+=2) {
|
||||||
|
pompom += i;
|
||||||
|
}
|
||||||
|
if (bestMax > sum + pompom) {
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int max = sum;
|
||||||
|
int stashCopy[4];
|
||||||
|
memcpy(stashCopy, stash, 4*sizeof(int));
|
||||||
|
int robotsCopy[4];
|
||||||
|
memcpy(robotsCopy, robots, 4*sizeof(int));
|
||||||
|
|
||||||
|
// At every step we decide what robot will we build next (if we can)
|
||||||
|
int mostGeodes = 0;
|
||||||
|
|
||||||
|
// Ore robot
|
||||||
|
int timeCost = 0, timeCost2 = 0;
|
||||||
|
while (stash[0] + timeCost*robots[0] < blueprint.ore_cost) {
|
||||||
|
timeCost++;
|
||||||
|
}
|
||||||
|
// Build time
|
||||||
|
timeCost++;
|
||||||
|
// We don't have the time left to build this
|
||||||
|
if (time - timeCost >= 0) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
stash[j] = stash[j] + timeCost * robots[j];
|
||||||
|
}
|
||||||
|
stash[0] -= blueprint.ore_cost;
|
||||||
|
robots[0]++;
|
||||||
|
mostGeodes = bestGeode(blueprint, stash, robots, sum, time - timeCost);
|
||||||
|
memcpy(stash, stashCopy, 4*sizeof(int));
|
||||||
|
memcpy(robots, robotsCopy, 4*sizeof(int));
|
||||||
|
|
||||||
|
if (mostGeodes > max) {
|
||||||
|
max = mostGeodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clay robot
|
||||||
|
timeCost = 0;
|
||||||
|
while (stash[0] + timeCost*robots[0] < blueprint.clay_cost) {
|
||||||
|
timeCost++;
|
||||||
|
}
|
||||||
|
// Build time
|
||||||
|
timeCost++;
|
||||||
|
// We don't have the time left to build this
|
||||||
|
if (time - timeCost >= 0) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
stash[j] = stash[j] + timeCost * robots[j];
|
||||||
|
}
|
||||||
|
stash[0] -= blueprint.clay_cost;
|
||||||
|
robots[1]++;
|
||||||
|
mostGeodes = bestGeode(blueprint, stash, robots, sum, time - timeCost);
|
||||||
|
memcpy(stash, stashCopy, 4*sizeof(int));
|
||||||
|
memcpy(robots, robotsCopy, 4*sizeof(int));
|
||||||
|
if (mostGeodes > max) {
|
||||||
|
max = mostGeodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obsidian robot
|
||||||
|
// Only if we have at least 1 clay robot
|
||||||
|
if (robots[1] > 0) {
|
||||||
|
timeCost = timeCost2 = 0;
|
||||||
|
while (stash[0] + timeCost*robots[0] < blueprint.obsidian_cost[0]) {
|
||||||
|
timeCost++;
|
||||||
|
}
|
||||||
|
while (stash[1] + timeCost2*robots[1] < blueprint.obsidian_cost[1]) {
|
||||||
|
timeCost2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeCost = max(timeCost, timeCost2);
|
||||||
|
// build time
|
||||||
|
timeCost++;
|
||||||
|
if (time - timeCost >= 0) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
stash[j] = stash[j] + timeCost * robots[j];
|
||||||
|
}
|
||||||
|
stash[0] -= blueprint.obsidian_cost[0];
|
||||||
|
stash[1] -= blueprint.obsidian_cost[1];
|
||||||
|
robots[2]++;
|
||||||
|
mostGeodes = bestGeode(blueprint, stash, robots, sum, time - timeCost);
|
||||||
|
memcpy(stash, stashCopy, 4*sizeof(int));
|
||||||
|
memcpy(robots, robotsCopy, 4*sizeof(int));
|
||||||
|
if (mostGeodes > max) {
|
||||||
|
max = mostGeodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Geode robot
|
||||||
|
// Only if we have at least 1 obsidian robot
|
||||||
|
if (robots[2] > 0) {
|
||||||
|
timeCost = timeCost2 = 0;
|
||||||
|
while (stash[0] + timeCost*robots[0] < blueprint.geode_cost[0]) {
|
||||||
|
timeCost++;
|
||||||
|
}
|
||||||
|
while (stash[2] + timeCost2*robots[2] < blueprint.geode_cost[1]) {
|
||||||
|
timeCost2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeCost = max(timeCost, timeCost2);
|
||||||
|
// build time
|
||||||
|
timeCost++;
|
||||||
|
if (time - timeCost >= 0) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
stash[j] = stash[j] + timeCost * robots[j];
|
||||||
|
}
|
||||||
|
stash[0] -= blueprint.geode_cost[0];
|
||||||
|
stash[2] -= blueprint.geode_cost[1];
|
||||||
|
robots[3]++;
|
||||||
|
mostGeodes = bestGeode(blueprint, stash, robots, sum + (time - timeCost), time - timeCost);
|
||||||
|
memcpy(stash, stashCopy, 4*sizeof(int));
|
||||||
|
memcpy(robots, robotsCopy, 4*sizeof(int));
|
||||||
|
if (mostGeodes > max) {
|
||||||
|
max = mostGeodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max > bestMax) {
|
||||||
|
bestMax = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user