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"]
path = lib/libflint
url = https://git.burkey.co/eburk/libflint
url = https://gitlab.com/eburk/libflint.git
[submodule "lib/uthash"]
path = lib/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 SRC2022 src/2022/*.c)
file(GLOB SRC2023 src/2023/*.c)
file(GLOB SRC2024 src/2024/*.c)
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"))
target_link_libraries(advent PRIVATE flint)
target_include_directories(advent PRIVATE include lib/libflint/include lib/uthash/src)
find_package(PCRE2 REQUIRED)
target_include_directories(advent PRIVATE ${INCLUDES} ${PCRE2_INCLUDE_DIR})
target_link_libraries(advent PRIVATE flint ${PCRE2_LIBRARIES})
elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
find_package(OpenSSL REQUIRED)
target_link_libraries(advent PRIVATE bsd flint ${OPENSSL_LIBRARIES})
target_include_directories(advent PRIVATE include lib/libflint/include lib/uthash/src ${OpenSSL_INCLUDE_DIR})
target_include_directories(advent PRIVATE ${INCLUDES} ${OpenSSL_INCLUDE_DIR} ${PCRE2_INCLUDE_DIR})
target_link_libraries(advent PRIVATE bsd flint ${PCRE2_LIBRARIES} ${OPENSSL_LIBRARIES})
elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Darwin"))
# OpenSSL
set(OPENSSL_ROOT_DIR /opt/homebrew/opt/openssl@3)
set(OpenSSL_INCLUDE_DIR /opt/homebrew/opt/openssl@3/include)
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()
message(FATAL_ERROR "OS ${CMAKE_SYSTEM_NAME} is not supported" )
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:
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.

View File

@ -2,7 +2,7 @@
mkdir -p include
for year in {2023..2023}; do
for year in {2015..2024}; do
rm -rf "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"
}
rm -rf input
for year in {2015..2023}; do
if [ -n "${2+x}" ] && [ -n "${3+x}" ]; then
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"
for day in {1..25}; do
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)
char *md5_str(const char *);
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

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

View File

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

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 <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
@ -34,9 +35,9 @@ char *md5_str(const char *input) {
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* token = strtok(copy, delim);
char *token = strtok(copy, delim);
Vector *v = malloc(sizeof(Vector));
vec_init(v, free);
@ -51,3 +52,127 @@ Vector *string_to_int_vector(const char *input_string, const char* delim) {
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 "advent2022.h"
#include "advent2023.h"
#include "advent2024.h"
int main(int argc, char **argv) {
if (argc != 3) {
@ -27,7 +28,7 @@ int main(int argc, char **argv) {
char buf[32];
const char *errstr = NULL;
year = strtonum(argv[1], 15, 23, &errstr);
year = strtonum(argv[1], 15, 24, &errstr);
if (NULL != errstr) {
printf("Input error: %s\n\n", errstr);
return 1;
@ -67,6 +68,9 @@ int main(int argc, char **argv) {
case 23:
solutions2023[day - 1]();
break;
case 24:
solutions2024[day - 1]();
break;
}
return 0;