2024-01,02,03
This commit is contained in:
parent
b5f4daede9
commit
69bed5d6a8
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
124
src/2024/02.c
124
src/2024/02.c
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
@ -53,4 +54,116 @@ 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user