Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4834

Teaching and learning resources • Re: Advent of Code 2024

$
0
0
Finally! I've completed day 19. It took a week (for part 2).
Naive version (that was passing the test case) of both part1 and part2 was done in 30 minutes the first day.
After that it took me the rest of the first day to add some short additional functions just to speed up the calculation. Functions like prune-towels, that removes useless towels (before starting a new match for each design string), and function can-match that collects only those towels (from already pruned) that can be the current prefix of a design string. By the end of first day I had the working (memoized) version for part1, that was accepted
The problem I had with part2 was that the function that calculated part2 was not purely functionl design. Althogh it was 99% identical to the part1 function, the base case, instead of returning #t (true) like for part1, was first setting the global count variable and then returning #f (false). And just because of that, I could not memoize it.
Both part1 and part2 were designed with one "and" inside the "or" that was forcing the backtracking. However for part2 this was always returning just #f, and therefore could not be memoized.
In the end, I changed the design to build a tree, instead of just backtracking on failure.
This is the function that does everything. It calculates simultaneously part1 (just take the length of returned list of matches that are not 0), and part2, just add all the numbers, after the tree function returns.

Code:

(define (tree dsnt twls)  (let* ((dsn (car dsnt)) (dl (string-length dsn)))    (if (zero? dl)1(apply + (map (lambda (dt) (tree dt twls))      (map (chop dsn dl) (can-match dsn dl twls)))))))
And that's all there is to it!

Code:

;;; Advent of code 2024 - day19, part1 & part2, on BPI-F3 RISC-V;;; Chez code (load "utils.so")(define (can-match s sl twls)  (filter   (lambda (p)      (string=? (substring s 0 (min (string-length p) sl)) p)) twls))(define (chop dsn dl)  (lambda (pat)    (list (substring dsn (string-length pat) dl))))(define (tree dsnt twls)  (let* ((dsn (car dsnt)) (dl (string-length dsn)))    (if (zero? dl)1(apply + (map (lambda (dt) (tree dt twls))      (map (chop dsn dl) (can-match dsn dl twls)))))))(define (prune-towels dsn twls)  (let ((len (string-length dsn)))    (filter (lambda (p)      (let f ([i 0])(let ((pl (string-length p)))  (cond   ((> (+ i pl) len) #f)   ((string=? (substring dsn i (+ i pl)) p))   (else (f (add1 i))))))) twls)))(define (day19 file)  (let* ((rawl (read-lines file)) (towels (sort ; greedy algorithm  (lambda (x y) (< (string-length x) (string-length y)))  (string-split-n (car rawl) '(#\space #\,)))) (dsns (cddr rawl)) (pruned (map (lambda (d) (prune-towels d towels)) dsns)) (result (filter (compose not zero?) (map (lambda (t p) (tree (list t) p)) dsns pruned))))    (values (length result) (apply + result))))
Considering that this is run on "banana" and from Emacs, and that the result is 700+ trillion, my hat is off to Chez Scheme.

Code:

> (time2 (lambda () (day19 "input.txt")))304705756472327497#<time-duration 1.483221209>

Statistics: Posted by hrvoje064 — Fri Dec 27, 2024 4:09 pm



Viewing all articles
Browse latest Browse all 4834

Trending Articles