init, 2015 & 2016

This commit is contained in:
2025-11-14 07:14:53 -08:00
commit ef109439e6
124 changed files with 14861 additions and 0 deletions

28
2015/src/01.c Normal file
View File

@@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day01(void) {
char *input = get_input("input/01");
char *c = input;
int f = 0, b = 0, s = 1;
while (*c != '\0') {
if (*c == '(') {
++f;
} else {
--f;
}
if (f == -1 && b == 0) {
b = s;
}
++c;
++s;
}
printf("%d\n%d\n", f, b);
free(input);
}

27
2015/src/02.c Normal file
View File

@@ -0,0 +1,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lfinput.h"
#include "lfmath.h"
void advent2015day02(void) {
size_t sz = 0;
char **lines = get_lines("input/02", &sz);
int paper = 0, ribbon = 0;
for (size_t i = 0; i < sz; i++) {
char *t = strtok(lines[i], "x");
int w = atoi(t);
t = strtok(NULL, "x");
int l = atoi(t);
t = strtok(NULL, "x");
int h = atoi(t);
paper += 2 * l * w + 2 * w * h + 2 * h * l + min_int(w * l, min_int(l * h, h * w));
ribbon += l * w * h + min_int(w + w + h + h, min_int(h + h + l + l, l + l + w + w));
}
printf("%d\n%d\n", paper, ribbon);
del_lines(lines);
}

89
2015/src/03.c Normal file
View File

@@ -0,0 +1,89 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfset.h"
#include "lfinput.h"
#include "lfutility.h"
static int part_two(char *input) {
int sx = 0, sy = 0, rx = 0, ry = 0, is_santa = 1;
int *x, *y;
char *c = input;
Set *houses = malloc(sizeof(Set));
set_init(houses, Point_cmp_v, free);
while (*c != '\0') {
if (is_santa) {
x = &sx;
y = &sy;
} else {
x = &rx;
y = &ry;
}
is_santa = is_santa == 1 ? 0 : 1;
switch (*c) {
case '^':
++(*y);
break;
case 'v':
--(*y);
break;
case '>':
++(*x);
break;
case '<':
--(*x);
break;
}
set_insert(houses, Point_new_p(*x, *y));
++c;
}
int sz = houses->size;
set_destroy(houses);
return sz;
}
static int part_one(char *input) {
int x = 0, y = 0;
char *c = input;
Set *houses = malloc(sizeof(Set));
set_init(houses, Point_cmp_v, free);
while (*c != '\0') {
switch (*c) {
case '^':
++y;
break;
case 'v':
--y;
break;
case '>':
++x;
break;
case '<':
--x;
break;
}
set_insert(houses, Point_new_p(x, y));
++c;
}
int sz = houses->size;
set_destroy(houses);
return sz;
}
void advent2015day03(void) {
char *input = get_input("input/03");
printf("%d\n", part_one(input));
printf("%d\n", part_two(input));
free(input);
}

52
2015/src/04.c Normal file
View File

@@ -0,0 +1,52 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lfinput.h"
#include "advent_utility.h"
static int is_five(char *test) {
char *t = test;
for (int i = 0; i < 5; ++i, ++t) {
if (*t != '0') {
return 0;
}
}
return 1;
}
static int is_six(char *test) {
char *t = test;
for (int i = 0; i < 6; ++i, ++t) {
if (*t != '0') {
return 0;
}
}
return 1;
}
void advent2015day04(void) {
char *input = get_input("input/04");
int c = 0, five = 0, six = 0;
while (!five || !six) {
int sz = strlen(input) + 8;
char test[sz];
snprintf(test, sz, "%s%d", input, c);
char *md5 = md5_str(test);
if (!five && is_five(md5)) {
five = c;
printf("%d\n", five);
}
if (is_six(md5)) {
six = c;
}
free(md5);
++c;
}
printf("%d\n", six);
free(input);
}

16
2015/src/05.c Normal file
View File

@@ -0,0 +1,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <lfinput.h>
void advent2015day05(void) {
/* Sometimes, grep really is the best tool */
const char *p1 = capture_system(
"grep -E \"(.*[aeiou]){3}\" ./input/2015/05 | grep \"\\(.\\)\\1\" | egrep -v \"(ab|cd|pq|xy)\" | wc -l", 0);
const char *p2 = capture_system("grep \"\\(..\\).*\\1\" ./input/2015/05 | grep \"\\(.\\).\\1\" | wc -l", 0);
printf("%s%s", p1, p2);
free(p1);
free(p2);
}

118
2015/src/06.c Normal file
View File

@@ -0,0 +1,118 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __linux__
#include <bsd/stdlib.h>
#endif
#include "lfinput.h"
#include "lfmath.h"
#define GRID_SZ 1000
typedef struct {
int mode; /* 0 = on, 1 = off, 2 = toggle */
int x0;
int y0;
int x1;
int y1;
} s1503;
static void get_coords(char *s, int *x, int *y) {
char buf[8];
char *c = s;
int i = 0;
const char *errstr = NULL;
while (*c != ',') {
buf[i++] = *c;
++c;
}
buf[i] = '\0';
*x = (int)strtonum(buf, 0, 999, &errstr);
if (NULL != errstr) {
exit(1);
}
memset(buf, 0, sizeof(char) * 8);
i = 0;
++c;
while (*c != '\0') {
buf[i++] = *c;
++c;
}
buf[i] = '\0';
*y = (int)strtonum(buf, 0, 999, &errstr);
if (NULL != errstr) {
exit(1);
}
}
static int run(s1503 *ins, size_t sz, int p1) {
int grid[GRID_SZ][GRID_SZ];
memset(grid, 0, sizeof(int) * GRID_SZ * GRID_SZ);
for (size_t i = 0; i < sz; ++i) {
for (int x = ins[i].x0; x <= ins[i].x1; ++x) {
for (int y = ins[i].y0; y <= ins[i].y1; ++y) {
switch (ins[i].mode) {
case 0: /* on */
if (p1) { grid[x][y] = 1; }
else {grid[x][y] += 1; }
break;
case 1: /* off */
if (p1) { grid[x][y] = 0; }
else {grid[x][y] = max_int(0, grid[x][y] - 1); }
break;
case 2: /* toggle */
if (p1) { grid[x][y] = grid[x][y] == 1 ? 0 : 1; }
else {grid[x][y] += 2; }
break;
}
}
}
}
int c = 0;
for (int x = 0; x < GRID_SZ; ++x) {
for (int y = 0; y < GRID_SZ; ++y) {
c += grid[x][y];
}
}
return c;
}
void advent2015day06(void) {
size_t sz = 0;
char **input = get_lines("input/06", &sz);
s1503 ins[sz];
for (size_t i = 0; i < sz; ++i) {
char *s = malloc(sizeof(char) * 64);
strncpy(s, input[i], 64);
size_t sp_sz = 0;
char **sp = split(s, &sp_sz, " ");
if (sp_sz == 4) {
ins[i].mode = 2;
get_coords(sp[1], &ins[i].x0, &ins[i].y0);
get_coords(sp[3], &ins[i].x1, &ins[i].y1);
} else {
if (strcmp(sp[1], "on") == 0) {
ins[i].mode = 0;
} else {
ins[i].mode = 1;
}
get_coords(sp[2], &ins[i].x0, &ins[i].y0);
get_coords(sp[4], &ins[i].x1, &ins[i].y1);
}
del_split(sp);
}
del_lines(input);
printf("%d\n", run(ins, sz, 1));
printf("%d\n", run(ins, sz, 0));
}

118
2015/src/07.c Normal file
View File

@@ -0,0 +1,118 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "uthash.h"
#include "lfinput.h"
#include "lfbool.h"
#ifdef __linux__
#include <bsd/stdlib.h>
#else
#include <stdlib.h>
#endif
struct Wire {
char name[8];
uint16_t val;
UT_hash_handle hh;
};
struct Wire *wires = NULL;
static void set_wire(const char *name, int v) {
struct Wire *w;
HASH_FIND_STR(wires, name, w);
if (w == NULL) {
w = malloc(sizeof(struct Wire));
strlcpy(w->name, name, 8);
HASH_ADD_STR(wires, name, w);
}
w->val = v;
}
static struct Wire *get_wire(const char *name) {
struct Wire *w = NULL;
HASH_FIND_STR(wires, name, w);
return w;
}
static void clear_wires() {
struct Wire *c, *t;
HASH_ITER(hh, wires, c, t) {
HASH_DEL(wires, c);
free(c);
}
}
static uint16_t get_val(const char* n) {
const char *errstr;
uint16_t v = strtonum(n, 0, 1 << 16, &errstr);
if (errstr == NULL) {
return v;
};
struct Wire *w = get_wire(n);
if (w == NULL) {
return 0;
}
return w->val;
}
void advent2015day07(void) {
size_t sz = 0;
char **input = get_lines("input/07", &sz);
size_t i = 0;
int a_set = LFFALSE;
while (!a_set) {
int sz = strlen(input[i]) + 1;
char *buf = malloc(sizeof(char) * sz);
strlcpy(buf, input[i], sz);
size_t sp_sz = 0;
char **sp = split(buf, &sp_sz, " ");
if (sp_sz == 3) {
uint16_t a = get_val(sp[0]);
if (a != 0) {
set_wire(sp[2], a);
}
} else if (sp_sz == 4) {
uint16_t a = get_val(sp[0]);
if (a != 0) {
set_wire(sp[2], ~a);
}
} else {
uint16_t a = get_val(sp[0]);
uint16_t b = get_val(sp[2]);
if (a != 0 && b != 0) {
if (strcmp(sp[1], "AND") == 0) {
set_wire(sp[4], a & b);
} else if (strcmp(sp[1], "OR") == 0) {
set_wire(sp[4], a | b);
} else if (strcmp(sp[1], "LSHIFT") == 0) {
set_wire(sp[4], a << b);
} else if (strcmp(sp[1], "RSHIFT") == 0) {
set_wire(sp[4], a >> b);
}
}
}
uint16_t a = get_val("a");
if (a != 0) {
a_set = LFTRUE;
}
del_split(sp);
++i;
if (i == sz) {
i = 0;
}
}
printf("%u\n", get_wire("a")->val);
del_lines(input);
clear_wires();
}

51
2015/src/08.c Normal file
View File

@@ -0,0 +1,51 @@
#include <stdio.h>
#include <string.h>
#include "lfinput.h"
static size_t part_one(char** input, size_t sz) {
size_t code = 0, mem = 0;
for (size_t i = 0; i < sz; ++i) {
code += strlen(input[i]);
for (size_t j = 1; j < strlen(input[i]) - 1; ++j) {
if (input[i][j] == '\\') {
if (input[i][j + 1] == '\"' || input[i][j + 1] == '\\') {
++j;
} else {
j += 3;
}
}
++mem;
}
}
return code - mem;
}
static size_t part_two(char** input, size_t sz) {
size_t code = 0, encoded = 0;
for (size_t i = 0; i < sz; ++i) {
code += strlen(input[i]);
encoded += 6;
for (size_t j = 1; j < strlen(input[i]) - 1; ++j) {
if (input[i][j] == '\\' || input[i][j] == '\"') {
++encoded;
}
++encoded;
}
}
return encoded - code;
}
void advent2015day08(void) {
size_t sz = 0;
char **input = get_lines("input/08", &sz);
printf("%zu\n", part_one(input, sz));
printf("%zu\n", part_two(input, sz));
del_lines(input);
}

10
2015/src/09.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day09(void) {
char *input = get_input("input/09");
printf("Solution for Day 09 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/10.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day10(void) {
char *input = get_input("input/10");
printf("Solution for Day 10 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/11.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day11(void) {
char *input = get_input("input/11");
printf("Solution for Day 11 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/12.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day12(void) {
char *input = get_input("input/12");
printf("Solution for Day 12 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/13.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day13(void) {
char *input = get_input("input/13");
printf("Solution for Day 13 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/14.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day14(void) {
char *input = get_input("input/14");
printf("Solution for Day 14 of 2015 is not completed yet\n");
free(input);
}

63
2015/src/15.c Normal file
View File

@@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
typedef struct {
long cap;
long dur;
long flv;
long tex;
long cal;
} Ingredient;
static long long_max(long a, long b) {
return a > b ? a : b;
}
void advent2015day15(void) {
size_t input_sz = 0;
char **input = get_lines("input/15", &input_sz);
Ingredient ing[input_sz]; for (size_t i = 0; i < input_sz; ++i) {
char n[16];
sscanf(input[i], "%s capacity %ld, durability %ld, flavor %ld, texture %ld, calories %ld",
n,
&ing[i].cap,
&ing[i].dur,
&ing[i].flv,
&ing[i].tex,
&ing[i].cal
);
}
long max = 0, max_healthy = 0;
for (long p0 = 0; p0 < 100; ++p0) {
for (long p1 = 0; p1 < 100; ++p1) {
for (long p2 = 0; p2 < 100; ++p2) {
for (long p3 = 0; p3 < 100; ++p3) {
if (p0 + p1 + p2 + p3 != 100) {
continue;
}
long cap = long_max(ing[0].cap * p0 + ing[1].cap * p1 + ing[2].cap * p2 + ing[3].cap * p3, 0);
long dur = long_max(ing[0].dur * p0 + ing[1].dur * p1 + ing[2].dur * p2 + ing[3].dur * p3, 0);
long flv = long_max(ing[0].flv * p0 + ing[1].flv * p1 + ing[2].flv * p2 + ing[3].flv * p3, 0);
long tex = long_max(ing[0].tex * p0 + ing[1].tex * p1 + ing[2].tex * p2 + ing[3].tex * p3, 0);
long cal = ing[0].cal * p0 + ing[1].cal * p1 + ing[2].cal * p2 + ing[3].cal * p3;
long score = cap * dur * flv * tex;
if (score > max) {
max = score;
}
if (cal == 500 && score > max_healthy) {
max_healthy = score;
}
}
}
}
}
printf("%ld\n", max);
printf("%ld\n", max_healthy);
del_lines(input);
}

10
2015/src/16.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day16(void) {
char *input = get_input("input/16");
printf("Solution for Day 16 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/17.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day17(void) {
char *input = get_input("input/17");
printf("Solution for Day 17 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/18.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day18(void) {
char *input = get_input("input//18");
printf("Solution for Day 18 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/19.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day19(void) {
char *input = get_input("input/19");
printf("Solution for Day 19 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/20.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day20(void) {
char *input = get_input("input/20");
printf("Solution for Day 20 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/21.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day21(void) {
char *input = get_input("input/21");
printf("Solution for Day 21 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/22.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day22(void) {
char *input = get_input("input/22");
printf("Solution for Day 22 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/23.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day23(void) {
char *input = get_input("input/23");
printf("Solution for Day 23 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/24.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day24(void) {
char *input = get_input("input/24");
printf("Solution for Day 24 of 2015 is not completed yet\n");
free(input);
}

10
2015/src/25.c Normal file
View File

@@ -0,0 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2015day25(void) {
char *input = get_input("input/25");
printf("Solution for Day 25 of 2015 is not completed yet\n");
free(input);
}

178
2015/src/advent_utility.c Normal file
View File

@@ -0,0 +1,178 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define PCRE2_CODE_UNIT_WIDTH 8
#include "pcre2.h"
#if defined __linux__ || defined __APPLE__
#include <openssl/md5.h>
#else
#include <md5.h>
#endif
#include "advent_utility.h"
char *md5_str(const char *input) {
unsigned char digest[16];
#if defined __linux__ || defined __APPLE__
MD5_CTX context;
MD5_Init(&context);
MD5_Update(&context, input, strlen(input));
MD5_Final(digest, &context);
#else
struct MD5Context context;
MD5Init(&context);
MD5Update(&context, input, strlen(input));
MD5Final(digest, &context);
#endif
char *md5string = malloc(33);
for (int i = 0; i < 16; ++i) {
snprintf(&md5string[i * 2], 33, "%02x", (unsigned int) digest[i]);
}
return md5string;
}
Vector *string_to_int_vector(const char *input_string, const char *delim) {
char *copy = strdup(input_string);
char *token = strtok(copy, delim);
Vector *v = malloc(sizeof(Vector));
vec_init(v, free);
while (token != NULL) {
int *i = malloc(sizeof(int));
*i = atoi(token);
vec_push(v, i);
token = strtok(NULL, delim);
}
free(copy);
return v;
}
int int_comp(const void *a, const void *b) {
return *(int *) a - *(int *) b;
}
char **get_matches(char *in, char *pat, size_t *sz, size_t max_matches) {
pcre2_code *re;
PCRE2_SPTR pattern = (PCRE2_SPTR)pat;
int errnum;
size_t erroff;
PCRE2_SPTR8 substr;
size_t substr_sz;
PCRE2_SPTR subject = (PCRE2_SPTR)in;
size_t subject_sz = strlen(in);
re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &errnum, &erroff, NULL);
if (re == NULL) {
char buffer[256];
pcre2_get_error_message(errnum, buffer, sizeof(buffer));
printf("PCRE2 compilation failed at offset %d: %s\n", (int) erroff, buffer);
return NULL;
}
char **matches = NULL;
matches = malloc(sizeof(char *) * max_matches);
if (matches == NULL) {
printf("failed to malloc matches\n");
pcre2_code_free(re);
return NULL;
}
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern_8(re, NULL);
int rc = pcre2_match(re, subject, subject_sz, 0, 0, match_data, NULL);
if (rc < 0) {
switch (rc) {
case PCRE2_ERROR_NOMATCH:
printf("PCRE2 no matches\n");
break;
default:
printf("PCRE2 matching error %d\n", rc);
break;
}
pcre2_match_data_free(match_data);
pcre2_code_free(re);
return NULL;
}
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
*sz = 0;
for (int i = 0; i < rc; ++i) {
substr = subject + ovector[2*i];
substr_sz = ovector[2*i+1] - ovector[2*i];
matches[*sz] = (char *) malloc(substr_sz + 1);
strncpy(matches[*sz], substr, substr_sz);
*sz += 1;
}
// Now loop through rest of the matches, if there are any
for (;;) {
uint32_t options = 0;
PCRE2_SIZE start_offset = ovector[1];
// Check for empty match
if (ovector[0] == ovector[1]) {
if (ovector[0] == subject_sz) {
break;
}
options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
}
rc = pcre2_match(re, subject, subject_sz, start_offset, options, match_data, NULL);
if (rc == PCRE2_ERROR_NOMATCH) {
// All matches have been found
if (options == 0) {
break;
}
// Handle newlines
ovector[1] = start_offset + 1;
if (start_offset < subject_sz - 1 &&
//subject[start_offset] == '\r' &&
subject[start_offset + 1] == '\n') {
ovector[1] += 1;
}
continue;
}
// Other failures, non-recoverable
if (rc < 0) {
printf("PCRE2 match-matching error %d\n", rc);
pcre2_match_data_free(match_data);
pcre2_code_free(re);
free_matches(matches, *sz);
return NULL;
}
for (int i = 0; i < rc; ++i) {
substr = subject + ovector[2*i];
substr_sz = ovector[2*i+1] - ovector[2*i];
matches[*sz] = (char *) malloc(substr_sz + 1);
strncpy(matches[*sz], substr, substr_sz);
*sz += 1;
}
}
pcre2_match_data_free(match_data);
pcre2_code_free(re);
return matches;
}
void free_matches(char **matches, size_t sz) {
for (size_t i = 0; i < sz; ++i) {
free(matches[i]);
}
free(matches);
}
void turn_right(enum Direction *d) {
*d = *d == DIR_WEST ? DIR_NORTH : *d + 1;
}
void turn_left(enum Direction *d) {
*d = *d == DIR_NORTH ? DIR_WEST : *d - 1;
}

22
2015/src/main.c Normal file
View File

@@ -0,0 +1,22 @@
#include <stdio.h>
#include <string.h>
#ifdef __linux__
#include <bsd/stdlib.h>
#else
#include <stdlib.h>
#endif
#include "advent.h"
int main(int argc, char **argv) {
int day = 0;
printf("Day: ");
scanf("%d", &day);
if (day < 1 || day > 25) {
printf("Invalid day\n");
return 1;
}
solutions2015[day - 1]();
return 0;
}