aoc2023/5.rkt

77 lines
2.7 KiB
Racket
Raw Normal View History

2023-12-05 05:34:56 +00:00
#lang curly-fn racket
(require "scripts/aoc.rkt")
;; solution for day 5
(struct rngmap [dst src len] #:transparent)
(define (transform-layer num mapping)
(or
(for/first ([entry (in-list mapping)]
#:do [(match-define (rngmap dst src len) entry)]
#:when (>= num src)
#:when (< num (+ src len)))
(+ dst (- num src)))
num))
(define (transform-all num mappings)
(for/fold ([cur-num num]) ([mapping (in-list mappings)])
(transform-layer cur-num mapping)))
(define (part1 input)
(apply min
(for/list ([num (in-list (first input))])
(transform-all num (rest input)))))
(define (part2-transform-layer iset mapping)
(define-values [rem-src dst]
(for/fold ([cur-src iset] [cur-dst (is:make-integer-set '())])
([entry (in-list mapping)]
#:do [(match-define (rngmap dst src len) entry)])
(define entry-src (is:make-range src (+ src (sub1 len))))
(define captured-values (is:intersect cur-src entry-src))
(define captured-wfs (is:integer-set-contents captured-values))
(define transformed-wfs
(for/list ([wfs-entry (in-list captured-wfs)])
(cons (+ dst (- (car wfs-entry) src))
(+ dst (- (cdr wfs-entry) src)))))
(define transformed-iset (is:make-integer-set transformed-wfs))
(values (is:subtract cur-src entry-src) (is:union cur-dst transformed-iset))))
(is:union rem-src dst))
(define (part2-transform-all iset mappings)
(for/fold ([cur-iset iset]) ([mapping (in-list mappings)])
(part2-transform-layer cur-iset mapping)))
(define (part2 input)
(define ranges (first input))
(define ranges-iset
(for/fold ([is (is:make-integer-set '())])
([chunk (in-slice 2 (in-list ranges))])
(is:union is
(is:make-range (first chunk) (+ (first chunk) (sub1 (second chunk)))))))
(define mappings (rest input))
(define ranges-out (part2-transform-all ranges-iset mappings))
(car (first (is:integer-set-contents ranges-out))))
(define (parse fname)
(match-define (cons initial mappings) (string-split (file->string fname) "\n\n"))
(define initial-nums (map string->number (rest (string-split initial " "))))
(define mapping-nums
(for/list ([map-str (in-list mappings)])
(define entries (rest (string-split map-str "\n")))
(for/list ([entry (in-list entries)])
(match-define (list dst src len) (map string->number (string-split entry " ")))
(rngmap dst src len))))
(cons initial-nums mapping-nums))
; (part2 (parse "inputs/5-test1"))
; (error)
(module+ main
(define input (parse "inputs/5"))
(answer 5 1 (time (part1 input)))
(answer 5 2 (time (part2 input)))
(displayln "meow"))