#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aocdailies.h"
#include "aocutils.h"
void aoc201505(char *data, size_t len) {
(void)len; // unused argument
unsigned nice = 0, nice2 = 0;
char *line = strtok(data, "\n"), *curr;
while (line) {
unsigned vowels = 0;
bool twice = false;
bool hasab, hascd, haspq, hasxy;
bool pair = false, hugged = false; // Part Two
curr = line;
if (strchr("aeiou", *curr)) vowels++;
if (curr[0] == curr[1]) twice = true;
for (curr = line + 1; *curr; curr++) {
if (strchr("aeiou", *curr)) vowels++;
if (curr[0] == curr[1]) twice = true;
if (curr[-1] == curr[1]) hugged = true;
char pp[3] = {curr[-1], curr[0], 0};
if (strstr(curr + 1, pp)) pair = true;
}
hasab = (strstr(line, "ab") != NULL);
hascd = (strstr(line, "cd") != NULL);
haspq = (strstr(line, "pq") != NULL);
hasxy = (strstr(line, "xy") != NULL);
if ((vowels >= 3) && twice && !hasab && !hascd && !haspq && !hasxy) {
nice++;
}
if (pair && hugged) nice2++;
line = strtok(NULL, "\n");
}
printf("There are %u nice strings.\n", nice);
printf("There are %u nice strings under the new rules.\n", nice2);
}
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);
}