Compare commits
7 Commits
b18a6d23e2
...
b6a0735aba
Author | SHA1 | Date | |
---|---|---|---|
b6a0735aba | |||
2aeb547987 | |||
e9b7b4becf | |||
69bed5d6a8 | |||
b5f4daede9 | |||
924caa936c | |||
a4fbc02b32 |
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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}"
|
||||
|
||||
|
17
get_input.sh
17
get_input.sh
@ -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
58
include/advent2024.h
Normal 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
|
@ -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
|
@ -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
58
src/2024/01.c
Normal 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
116
src/2024/02.c
Normal 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
34
src/2024/03.c
Normal 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
92
src/2024/04.c
Normal 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
94
src/2024/05.c
Normal 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
110
src/2024/06.c
Normal 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
13
src/2024/07.c
Normal 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
10
src/2024/08.c
Normal 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
10
src/2024/09.c
Normal 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
10
src/2024/10.c
Normal 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
10
src/2024/11.c
Normal 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
10
src/2024/12.c
Normal 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
10
src/2024/13.c
Normal 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
10
src/2024/14.c
Normal 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
10
src/2024/15.c
Normal 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
10
src/2024/16.c
Normal 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
10
src/2024/17.c
Normal 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
10
src/2024/18.c
Normal 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
10
src/2024/19.c
Normal 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
10
src/2024/20.c
Normal 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
10
src/2024/21.c
Normal 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
10
src/2024/22.c
Normal 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
10
src/2024/23.c
Normal 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
10
src/2024/24.c
Normal 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
10
src/2024/25.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user