diff options
Diffstat (limited to 'advent-of-code/2023/03')
| -rw-r--r-- | advent-of-code/2023/03/1.rkt | 84 | ||||
| -rw-r--r-- | advent-of-code/2023/03/2.rkt | 106 | ||||
| -rw-r--r-- | advent-of-code/2023/03/Makefile | 14 | ||||
| -rw-r--r-- | advent-of-code/2023/03/part1.c | 130 | ||||
| -rw-r--r-- | advent-of-code/2023/03/part2.c | 149 |
5 files changed, 190 insertions, 293 deletions
diff --git a/advent-of-code/2023/03/1.rkt b/advent-of-code/2023/03/1.rkt new file mode 100644 index 0000000..537d65f --- /dev/null +++ b/advent-of-code/2023/03/1.rkt @@ -0,0 +1,84 @@ +#lang racket/base + +(require "../lib/utils.rkt") +(require "../lib/obj.rkt") + +(define (read-input) + (call-with-input-file "input" + (lambda (fp) + (list->vector (get-lines fp))))) + +(define schema (read-input)) + +(define (char-at line col) + (string-ref (vector-ref schema line) col)) + +(define height (vector-length schema)) +(define width (string-length (vector-ref schema 0))) + +(define make-num (obj-maker 'line 'col 'value 'length)) + +(define (scan-nums) + (define nums '()) + (let loop ((i 0)) + (if (>= i height) + (void) + (let () + (let loop ((j 0)) + (define curline (vector-ref schema i)) + (if (>= j width) + (void) + (let () + (define next 1) + (define (find-next) + (if (or (>= (+ j next) 140) + (not (char-numeric? (char-at i (+ j next))))) + (void) + (let () + (set! next (+ 1 next)) + (find-next)))) + (if (char-numeric? (char-at i j)) + (let () + (find-next) + (define value (string->number (substring curline j (+ j next)))) + (set! nums (cons (make-num i j value next) nums))) + (void)) + (loop (+ j next))))) + (loop (+ 1 i))))) + (reverse nums)) +(define nums (scan-nums)) + +(define (is-symbol? c) + (and (not (char-numeric? c)) + (not (char=? #\. c)))) + +(define (collect-adjacent num) + (define left + (if (= 0 (num 'col)) + '() + (list (char-at (num 'line) (- (num 'col) 1))))) + (define right + (if (= width (+ (num 'col) (num 'length))) + '() + (list (char-at (num 'line) (+ (num 'col) (num 'length)))))) + (define up + (if (= 0 (num 'line)) + '() + (string->list + (substring (vector-ref schema (- (num 'line) 1)) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1)))))) + (define down + (if (= (- height 1) (num 'line)) + '() + (string->list + (substring (vector-ref schema (+ (num 'line) 1)) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1)))))) + (append left right up down)) + +(define (is-part-num? num) + (findf is-symbol? (collect-adjacent num))) + +(apply + (map (lambda (x) (x 'value)) + (filter is-part-num? nums)))
\ No newline at end of file diff --git a/advent-of-code/2023/03/2.rkt b/advent-of-code/2023/03/2.rkt new file mode 100644 index 0000000..721a9d1 --- /dev/null +++ b/advent-of-code/2023/03/2.rkt @@ -0,0 +1,106 @@ +#lang racket + +(require "../lib/utils.rkt") +(require "../lib/obj.rkt") + +(define (read-input) + (call-with-input-file "input" + (lambda (fp) + (list->vector (get-lines fp))))) + +(define schema (read-input)) + +(define (char-at line col) + (string-ref (vector-ref schema line) col)) + +(define height (vector-length schema)) +(define width (string-length (vector-ref schema 0))) + +(define make-num (obj-maker 'line 'col 'value 'length)) + +(define (scan-nums) + (define nums '()) + (let loop ((i 0)) + (if (>= i height) + (void) + (let () + (let loop ((j 0)) + (define curline (vector-ref schema i)) + (if (>= j width) + (void) + (let () + (define next 1) + (define (find-next) + (if (or (>= (+ j next) 140) + (not (char-numeric? (char-at i (+ j next))))) + (void) + (let () + (set! next (+ 1 next)) + (find-next)))) + (if (char-numeric? (char-at i j)) + (let () + (find-next) + (define value (string->number (substring curline j (+ j next)))) + (set! nums (cons (make-num i j value next) nums))) + (void)) + (loop (+ j next))))) + (loop (+ 1 i))))) + (reverse nums)) +(define nums (scan-nums)) + +(define (is-symbol? c) + (and (not (char-numeric? c)) + (not (char=? #\. c)))) + +(define (collect-adjacent-positions num) + (define (position-range line start end) + (define delta (- end start)) + (map list (repeat delta line) (range start end))) + (define left + (if (= 0 (num 'col)) + '() + (list (list (num 'line) (- (num 'col) 1))))) + (define right + (if (= width (+ (num 'col) (num 'length))) + '() + (list (list (num 'line) (+ (num 'col) (num 'length)))))) + (define up + (if (= 0 (num 'line)) + '() + (position-range (- (num 'line) 1) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1))))) + (define down + (if (= (- height 1) (num 'line)) + '() + (position-range (+ (num 'line) 1) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1))))) + (append left right up down)) + +(define asterisks (make-hash)) + +(define (mark-adj-asterisk num) + (define adjs (collect-adjacent-positions num)) + (define (mark coord) + (if (not (char=? #\* (char-at (car coord) (cadr coord)))) + (void) + (let () + (when (not (hash-has-key? asterisks coord)) + (hash-set! asterisks coord '())) + (hash-set! asterisks coord (cons (num 'value) (hash-ref asterisks coord)))))) + (for-each mark adjs)) + +(for-each mark-adj-asterisk nums) + +(define aster-list (hash->list asterisks)) + +(define (is-gear? aster) + (define nums-list (cdr aster)) + (= 2 (length nums-list))) + +(define (power aster) + (define nums-list (cdr aster)) + (* (car nums-list) (cadr nums-list))) + +(apply + (map power (filter is-gear? aster-list))) diff --git a/advent-of-code/2023/03/Makefile b/advent-of-code/2023/03/Makefile deleted file mode 100644 index 44480b6..0000000 --- a/advent-of-code/2023/03/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: run - -run: part1 part2 - ./part1 - ./part2 - -part1: part1.c - gcc -g -I../lib/ ../lib/*.c part1.c -o part1 - -part2: part2.c - gcc -g -I../lib/ ../lib/*.c part2.c -o part2 - -clean: - rm part1 part2 diff --git a/advent-of-code/2023/03/part1.c b/advent-of-code/2023/03/part1.c deleted file mode 100644 index 4ae9ef9..0000000 --- a/advent-of-code/2023/03/part1.c +++ /dev/null @@ -1,130 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <assert.h> - -#include "vec.h" -#include "str.h" - -void* read_input() { - FILE* fp = fopen("./input", "r"); - void *vec = new_vec(); - while(1) { - char *line = fgetline(fp); - if (line == NULL) break; - char *stripped = str_strip(line); - if (strlen(stripped) == 0) break; - vec_push_back(vec, stripped); - } - return vec; -} - -typedef struct { - int line; - int column; - int value; - int length; -} num_t; - -void *parse_nums(void *schema) { - void *nums = new_vec(); - int j = 0; - const int IN_NUM = 0, IDLE = 1; - int state = IDLE; - for (int i = 0; i < vec_size(schema); i++) { - char *line = vec_get(schema, i); - int line_len = strlen(line); - int value = 0; - int length = 0; - state = IDLE; - j = 0; - while (1) { - char c = '.'; - if (j < line_len) c = line[j]; - if (state == IDLE) { - if (isdigit(c)) { - state = IN_NUM; - continue; - } else { - j++; - if (j >= line_len) break; - continue; - } - } else if (state == IN_NUM) { - if (isdigit(c)) { - value = value * 10 + (c - '0'); - length++; - j++; - continue; - } else { - num_t *n = malloc(sizeof(num_t)); - *n = (num_t){ - .line = i, - .column = j - length, - .value = value, - .length = length - }; - vec_push_back(nums, n); - value = 0; - length = 0; - state = IDLE; - if (j >= line_len) break; - continue; - } - } - } - } - return nums; -} - -int is_symbol(char c) { - if (c >= '0' && c <= '9') return 0; - if (c == '.') return 0; - return 1; -} - -int is_a_part(void *schema, num_t *num) { - int line_len = vec_size(schema); - int col_len = strlen(vec_get(schema, 0)); - for (int i = num->column - 1; i < num->column + num->length + 1; i++) { - if (num->line - 1 < 0) continue; - if (i < 0 || i >= col_len) continue; - if (is_symbol(((char*)vec_get(schema, num->line - 1))[i])) { - return 1; - } - } - for (int i = num->column - 1; i < num->column + num->length + 1; i++) { - if (num->line + 1 >= line_len) continue; - if (i < 0 || i >= col_len) continue; - if (is_symbol(((char*)vec_get(schema, num->line + 1))[i])) { - return 1; - } - } - if (num->column - 1 >= 0) { - if (is_symbol(((char*)vec_get(schema, num->line))[num->column - 1])) { - return 1; - } - } - if (num->column + num->length < col_len) { - char *line = vec_get(schema, num->line); - if (is_symbol(line[num->column + num->length])) { - return 1; - } - } - return 0; -} - -int main() { - void *schema = read_input(); - void *nums = parse_nums(schema); - int sum = 0; - for (int i = 0; i < vec_size(nums); i++) { - num_t *num = vec_get(nums, i); - if (is_a_part(schema, num)) { - sum += num->value; - } - } - printf("%d\n", sum); - return 0; -} diff --git a/advent-of-code/2023/03/part2.c b/advent-of-code/2023/03/part2.c deleted file mode 100644 index a5ab825..0000000 --- a/advent-of-code/2023/03/part2.c +++ /dev/null @@ -1,149 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <assert.h> - -#include "vec.h" -#include "str.h" -#include "map.h" - -void* read_input() { - FILE* fp = fopen("./input", "r"); - void *vec = new_vec(); - while(1) { - char *line = fgetline(fp); - if (line == NULL) break; - char *stripped = str_strip(line); - if (strlen(stripped) == 0) break; - vec_push_back(vec, stripped); - } - return vec; -} - -typedef struct { - int line; - int column; - int value; - int length; -} num_t; - -char *compose_key(int x, int y) { - void* ss = new_ss(); - ss_add(ss, "%d,%d", x, y); - return ss_cstr(ss); -} - -void *parse_nums(void *schema) { - void *nums = new_vec(); - int j = 0; - const int IN_NUM = 0, IDLE = 1; - int state = IDLE; - for (int i = 0; i < vec_size(schema); i++) { - char *line = vec_get(schema, i); - int line_len = strlen(line); - int value = 0; - int length = 0; - state = IDLE; - j = 0; - while (1) { - char c = '.'; - if (j < line_len) c = line[j]; - if (state == IDLE) { - if (isdigit(c)) { - state = IN_NUM; - continue; - } else { - j++; - if (j >= line_len) break; - continue; - } - } else if (state == IN_NUM) { - if (isdigit(c)) { - value = value * 10 + (c - '0'); - length++; - j++; - continue; - } else { - num_t *n = malloc(sizeof(num_t)); - *n = (num_t){ - .line = i, - .column = j - length, - .value = value, - .length = length - }; - vec_push_back(nums, n); - value = 0; - length = 0; - state = IDLE; - if (j >= line_len) break; - continue; - } - } - } - } - return nums; -} - -char char_at(void *schema, int line, int column) { - char *buf = vec_get(schema, line); - return buf[column]; -} - -void mark_asterisks(void *asterisks, num_t *num, int x, int y) { - const char *key = compose_key(x, y); - void *num_list = dict_get(asterisks, key); - if (num_list == NULL) { - num_list = new_vec(); - dict_set(asterisks, key, num_list); - } - vec_push_back(num_list, num); -} - -void find_asterisks(void *schema, void *asterisks, num_t *num) { - int line_len = vec_size(schema); - int col_len = strlen(vec_get(schema, 0)); - for (int i = num->column - 1; i < num->column + num->length + 1; i++) { - if (num->line - 1 < 0) continue; - if (i < 0 || i >= col_len) continue; - char c = char_at(schema, num->line - 1, i); - if (c == '*') mark_asterisks(asterisks, num, num->line - 1, i); - } - for (int i = num->column - 1; i < num->column + num->length + 1; i++) { - if (num->line + 1 >= line_len) continue; - if (i < 0 || i >= col_len) continue; - char c = char_at(schema, num->line + 1, i); - if (c == '*') mark_asterisks(asterisks, num, num->line + 1, i); - } - if (num->column - 1 >= 0) { - char c = char_at(schema, num->line, num->column - 1); - if (c == '*') mark_asterisks(asterisks, num, num->line, num->column - 1); - } - if (num->column + num->length < col_len) { - char c = char_at(schema, num->line, num->column + num->length); - if (c == '*') mark_asterisks(asterisks, num, num->line, num->column + num->length); - } -} - -int main() { - void *schema = read_input(); - void *nums = parse_nums(schema); - int sum = 0; - void *asterisks = new_dict(); - for (int i = 0; i < vec_size(nums); i++) { - num_t *num = vec_get(nums, i); - find_asterisks(schema, asterisks, num); - } - for (void *iter = dict_begin(asterisks); - iter != NULL; - iter = dict_next(asterisks, iter)) { - void *list = dict_iter_value(iter); - if (vec_size(list) == 2) { - num_t* n1 = vec_get(list, 0); - num_t* n2 = vec_get(list, 1); - sum += n1->value * n2->value; - } - } - printf("%d\n", sum); - return 0; -} |
