#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include "aocdailies.h" #include "aocutils.h" void aoc201504(char *data, size_t len) { data[--len] = 0; // remove newline, adjust `len` char longkey[128]; unsigned extra = 1; for (;;) { sprintf(longkey, "%s%u", data, extra); unsigned char tmp[16]; md5mini(tmp, longkey); if ((tmp[0] == 0) && (tmp[1] == 0) && (tmp[2] < 16)) break; extra++; } printf("Follow your key with %u to obtain five zeroes\n", extra); for (;;) { sprintf(longkey, "%s%u", data, extra); unsigned char tmp[16]; md5mini(tmp, longkey); if ((tmp[0] == 0) && (tmp[1] == 0) && (tmp[2] == 0)) break; extra++; } printf("Follow your key with %u to obtain six zeroes\n", extra); } struct House { int row, col; }; void aoc201503(char *data, size_t len) { (void)len; // unused argument char *data2 = data; // save it struct House *house = malloc(512 * sizeof *house); // assume it worked unsigned mhouse = 512, nhouse = 1; house[0].row = house[0].col = 0; // house at [0, 0] visited int x = 0, y = 0; while (*data) { switch (*data) { default: break; case '^': y++; break; case 'v': y--; break; case '>': x++; break; case '<': x--; break; } data++; bool visited = false; for (size_t k = 0; k < nhouse; k++) { if ((house[k].row == x) && (house[k].col == y)) { visited = true; break; } } if (!visited) { if (nhouse == mhouse) { // grow the array (by golden ratio) struct House *tmp = realloc(house, (13*mhouse) / 8 * sizeof *house); if (!tmp) { fprintf(stderr, "no memory. program aborted\n"); exit(EXIT_FAILURE); } house = tmp; mhouse = (13*mhouse) / 8; } house[nhouse].row = x; house[nhouse].col = y; nhouse += 1; } } printf("Santa delivered at least 1 present to %u houses.\n", nhouse); // reuse house array for part 2; don't worry about its contents nhouse = 1; // house at [0, 0] still visited :) struct House p[2] = {0}; // coordinates of santa and bot int who = 0; // 0: santa; 1: santa bot // go around from the beginning while (*data2) { switch (*data2) { default: break; case '^': p[who].row++; break; case 'v': p[who].row--; break; case '>': p[who].col++; break; case '<': p[who].col--; break; } data2++; bool visited = false; for (size_t k = 0; k < nhouse; k++) { if ((house[k].row == p[who].row) && (house[k].col == p[who].col)) { visited = true; break; } } if (!visited) { if (nhouse == mhouse) { // grow the array (by golden ratio) struct House *tmp = realloc(house, (13*mhouse) / 8 * sizeof *house); if (!tmp) { fprintf(stderr, "no memory. program aborted\n"); exit(EXIT_FAILURE); } house = tmp; mhouse = (13*mhouse) / 8; } house[nhouse].row = p[who].row; house[nhouse].col = p[who].col; nhouse += 1; } who = 1 - who; // santa; bot; santa; bot; ..., ..., ... } free(house); printf("Santa and santa bot delivered at least 1 present to %u houses.\n", nhouse); } void aoc201502(char *data, size_t len) { (void)len; // unused argument unsigned sqf = 0, f = 0; for (;;) { char *err; unsigned l = strtoul(data, &err, 10); if (*err == 0) break; data = err + 1; // skip 'x' unsigned w = strtoul(data, &err, 10); data = err + 1; // skip 'x' unsigned h = strtoul(data, &err, 10); data = err + 1; // skip newline unsigned lw = l * w; unsigned wh = w * h; unsigned hl = h * l; unsigned m = min3u(lw, wh, hl); sqf += 2*(lw + wh + hl) + m; unsigned M = max3u(l, w, h); unsigned feet = 2*(l+w+h - M) + l*h*w; f += feet; } printf("The elves need %u square feet of paper.\n", sqf); printf("The elves need %u feet of ribbon.\n", f); } void aoc201501(char *data, size_t len) { (void)len; // unused argument int floor = 0, basementsteps = -1; char *ddata = data; // save start while (*data) { if (*data == '(') floor++; else if (*data == ')') floor--; data++; // if entered the basement, part 2 done if (floor == -1) { basementsteps = data - ddata; // steps taken break; } } // continue with no regard to basement while (*data) { if (*data == '(') floor++; else if (*data == ')') floor--; data++; } printf("Santa is taken to floor {%d}.\n", floor); printf("Santa first goes to the basement at step {%d}.\n", basementsteps); }