Browse Source

refactor advent of code 2023 day 04 from c to racket

Mistivia 1 year ago
parent
commit
f163146fe4

+ 35 - 0
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)))

+ 53 - 0
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))

+ 0 - 14
advent-of-code/2023/04/Makefile

@@ -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

+ 0 - 69
advent-of-code/2023/04/part1.c

@@ -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;
-}

+ 0 - 81
advent-of-code/2023/04/part2.c

@@ -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;
-}