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})
|
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()
|
||||||
|
@ -9,7 +9,13 @@
|
|||||||
#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);
|
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
|
#endif
|
||||||
|
@ -5,54 +5,54 @@
|
|||||||
#include "advent_utility.h"
|
#include "advent_utility.h"
|
||||||
|
|
||||||
void advent2024day01(void) {
|
void advent2024day01(void) {
|
||||||
size_t sz = 0;
|
size_t sz = 0;
|
||||||
char **input = get_lines("input/2024/01", &sz);
|
char **input = get_lines("input/2024/01", &sz);
|
||||||
int a[sz];
|
int a[sz];
|
||||||
int b[sz];
|
int b[sz];
|
||||||
const char* errstr;
|
const char *errstr;
|
||||||
|
|
||||||
for (size_t i = 0; i < sz; i++) {
|
for (size_t i = 0; i < sz; i++) {
|
||||||
size_t sp_sz = 0;
|
size_t sp_sz = 0;
|
||||||
char **sp = split(input[i], &sp_sz, " ");
|
char **sp = split(input[i], &sp_sz, " ");
|
||||||
|
|
||||||
a[i] = (int)strtonum(sp[0], INT_MIN, INT_MAX, &errstr);
|
a[i] = (int) strtonum(sp[0], INT_MIN, INT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
printf("ERR: %s\n", errstr);
|
printf("ERR: %s\n", errstr);
|
||||||
free(sp);
|
free(sp);
|
||||||
break;
|
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);
|
qsort(a, sz, sizeof(int), int_comp);
|
||||||
if (errstr != NULL) {
|
qsort(b, sz, sizeof(int), int_comp);
|
||||||
printf("ERR: %s\n", errstr);
|
|
||||||
free(sp);
|
int p1 = 0;
|
||||||
break;
|
for (size_t i = 0; i < sz; i++) {
|
||||||
|
p1 += abs(a[i] - b[i]);
|
||||||
}
|
}
|
||||||
free(sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
qsort(a, sz, sizeof(int), int_comp);
|
printf("%d\n", p1);
|
||||||
qsort(b, sz, sizeof(int), int_comp);
|
|
||||||
|
|
||||||
int p1 = 0;
|
int p2 = 0;
|
||||||
for (size_t i = 0; i < sz; i++) {
|
for (size_t i = 0; i < sz; i++) {
|
||||||
p1 += abs(a[i] - b[i]);
|
int c = 0;
|
||||||
}
|
for (size_t j = 0; j < sz; j++) {
|
||||||
|
if (a[i] == b[j]) {
|
||||||
printf("%d\n", p1);
|
++c;
|
||||||
|
}
|
||||||
int p2 = 0;
|
}
|
||||||
for (size_t i = 0; i < sz; i++) {
|
p2 += a[i] * c;
|
||||||
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);
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "lfinput.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) {
|
void advent2024day02(void) {
|
||||||
char *input = get_input("input/2024/02");
|
size_t sz = 0;
|
||||||
printf("Solution for Day 02 of 2024 is not completed yet\n");
|
char **input = get_lines("input/2024/02", &sz);
|
||||||
free(input);
|
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 <stdlib.h>
|
||||||
|
|
||||||
#include "lfinput.h"
|
#include "lfinput.h"
|
||||||
|
#include "advent_utility.h"
|
||||||
|
|
||||||
void advent2024day03(void) {
|
void advent2024day03(void) {
|
||||||
char *input = get_input("input/2024/03");
|
char *input = get_input("input/2024/03");
|
||||||
printf("Solution for Day 03 of 2024 is not completed yet\n");
|
size_t m_sz = 0;
|
||||||
free(input);
|
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 <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);
|
||||||
|
|
||||||
@ -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) {
|
int int_comp(const void *a, const void *b) {
|
||||||
return *(int *) a - *(int *) 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