2024-01,02,03

This commit is contained in:
Evan Burkey 2024-12-03 12:08:18 -08:00
parent b5f4daede9
commit 69bed5d6a8
6 changed files with 329 additions and 57 deletions

View File

@ -23,19 +23,32 @@ file(COPY input DESTINATION ${CMAKE_BINARY_DIR})
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

@ -9,7 +9,13 @@
#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);
#endif

View File

@ -5,54 +5,54 @@
#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;
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, " ");
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;
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);
}
b[i] = (int)strtonum(sp[1], INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
printf("ERR: %s\n", errstr);
free(sp);
break;
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]);
}
free(sp);
}
qsort(a, sz, sizeof(int), int_comp);
qsort(b, sz, sizeof(int), int_comp);
printf("%d\n", p1);
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;
}
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;
}
p2 += a[i] * c;
}
printf("%d\n", p2);
printf("%d\n", p2);
del_lines(input);
del_lines(input);
}

View File

@ -1,10 +1,126 @@
#include <lflinkedlist.h>
#include <lfmemory.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.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) {
char *input = get_input("input/2024/02");
printf("Solution for Day 02 of 2024 is not completed yet\n");
free(input);
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);
int s = part2(a);
if (s) {
LL_ITER(a) {
int *str = node->data;
printf("%d ", *str);
}
printf("\n");
p2 += s;
}
free(sp);
ll_destroy(a);
arena_free(arena);
}
printf("%d\n", p1);
printf("%d\n", p2);
del_lines(input);
}

View File

@ -2,9 +2,33 @@
#include <stdlib.h>
#include "lfinput.h"
#include "advent_utility.h"
void advent2024day03(void) {
char *input = get_input("input/2024/03");
printf("Solution for Day 03 of 2024 is not completed yet\n");
free(input);
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);
}

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);
@ -54,3 +55,115 @@ Vector *string_to_int_vector(const char *input_string, const char* delim) {
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);
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);
}