Compare commits

..

7 Commits

Author SHA1 Message Date
b6a0735aba 2024-06,07 2025-01-02 12:12:42 -08:00
2aeb547987 2024-05 2024-12-09 19:12:05 -08:00
e9b7b4becf 2024-04 2024-12-05 10:37:32 -08:00
69bed5d6a8 2024-01,02,03 2024-12-03 12:17:24 -08:00
b5f4daede9 24-01 2024-12-02 07:17:41 -08:00
924caa936c setup 2024 2024-12-02 06:31:16 -08:00
a4fbc02b32 update submodules 2024-12-02 06:07:38 -08:00
36 changed files with 946 additions and 23 deletions

2
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "lib/libflint"] [submodule "lib/libflint"]
path = lib/libflint path = lib/libflint
url = https://git.burkey.co/eburk/libflint url = https://gitlab.com/eburk/libflint.git
[submodule "lib/uthash"] [submodule "lib/uthash"]
path = lib/uthash path = lib/uthash
url = https://github.com/troydhanson/uthash url = https://github.com/troydhanson/uthash

View File

@ -17,24 +17,38 @@ file(GLOB SRC2020 src/2020/*.c)
file(GLOB SRC2021 src/2021/*.c) file(GLOB SRC2021 src/2021/*.c)
file(GLOB SRC2022 src/2022/*.c) file(GLOB SRC2022 src/2022/*.c)
file(GLOB SRC2023 src/2023/*.c) file(GLOB SRC2023 src/2023/*.c)
file(GLOB SRC2024 src/2024/*.c)
file(COPY input DESTINATION ${CMAKE_BINARY_DIR}) file(COPY input DESTINATION ${CMAKE_BINARY_DIR})
add_executable(advent ${SRC} ${SRC2015} ${SRC2016} ${SRC2017} ${SRC2018} ${SRC2019} ${SRC2020} ${SRC2021} ${SRC2022} ${SRC2023}) add_executable(advent ${SRC} ${SRC2015} ${SRC2016} ${SRC2017} ${SRC2018} ${SRC2019} ${SRC2020} ${SRC2021} ${SRC2022} ${SRC2023} ${SRC2024})
set(INCLUDES
include
lib/libflint/include
lib/uthash/src
)
if ((${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")) if ((${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD"))
target_link_libraries(advent PRIVATE flint) find_package(PCRE2 REQUIRED)
target_include_directories(advent PRIVATE include lib/libflint/include lib/uthash/src) target_include_directories(advent PRIVATE ${INCLUDES} ${PCRE2_INCLUDE_DIR})
target_link_libraries(advent PRIVATE flint ${PCRE2_LIBRARIES})
elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux")) elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
target_link_libraries(advent PRIVATE bsd flint ${OPENSSL_LIBRARIES}) target_include_directories(advent PRIVATE ${INCLUDES} ${OpenSSL_INCLUDE_DIR} ${PCRE2_INCLUDE_DIR})
target_include_directories(advent PRIVATE include lib/libflint/include lib/uthash/src ${OpenSSL_INCLUDE_DIR}) target_link_libraries(advent PRIVATE bsd flint ${PCRE2_LIBRARIES} ${OPENSSL_LIBRARIES})
elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")) elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin"))
# OpenSSL
set(OPENSSL_ROOT_DIR /opt/homebrew/opt/openssl@3) set(OPENSSL_ROOT_DIR /opt/homebrew/opt/openssl@3)
set(OpenSSL_INCLUDE_DIR /opt/homebrew/opt/openssl@3/include) set(OpenSSL_INCLUDE_DIR /opt/homebrew/opt/openssl@3/include)
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
target_link_libraries(advent PRIVATE flint ${OPENSSL_LIBRARIES})
target_include_directories(advent PRIVATE include lib/libflint/include lib/uthash/src ${OpenSSL_INCLUDE_DIR}) # PCRE2
set(PCRE2_INCLUDE_DIR /opt/homebrew/opt/pcre2/include)
set(PCRE2_LIBRARIES /opt/homebrew/opt/pcre2/lib/libpcre2-8.dylib)
target_include_directories(advent PRIVATE ${INCLUDES} ${OpenSSL_INCLUDE_DIR} ${PCRE2_INCLUDE_DIR})
target_link_libraries(advent PRIVATE flint ${OPENSSL_LIBRARIES} ${PCRE2_LIBRARIES})
else() else()
message(FATAL_ERROR "OS ${CMAKE_SYSTEM_NAME} is not supported" ) message(FATAL_ERROR "OS ${CMAKE_SYSTEM_NAME} is not supported" )
endif() endif()

View File

@ -6,7 +6,7 @@ Advent Of Code solutions using C99. Builds and runs on macOS, Linux, and OpenBSD
Be sure to clone the project with its submodules: Be sure to clone the project with its submodules:
git clone --recurse-submodules https://git.burkey.co/eburk/advent git clone --recurse-submodules https://gitlab.com/eburk/aoc
This project relies on several BSD extensions to the stdlib. OpenBSD and macOS users should be able to build the project out of the box. Linux users will need `libbsd` installed. The package is called `libbsd-dev` on Debian-based systems. This project relies on several BSD extensions to the stdlib. OpenBSD and macOS users should be able to build the project out of the box. Linux users will need `libbsd` installed. The package is called `libbsd-dev` on Debian-based systems.

View File

@ -2,7 +2,7 @@
mkdir -p include mkdir -p include
for year in {2023..2023}; do for year in {2015..2024}; do
rm -rf "src/${year}" rm -rf "src/${year}"
mkdir -p "src/${year}" mkdir -p "src/${year}"

View File

@ -4,8 +4,21 @@ get(){
curl -s --cookie "session=$1" "$2" | perl -pe 'chomp if eof' > "$3" curl -s --cookie "session=$1" "$2" | perl -pe 'chomp if eof' > "$3"
} }
rm -rf input if [ -n "${2+x}" ] && [ -n "${3+x}" ]; then
for year in {2015..2023}; do year="20$2"
day="$3"
if [ "$day" -lt 10 ]; then
d="0$day"
else
d="$day"
fi
url="https://adventofcode.com/$year/day/$day/input"
get "$1" "$url" "input/$year/$d"
exit 0
fi
#rm -rf input
for year in {2015..2024}; do
mkdir -p input/"$year" mkdir -p input/"$year"
for day in {1..25}; do for day in {1..25}; do
if [[ day -lt 10 ]]; then if [[ day -lt 10 ]]; then

58
include/advent2024.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef ADVENT_2024_H
#define ADVENT_2024_H
void advent2024day01(void);
void advent2024day02(void);
void advent2024day03(void);
void advent2024day04(void);
void advent2024day05(void);
void advent2024day06(void);
void advent2024day07(void);
void advent2024day08(void);
void advent2024day09(void);
void advent2024day10(void);
void advent2024day11(void);
void advent2024day12(void);
void advent2024day13(void);
void advent2024day14(void);
void advent2024day15(void);
void advent2024day16(void);
void advent2024day17(void);
void advent2024day18(void);
void advent2024day19(void);
void advent2024day20(void);
void advent2024day21(void);
void advent2024day22(void);
void advent2024day23(void);
void advent2024day24(void);
void advent2024day25(void);
void (*solutions2024[25])(void) = {
advent2024day01,
advent2024day02,
advent2024day03,
advent2024day04,
advent2024day05,
advent2024day06,
advent2024day07,
advent2024day08,
advent2024day09,
advent2024day10,
advent2024day11,
advent2024day12,
advent2024day13,
advent2024day14,
advent2024day15,
advent2024day16,
advent2024day17,
advent2024day18,
advent2024day19,
advent2024day20,
advent2024day21,
advent2024day22,
advent2024day23,
advent2024day24,
advent2024day25
};
#endif

View File

@ -9,7 +9,19 @@
#define MIN(x, y) (x) < (y) ? (x) : (y) #define MIN(x, y) (x) < (y) ? (x) : (y)
char *md5_str(const char *); char *md5_str(const char *);
Vector *string_to_int_vector(const char *input_string, const char *delim); Vector *string_to_int_vector(const char *input_string, const char *delim);
int int_comp(const void *a, const void *b);
char **get_matches(char *in, char *pat, size_t *sz, size_t max_matches);
void free_matches(char **matches, size_t sz);
enum Direction {
DIR_NORTH = 0,
DIR_EAST = 1,
DIR_SOUTH = 2,
DIR_WEST = 3,
};
void turn_right(enum Direction *d);
void turn_left(enum Direction *d);
#endif #endif

@ -1 +1 @@
Subproject commit 619fe95ca4679249528f086536aadd0c469dbd99 Subproject commit f69112c04f1b6e059b8071cb391a1fcc83791a00

View File

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

58
src/2024/01.c Normal file
View File

@ -0,0 +1,58 @@
#include <limits.h>
#include <stdio.h>
#include "lfinput.h"
#include "advent_utility.h"
void advent2024day01(void) {
size_t sz = 0;
char **input = get_lines("input/2024/01", &sz);
int a[sz];
int b[sz];
const char *errstr;
for (size_t i = 0; i < sz; i++) {
size_t sp_sz = 0;
char **sp = split(input[i], &sp_sz, " ");
a[i] = (int) strtonum(sp[0], INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
printf("ERR: %s\n", errstr);
free(sp);
break;
}
b[i] = (int) strtonum(sp[1], INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
printf("ERR: %s\n", errstr);
free(sp);
break;
}
free(sp);
}
qsort(a, sz, sizeof(int), int_comp);
qsort(b, sz, sizeof(int), int_comp);
int p1 = 0;
for (size_t i = 0; i < sz; i++) {
p1 += abs(a[i] - b[i]);
}
printf("%d\n", p1);
int p2 = 0;
for (size_t i = 0; i < sz; i++) {
int c = 0;
for (size_t j = 0; j < sz; j++) {
if (a[i] == b[j]) {
++c;
}
}
p2 += a[i] * c;
}
printf("%d\n", p2);
del_lines(input);
}

116
src/2024/02.c Normal file
View File

@ -0,0 +1,116 @@
#include <lflinkedlist.h>
#include <lfmemory.h>
#include <limits.h>
#include <stdio.h>
#include "lfinput.h"
#include "lfbool.h"
static int part1(List *a) {
ListNode *n = a->head;
int inc = LFFALSE;
if (*(int *) n->data < *(int *) n->next->data) {
inc = LFTRUE;
}
int safe = LFTRUE;
while (n->next != NULL) {
int prev = *(int *) n->data, cur = *(int *) n->next->data;
if (inc == LFTRUE) {
if (prev > cur || prev == cur || cur - prev > 3) {
safe = LFFALSE;
break;
}
} else {
if (prev < cur || prev == cur || prev - cur > 3) {
safe = LFFALSE;
break;
}
}
n = n->next;
}
return safe;
}
static int part2(List *a) {
ListNode *n = a->head;
int inc = LFFALSE;
if (*(int *) n->data < *(int *) n->next->data) {
inc = LFTRUE;
}
int bad = 0;
int safe = LFTRUE;
while (n->next != NULL) {
const int prev = *(int *) n->data;
const int cur = *(int *) n->next->data;
if (inc == LFTRUE) {
if (prev > cur || prev == cur || cur - prev > 3) {
if (bad == 0) {
void *t;
ll_remove_next(a, n, &t);
bad = 1;
continue;
}
safe = LFFALSE;
break;
}
} else {
if (prev < cur || prev == cur || prev - cur > 3) {
if (bad == 0) {
void *t;
ll_remove_next(a, n, &t);
bad = 1;
continue;
}
safe = LFFALSE;
break;
}
}
n = n->next;
}
return safe;
}
void advent2024day02(void) {
size_t sz = 0;
char **input = get_lines("input/2024/02", &sz);
char *errstr = NULL;
int p1 = 0, p2 = 0;
for (size_t i = 0; i < sz; i++) {
List *a = malloc(sizeof(List));
ll_init(a, NULL);
ArenaAllocator *arena = malloc(sizeof(ArenaAllocator));
arena_init(arena, sizeof(int) * 32);
size_t sp_sz = 0;
char **sp = split(input[i], &sp_sz, " ");
for (size_t j = 0; j < sp_sz; j++) {
int *t = arena_malloc(arena, sizeof(int));
*t = (int) strtonum(sp[j], INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
printf("ERR: %s\n", errstr);
exit(1);
}
ll_ins_next(a, a->tail, t);
}
p1 += part1(a);
p2 += part2(a);
free(sp);
ll_destroy(a);
arena_free(arena);
}
printf("%d\n", p1);
printf("%d\n", p2);
del_lines(input);
}

34
src/2024/03.c Normal file
View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
#include "advent_utility.h"
void advent2024day03(void) {
char *input = get_input("input/2024/03");
size_t m_sz = 0;
char **matches = get_matches(input, "mul\\(\\d+,\\d+\\)|do\\(\\)|don't\\(\\)", &m_sz, 32);
int p1 = 0, p2 = 0, x, y, enabled = 1;
for (size_t i = 0; i < m_sz; i++) {
if (strcmp(matches[i], "do()") == 0) {
enabled = 1;
} else if (strcmp(matches[i], "don't()") == 0) {
enabled = 0;
}
if (strstr(matches[i], "mul") != NULL) {
sscanf(matches[i], "mul(%d,%d)", &x, &y);
p1 += x * y;
if (enabled) {
p2 += x * y;
}
}
}
printf("%d\n", p1);
printf("%d\n", p2);
free_matches(matches, m_sz);
free(input);
}

92
src/2024/04.c Normal file
View File

@ -0,0 +1,92 @@
#include <stdio.h>
#include <string.h>
#include "lfinput.h"
#define GRID_SZ 140
char **gd;
static int horz(int x, int y, const char *w) {
if (y <= GRID_SZ - 4) {
return strncmp(&gd[x][y], w, 4) == 0;
}
return 0;
}
static int vert(int x, int y, const char *w) {
if (x <= GRID_SZ - 4) {
int c = 1;
for (int j = 0; j < 4; j++) {
if (gd[x + j][y] != w[j]) {
c = 0;
}
}
return c;
}
return 0;
}
static int diag_right(int x, int y, const char *w) {
if (x <= GRID_SZ - 4 && y >= 3) {
int c = 1;
for (int j = 0; j < 4; j++) {
if (gd[x + j][y - j] != w[j]) {
c = 0;
}
}
return c;
}
return 0;
}
static int diag_left(int x, int y, const char *w) {
if (x <= GRID_SZ - 4 && y <= GRID_SZ - 4) {
int c = 1;
for (int j = 0; j < 4; j++) {
if (gd[x + j][y + j] != w[j]) {
c = 0;
}
}
return c;
}
return 0;
}
void advent2024day04(void) {
int p1 = 0, p2 = 0;
size_t sz = GRID_SZ;
gd = get_lines("input/2024/04", &sz);
for (size_t x = 0; x < sz; ++x) {
for (size_t y = 0; y < sz; ++y) {
p1 += horz(x, y, "XMAS");
p1 += horz(x, y, "SAMX");
p1 += vert(x, y, "XMAS");
p1 += vert(x, y, "SAMX");
p1 += diag_left(x, y, "XMAS");
p1 += diag_left(x, y, "SAMX");
p1 += diag_right(x, y, "XMAS");
p1 += diag_right(x, y, "SAMX");
}
}
printf("%d\n", p1);
for (size_t x = 1; x < sz - 1; ++x) {
for (size_t y = 1; y < sz - 1; ++y) {
if (gd[x][y] == 'A') {
int c = 0;
if ((gd[x - 1][y - 1] == 'M' && gd[x + 1][y + 1] == 'S') || (gd[x - 1][y - 1] == 'S' && gd[x + 1][y + 1] == 'M')) {
if ((gd[x + 1][y - 1] == 'M' && gd[x - 1][y + 1] == 'S') || (gd[x + 1][y - 1] == 'S' && gd[x - 1][y + 1] == 'M')) {
c = 1;
}
}
p2 += c;
}
}
}
printf("%d\n", p2);
del_lines(gd);
}

94
src/2024/05.c Normal file
View File

@ -0,0 +1,94 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lfinput.h"
#define RULES_SZ 1176
struct Rule {
int a;
int b;
};
static int part_one(int *pages, size_t sz, struct Rule *rules) {
int midpoint = pages[sz / 2];
for (size_t ridx = 0; ridx < RULES_SZ; ++ridx) {
int a = -1;
int b = 500;
for (int pidx = 0; pidx < sz; ++pidx) {
if (pages[pidx] == rules[ridx].a) {
a = pidx;
}
if (pages[pidx] == rules[ridx].b) {
b = pidx;
}
if (a > b) {
midpoint = 0;
}
}
}
return midpoint;
}
int rule_matrix[100][100] = {0};
static int sort(const void *a, const void *b) {
int ia = *(int*)a;
int ib = *(int*)b;
if (rule_matrix[ia][ib]) {
return -1;
}
if (rule_matrix[ib][ia]) {
return 1;
}
return 0;
}
static int part_two(int *pages, size_t sz, struct Rule *rules) {
int s = 0;
int sorted[100];
memcpy(sorted, pages, sizeof(int) * sz);
qsort(sorted, sz, sizeof(int), sort);
if (memcmp(pages, sorted, sz * sizeof(int)) != 0) {
s += sorted[sz / 2];
}
return s;
}
void advent2024day05(void) {
size_t sz = 0;
char **input = get_lines("input/2024/05", &sz);
char *errstr = NULL;
struct Rule rules[RULES_SZ];
int p1 = 0, p2 = 0;
size_t i = 0;
for (; strlen(input[i]) == 5; ++i) {
sscanf(input[i], "%d|%d", &rules[i].a, &rules[i].b);
rule_matrix[rules[i].a][rules[i].b] = 1;
}
for (; i < sz; ++i) {
size_t sz_sp = 0;
char **sp = split(input[i], &sz_sp, ",");
int *pages = malloc(sizeof(int) * sz_sp);
for (size_t j = 0; j < sz_sp; ++j) {
pages[j] = (int) strtonum(sp[j], INT_MIN, INT_MAX, &errstr);
}
p1 += part_one(pages, sz_sp, rules);
p2 += part_two(pages, sz_sp, rules);
free(pages);
free(sp);
}
printf("%d\n", p1);
printf("%d\n", p2);
del_lines(input);
}

110
src/2024/06.c Normal file
View File

@ -0,0 +1,110 @@
#include <advent_utility.h>
#include <lfutility.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lfinput.h"
#define TRAVELED 'X'
#define BLOCK '#'
static int sim(Point guard, char **map, const size_t width, const size_t height) {
enum Direction dir = DIR_NORTH;
while (guard.x > 0 && guard.y > 0 && guard.x < width && guard.y < height) {
map[guard.y][guard.x] = TRAVELED;
switch (dir) {
case DIR_NORTH:
if (guard.y == 0) {
break;
}
if (map[guard.y - 1][guard.x] == BLOCK) {
turn_right(&dir);
}
break;
case DIR_EAST:
if (guard.x + 1 == width) {
break;
}
if (map[guard.y][guard.x + 1] == BLOCK) {
turn_right(&dir);
}
break;
case DIR_SOUTH:
if (guard.y + 1 == height) {
break;
}
if (map[guard.y + 1][guard.x] == BLOCK) {
turn_right(&dir);
}
break;
case DIR_WEST:
if (guard.x == 0) {
break;
}
if (map[guard.y][guard.x - 1] == BLOCK) {
turn_right(&dir);
}
break;
}
switch (dir) {
case DIR_NORTH: guard.y--;
break;
case DIR_EAST: guard.x++;
break;
case DIR_SOUTH: guard.y++;
break;
case DIR_WEST: guard.x--;
break;
}
/*
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
printf("%c", map[y][x]);
}
printf("\n");
}
printf("\n");
*/
}
int v = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
//printf("%c", map[y][x]);
if (map[y][x] == TRAVELED) {
++v;
}
}
//printf("\n");
}
return v;
}
void advent2024day06(void) {
size_t height = 0;
char **map = get_lines("input/2024/06", &height);
const size_t width = strlen(map[0]);
Point guard = {.x = 0, .y = 0};
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (map[y][x] == '^') {
guard.x = x;
guard.y = y;
goto GUARD_SEARCH_COMPLETE;
}
}
}
GUARD_SEARCH_COMPLETE:
printf("%d\n", sim(guard, map, width, height));
del_lines(map);
}

13
src/2024/07.c Normal file
View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include <stdlib.h>
#include "lfinput.h"
void advent2024day07(void) {
size_t sz = 0;
char **input = get_lines("input/2024/07", &sz);
del_lines(input);
}

10
src/2024/08.c Normal file
View File

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

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

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

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

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

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

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

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

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

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

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

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

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

10
src/2024/15.c Normal file
View File

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

View File

@ -2,10 +2,11 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#define PCRE2_CODE_UNIT_WIDTH 8
#include "pcre2.h"
#if defined __linux__ || defined __APPLE__ #if defined __linux__ || defined __APPLE__
#include <openssl/md5.h> #include <openssl/md5.h>
#else #else
#include <md5.h> #include <md5.h>
#endif #endif
@ -34,9 +35,9 @@ char *md5_str(const char *input) {
return md5string; return md5string;
} }
Vector *string_to_int_vector(const char *input_string, const char* delim) { Vector *string_to_int_vector(const char *input_string, const char *delim) {
char *copy = strdup(input_string); char *copy = strdup(input_string);
char* token = strtok(copy, delim); char *token = strtok(copy, delim);
Vector *v = malloc(sizeof(Vector)); Vector *v = malloc(sizeof(Vector));
vec_init(v, free); vec_init(v, free);
@ -51,3 +52,127 @@ Vector *string_to_int_vector(const char *input_string, const char* delim) {
return v; 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;
}

View File

@ -16,6 +16,7 @@
#include "advent2021.h" #include "advent2021.h"
#include "advent2022.h" #include "advent2022.h"
#include "advent2023.h" #include "advent2023.h"
#include "advent2024.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
if (argc != 3) { if (argc != 3) {
@ -27,7 +28,7 @@ int main(int argc, char **argv) {
char buf[32]; char buf[32];
const char *errstr = NULL; const char *errstr = NULL;
year = strtonum(argv[1], 15, 23, &errstr); year = strtonum(argv[1], 15, 24, &errstr);
if (NULL != errstr) { if (NULL != errstr) {
printf("Input error: %s\n\n", errstr); printf("Input error: %s\n\n", errstr);
return 1; return 1;
@ -67,6 +68,9 @@ int main(int argc, char **argv) {
case 23: case 23:
solutions2023[day - 1](); solutions2023[day - 1]();
break; break;
case 24:
solutions2024[day - 1]();
break;
} }
return 0; return 0;