From 6847442511c4654c95120d8fc225f5aa7076ff0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dobos=20=C3=81d=C3=A1m?= Date: Thu, 22 Dec 2022 20:15:21 +0100 Subject: [PATCH] Day19 --- day19/input.txt | 30 +++++++ day19/robot | Bin 0 -> 16304 bytes day19/robot.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 day19/input.txt create mode 100755 day19/robot create mode 100644 day19/robot.c diff --git a/day19/input.txt b/day19/input.txt new file mode 100644 index 0000000..2c1044f --- /dev/null +++ b/day19/input.txt @@ -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. diff --git a/day19/robot b/day19/robot new file mode 100755 index 0000000000000000000000000000000000000000..15b6368fd5e7e4f74c7cf805aaa1af59ad45e064 GIT binary patch literal 16304 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 iC(`-Bfe##24UG#s2~U%a@V> literal 0 HcmV?d00001 diff --git a/day19/robot.c b/day19/robot.c new file mode 100644 index 0000000..4553fb0 --- /dev/null +++ b/day19/robot.c @@ -0,0 +1,206 @@ +#include +#include +#include +#include + +#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; +}