aoc-all

My solutions to all Advent of Code
git clone https://git.instinctive.eu/aoc-all.git
Log | Files | Refs | README | LICENSE

commit 3f38f34eb00f30603e93e94d6e355de30b388dd2
parent 10371324fb8400ef90f5555d997ace9c82bccee9
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Mon,  4 Dec 2023 22:35:53 +0000

Add day 4 reference and solution
Diffstat:
A2023/day04.scm | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2023/ref/day04.txt | 6++++++
2 files changed, 118 insertions(+), 0 deletions(-)

diff --git a/2023/day04.scm b/2023/day04.scm @@ -0,0 +1,112 @@ +; Copyright (c) 2023, Natacha Porté +; +; Permission to use, copy, modify, and distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +(import (chicken io) (chicken string) + comparse + srfi-1 + srfi-14) + +;;;;;;;;;;;;;;;;; +;; Input parsing + +(define spaces + (one-or-more (is #\space))) + +(define digit + (in char-set:digit)) + +(define digits + (as-string (one-or-more digit))) + +(define number-list + (sequence* ((first digits) + (rest (zero-or-more (preceded-by spaces digits)))) + (result (map string->number (cons first rest))))) + +(define card-line + (sequence* ((_ (sequence (char-seq "Card") spaces)) + (id digits) + (_ (sequence (is #\:) spaces)) + (winning number-list) + (_ (sequence spaces (is #\|) spaces)) + (owned number-list) + (_ (is #\newline))) + (result (list (string->number id) winning owned)))) + +(define all-data + (one-or-more card-line)) + +(define data (parse all-data (read-string))) + +;;;;;;;;;;;;;;;;; +;; Second Puzzle + +(define (is-in? n l) + (cond ((null? l) #f) + ((= n (car l)) #t) + (else (is-in? n (cdr l))))) + +(define (count-score winning todo acc) + (if (null? todo) + acc + (count-score winning + (cdr todo) + (cond ((not (is-in? (car todo) winning)) acc) + ((= acc 0) 1) + (else (* acc 2)))))) + +(define (card-score card) + (let ((winning (cadr card)) + (owned (caddr card))) + (count-score winning owned 0))) + +(define (answer-1 todo acc) + (if (null? todo) acc (answer-1 (cdr todo) (+ acc (card-score (car todo)))))) + +(write-line (conc "First puzzle: " (answer-1 data 0))) + +;;;;;;;;;;;;;;;;; +;; Second Puzzle + +(define (count-matches winning todo acc) + (if (null? todo) + acc + (count-matches winning + (cdr todo) + (if (is-in? (car todo) winning) (add1 acc) acc)))) + +(define (add-copies count-vector id m n) + (if (= 0 n) count-vector + (begin (vector-set! count-vector id (+ (vector-ref count-vector id) m)) + (add-copies count-vector (add1 id) m (sub1 n))))) + +(define (process-card count-vector card) + (let ((id (car card)) + (winning (cadr card)) + (owned (caddr card))) + (add-copies count-vector + (add1 id) + (vector-ref count-vector id) + (count-matches winning owned 0)))) + +(define (process-cards count-vector todo) + (if (null? todo) + count-vector + (process-cards (process-card count-vector (car todo)) (cdr todo)))) + +(define inst-count + (process-cards (make-vector (add1 (length data)) 1) data)) +(vector-set! inst-count 0 0) + +(write-line (conc "Second puzzle: " (apply + (vector->list inst-count)))) diff --git a/2023/ref/day04.txt b/2023/ref/day04.txt @@ -0,0 +1,6 @@ +Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 +Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 +Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 +Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 +Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 +Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11