diff options
| author | Mistivia <i@mistivia.com> | 2024-02-15 17:49:56 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2024-02-15 17:51:00 +0800 |
| commit | f163146fe4b31f1b9e4e25f7f61a5c6928e2fe5b (patch) | |
| tree | e3e99fc5eb674c783ac2947a4276f1b92a892a64 /advent-of-code/2023/04 | |
| parent | 58709a89622062b527b242f65aa0501a4efd47d3 (diff) | |
refactor advent of code 2023 day 04 from c to racket
Diffstat (limited to 'advent-of-code/2023/04')
| -rw-r--r-- | advent-of-code/2023/04/1.rkt | 35 | ||||
| -rw-r--r-- | advent-of-code/2023/04/2.rkt | 53 | ||||
| -rw-r--r-- | advent-of-code/2023/04/Makefile | 14 | ||||
| -rw-r--r-- | advent-of-code/2023/04/part1.c | 69 | ||||
| -rw-r--r-- | advent-of-code/2023/04/part2.c | 81 |
5 files changed, 88 insertions, 164 deletions
diff --git a/advent-of-code/2023/04/1.rkt b/advent-of-code/2023/04/1.rkt new file mode 100644 index 0000000..30ea62f --- /dev/null +++ b/advent-of-code/2023/04/1.rkt @@ -0,0 +1,35 @@ +#lang racket + +(require "../lib/obj.rkt") + +(define (get-lines fp) + (let loop ((lines '())) + (define l (read-line fp)) + (if (eof-object? l) + (reverse lines) + (loop (cons l lines))))) + +(define fp (open-input-file "input")) + +(define lines (get-lines fp)) + +(define (strip-head s) + (string-trim (cadr (string-split s ":")))) + +(set! lines (map strip-head lines)) + +(define make-card (obj-maker 'win-nums 'nums)) + +(define (parse-card s) + (define lst (string-split s "|")) + (define win-nums (map string->number (string-split (car lst)))) + (define nums (map string->number (string-split (cadr lst)))) + (make-card win-nums nums)) + +(define (point card) + (define wins (length (filter (lambda (x) (member x (card 'win-nums))) (card 'nums)))) + (if (= wins 0) + 0 + (expt 2 (- wins 1)))) + +(apply + (map point (map parse-card lines))) diff --git a/advent-of-code/2023/04/2.rkt b/advent-of-code/2023/04/2.rkt new file mode 100644 index 0000000..cf874d2 --- /dev/null +++ b/advent-of-code/2023/04/2.rkt @@ -0,0 +1,53 @@ +#lang racket + +(require "../lib/obj.rkt") + +(define (get-lines fp) + (let loop ((lines '())) + (define l (read-line fp)) + (if (eof-object? l) + (reverse lines) + (loop (cons l lines))))) + +(define fp (open-input-file "input")) + +(define lines (get-lines fp)) + +(define (strip-head s) + (string-trim (cadr (string-split s ":")))) + +(set! lines (map strip-head lines)) + +(define make-card (obj-maker 'win-nums 'nums)) + +(define (parse-card s) + (define lst (string-split s "|")) + (define win-nums (map string->number (string-split (car lst)))) + (define nums (map string->number (string-split (cadr lst)))) + (make-card win-nums nums)) + +(define cards (map parse-card lines)) + +(define card-count (make-vector (length cards) 1)) + +(define (win-count card) + (length (filter (lambda (x) (member x (card 'win-nums))) (card 'nums)))) + +(define card-vec (list->vector cards)) + +(let loop ((i 0)) + (if (>= i (vector-length card-count)) + (void) + (let () + (define win-cnt (win-count (vector-ref card-vec i))) + (let loop ((j (+ i 1))) + (if (or (>= j (vector-length card-count)) + (>= j (+ 1 i win-cnt))) + (void) + (let () + (vector-set! card-count j (+ (vector-ref card-count i) + (vector-ref card-count j))) + (loop (+ 1 j))))) + (loop (+ 1 i))))) + +(apply + (vector->list card-count))
\ No newline at end of file diff --git a/advent-of-code/2023/04/Makefile b/advent-of-code/2023/04/Makefile deleted file mode 100644 index 122af1e..0000000 --- a/advent-of-code/2023/04/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: run - -run: part1 part2 - ./part1 - ./part2 - -part1: part1.c - gcc -g -lm -I../lib/ ../lib/*.c part1.c -o part1 - -part2: part2.c - gcc -g -lm -I../lib/ ../lib/*.c part2.c -o part2 - -clean: - rm part1 part2 diff --git a/advent-of-code/2023/04/part1.c b/advent-of-code/2023/04/part1.c deleted file mode 100644 index 4dd94ba..0000000 --- a/advent-of-code/2023/04/part1.c +++ /dev/null @@ -1,69 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#include "vec.h" -#include "str.h" - -typedef struct { - void *win_nums; - void *nums; -} card_t; - -void *parse_input() { - FILE *fp = fopen("./input", "r"); - void *cards = new_vec(); - char *line; - while ((line = fgetline(fp)) != NULL) { - line = str_strip(line); - line = vec_get(str_split(line, ':'), 1); - line = str_strip(line); - void *splited = str_split(line, '|'); - char *win_str = str_strip(vec_get(splited, 0)); - char *num_str = str_strip(vec_get(splited, 1)); - void *winnums_str = str_split(win_str, ' '); - void *nums_str = str_split(num_str, ' '); - - card_t *card = malloc(sizeof(card_t)); - card->win_nums = new_vec(); - card->nums = new_vec(); - for (int i = 0; i < vec_size(winnums_str); i++) { - int *n = malloc(sizeof(int)); - *n = strtol(vec_get(winnums_str, i), NULL, 10); - vec_push_back(card->win_nums, n); - } - for (int i = 0; i < vec_size(nums_str); i++) { - int *n = malloc(sizeof(int)); - *n = strtol(vec_get(nums_str, i), NULL, 10); - vec_push_back(card->nums, n); - } - vec_push_back(cards, card); - } - return cards; -} - -int points(card_t *card) { - int win_count = 0; - for (int i = 0; i < vec_size(card->nums); i++) { - int num = *(int*)vec_get(card->nums, i); - for (int j = 0; j < vec_size(card->win_nums); j++) { - if (num == *(int*)vec_get(card->win_nums, j)) { - win_count++; - break; - } - } - } - if (win_count == 0) return 0; - return (int)pow(2, win_count - 1); -} - -int main() { - void *cards = parse_input(); - int sum = 0; - for (int i = 0; i < vec_size(cards); i++) { - int p = points(vec_get(cards, i)); - sum += p; - } - printf("%d\n", sum); - return 0; -} diff --git a/advent-of-code/2023/04/part2.c b/advent-of-code/2023/04/part2.c deleted file mode 100644 index 5e67ead..0000000 --- a/advent-of-code/2023/04/part2.c +++ /dev/null @@ -1,81 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> - -#include "vec.h" -#include "str.h" - -typedef struct { - void *win_nums; - void *nums; -} card_t; - -void *parse_input() { - FILE *fp = fopen("./input", "r"); - void *cards = new_vec(); - char *line; - while ((line = fgetline(fp)) != NULL) { - line = str_strip(line); - line = vec_get(str_split(line, ':'), 1); - line = str_strip(line); - void *splited = str_split(line, '|'); - char *win_str = str_strip(vec_get(splited, 0)); - char *num_str = str_strip(vec_get(splited, 1)); - void *winnums_str = str_split(win_str, ' '); - void *nums_str = str_split(num_str, ' '); - - card_t *card = malloc(sizeof(card_t)); - card->win_nums = new_vec(); - card->nums = new_vec(); - for (int i = 0; i < vec_size(winnums_str); i++) { - int *n = malloc(sizeof(int)); - *n = strtol(vec_get(winnums_str, i), NULL, 10); - vec_push_back(card->win_nums, n); - } - for (int i = 0; i < vec_size(nums_str); i++) { - int *n = malloc(sizeof(int)); - *n = strtol(vec_get(nums_str, i), NULL, 10); - vec_push_back(card->nums, n); - } - vec_push_back(cards, card); - } - return cards; -} - -int win_count(card_t *card) { - int win_count = 0; - for (int i = 0; i < vec_size(card->nums); i++) { - int num = *(int*)vec_get(card->nums, i); - for (int j = 0; j < vec_size(card->win_nums); j++) { - if (num == *(int*)vec_get(card->win_nums, j)) { - win_count++; - break; - } - } - } - return win_count; -} - -int process_card(int *card_cnt, void *cards, int i) { - int card_num = vec_size(cards); - int win_cnt = win_count(vec_get(cards, i)); - for (int j = i + 1; j < card_num && j < i + 1 + win_cnt; j++) { - card_cnt[j] += card_cnt[i]; - } - return card_cnt[i]; -} - -int main() { - void *cards = parse_input(); - int sum = 0; - int *card_cnt = malloc(sizeof(int) * vec_size(cards)); - for (int i = 0; i < vec_size(cards); i++) { - card_cnt[i] = 1; - } - for (int i = 0; i < vec_size(cards); i++) { - sum += process_card(card_cnt, cards, i); - } - printf("%d\n", sum); - return 0; -} |
