Various refactorings.
This commit is contained in:
parent
5a6bc1e053
commit
a6085863c6
131
lib.rkt
131
lib.rkt
|
@ -10,59 +10,11 @@
|
|||
read-file))
|
||||
|
||||
(provide (all-from-out threading)
|
||||
|
||||
problem-input
|
||||
problem-input-all
|
||||
problem-input-grouped
|
||||
show-solution
|
||||
|
||||
make-vector-grid
|
||||
vector-grid-update
|
||||
lists->vectors
|
||||
vectors->lists
|
||||
lists->hash
|
||||
hash->vectors
|
||||
show-list-grid
|
||||
show-vector-grid
|
||||
show-hash-grid
|
||||
|
||||
∘ ∂ ∂r $ %
|
||||
uncurry
|
||||
|
||||
string->number*
|
||||
string->symbol*
|
||||
|
||||
nchar=?
|
||||
char-alphanumeric?
|
||||
|
||||
sum
|
||||
!=
|
||||
nzero?
|
||||
negate
|
||||
pos-or-zero
|
||||
number->digits
|
||||
number->digits-reverse
|
||||
digits->number
|
||||
string->binary
|
||||
|
||||
snoc
|
||||
scanl scanr
|
||||
list-ref*
|
||||
repeat
|
||||
chunks-of
|
||||
transpose
|
||||
list->queue
|
||||
|
||||
vector-first
|
||||
vector-last
|
||||
vector-ref*
|
||||
vector-grid-ref*
|
||||
vector-set!*
|
||||
hash->vector
|
||||
vector->hash)
|
||||
(all-defined-out))
|
||||
|
||||
|
||||
;; Function helpers ;;
|
||||
|
||||
(define ∘ compose)
|
||||
(define ∂ curry)
|
||||
(define ∂r curryr)
|
||||
|
@ -103,18 +55,35 @@
|
|||
|
||||
;; Grid helpers ;;
|
||||
;; A grid of values might be stored in three different ways:
|
||||
;; - As a hashtable from positions (number . number) to values; or
|
||||
;; - As a hashtable from coordinates (list x y) to values; or
|
||||
;; - As a vector of vectors of values; or
|
||||
;; - As a list of lists of values.
|
||||
;; coord = (list? number? number?)
|
||||
;; Coordinate axes point right (x-axis) and down (y-axis).
|
||||
|
||||
;; make-vector-grid : number -> number -> number -> vector-grid
|
||||
(define (make-vector-grid width height [default 0])
|
||||
(build-vector height (λ (_) (make-vector width default))))
|
||||
|
||||
;; vector-grid-update : vector-grid -> (number . number) -> a -> void
|
||||
;; vector-grid-update : vector-grid -> coord -> a -> void
|
||||
;; Set the vector grid to given value at position (row, col)
|
||||
(define (vector-grid-update vector-grid pos value)
|
||||
(vector-set! (vector-ref vector-grid (car pos)) (cdr pos) value))
|
||||
(define (vector-grid-update vector-grid coord value)
|
||||
(vector-set! (vector-ref vector-grid (second coord)) (first coord) value))
|
||||
|
||||
;; vector-grid-ref* : (vectorof (vectorof any)) -> coord -> any -> any
|
||||
;; Given coordinates (x, y), in the yth vector, find the xth element.
|
||||
;; If either x or y are beyond the indices of the vectors,
|
||||
;; return the default value provided.
|
||||
(define (vector-grid-ref* grid coord failure-result)
|
||||
(match-let ([(list x y) coord]
|
||||
[y-len (vector-length grid)])
|
||||
(if (or (< y 0) (>= y y-len))
|
||||
failure-result
|
||||
(let* ([row (vector-ref grid y)]
|
||||
[x-len (vector-length row)])
|
||||
(if (or (< x 0) (>= x x-len))
|
||||
failure-result
|
||||
(vector-ref row x))))))
|
||||
|
||||
;; lists->vectors : list-grid -> vector-grid
|
||||
(define (lists->vectors list-grid)
|
||||
|
@ -131,24 +100,24 @@
|
|||
(for*/fold ([hash-grid (hash)])
|
||||
([x (in-range width)]
|
||||
[y (in-range length)])
|
||||
(hash-set hash-grid (cons x y) (list-ref (list-ref list-grid y) x)))))
|
||||
(hash-set hash-grid (list x y) (list-ref (list-ref list-grid y) x)))))
|
||||
|
||||
;; hash->vectors : hash-grid -> number -> vector-grid
|
||||
;; Where the position is not in the hash-grid,
|
||||
;; When a coordinate is not in the hash-grid,
|
||||
;; the vector-grid takes on the default value.
|
||||
(define (hash->vectors hash-grid [default 0])
|
||||
(let* ([keys (hash-keys hash-grid)]
|
||||
[xs (map car keys)]
|
||||
[ys (map cdr keys)]
|
||||
[xs (map first keys)]
|
||||
[ys (map second keys)]
|
||||
[min-x (apply min xs)]
|
||||
[min-y (apply min ys)]
|
||||
[width (add1 (- (apply max xs) min-x))]
|
||||
[height (add1 (- (apply max ys) min-y))]
|
||||
[vector-grid (make-vector-grid width height default)])
|
||||
(hash-for-each
|
||||
hash-grid (λ (pos val)
|
||||
(let ([x (- (car pos) min-x)]
|
||||
[y (- (cdr pos) min-y)])
|
||||
hash-grid (λ (coord val)
|
||||
(let ([x (- (first coord) min-x)]
|
||||
[y (- (second coord) min-y)])
|
||||
(vector-set! (vector-ref vector-grid y) x val))))
|
||||
vector-grid))
|
||||
|
||||
|
@ -169,7 +138,7 @@
|
|||
(show-vector-grid char-hash (hash->vectors hash-grid default)))
|
||||
|
||||
|
||||
;; Conversion helpers ;;
|
||||
;; String helpers ;;
|
||||
|
||||
;; string->number* : (or/c string? #f) -> (or/c number? #f)
|
||||
(define (string->number* s)
|
||||
|
@ -179,6 +148,23 @@
|
|||
(define (string->symbol* s)
|
||||
(and (string? s) (string->symbol s)))
|
||||
|
||||
;; string->binary : string? -> number?
|
||||
;; Given a string representation of a binary number,
|
||||
;; convert it to the number it represents
|
||||
(define (string->binary str)
|
||||
(string->number (string-append "#b" str)))
|
||||
|
||||
;; string-replaces : string? -> (listof (list? string? string?)) -> string
|
||||
;; Perform string replacements in order,
|
||||
;; so that later replacments may affect earlier ones
|
||||
(define (string-replaces str replaces)
|
||||
(if (empty? replaces)
|
||||
str
|
||||
(string-replaces (string-replace str
|
||||
(caar replaces)
|
||||
(cadar replaces))
|
||||
(rest replaces))))
|
||||
|
||||
|
||||
;; Char helpers ;;
|
||||
|
||||
|
@ -236,12 +222,6 @@
|
|||
(if (empty? ns) n
|
||||
(loop (+ (* n 10) (car ns)) (cdr ns)))))
|
||||
|
||||
;; string->binary : string -> number
|
||||
;; Given a string representation of a binary number,
|
||||
;; convert it to the number it represents
|
||||
(define (string->binary str)
|
||||
(string->number (string-append "#b" str)))
|
||||
|
||||
|
||||
;; List helpers ;;
|
||||
|
||||
|
@ -327,21 +307,6 @@
|
|||
failure-result
|
||||
(vector-ref vec pos)))
|
||||
|
||||
;; vector-grid-ref* : (vectorof (vectorof any)) -> (list number number) -> any -> any
|
||||
;; Given coordinates (x, y), in the yth vector, find the xth element.
|
||||
;; If either x or y are beyond the indices of the vectors,
|
||||
;; return the default value provided.
|
||||
(define (vector-grid-ref* grid coord failure-result)
|
||||
(match-let ([(list x y) coord]
|
||||
[y-len (vector-length grid)])
|
||||
(if (or (< y 0) (>= y y-len))
|
||||
failure-result
|
||||
(let* ([row (vector-ref grid y)]
|
||||
[x-len (vector-length row)])
|
||||
(if (or (< x 0) (>= x x-len))
|
||||
failure-result
|
||||
(vector-ref row x))))))
|
||||
|
||||
;; vector-set!* : (vectorof any) -> number -> any -> (vectorof any)
|
||||
;; Set the value at given index in a new vector, then return that vector
|
||||
;; If the index is beyond the indices of the vector,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#lang curly-fn racket
|
||||
|
||||
(require threading
|
||||
"../lib.rkt")
|
||||
(require "../lib.rkt")
|
||||
|
||||
(define input (lists->vectors (map string->list (problem-input 11))))
|
||||
(define width (vector-length (vector-ref input 0)))
|
||||
|
|
24
src/12.rkt
24
src/12.rkt
|
@ -21,21 +21,17 @@
|
|||
[`(,_ 180) (values x y (- dx) (- dy))]))
|
||||
|
||||
(define part1
|
||||
(match-let-values
|
||||
([(x y dx dy)
|
||||
(for/fold ([x 0] [y 0]
|
||||
[dx 1] [dy 0])
|
||||
([instr input])
|
||||
(move instr 1 0 x y dx dy))])
|
||||
(+ (abs x) (abs y))))
|
||||
(for/fold ([x 0] [y 0]
|
||||
[dx 1] [dy 0]
|
||||
#:result (+ (abs x) (abs y)))
|
||||
([instr input])
|
||||
(move instr 1 0 x y dx dy)))
|
||||
|
||||
(define part2
|
||||
(match-let-values
|
||||
([(x-ship y-ship x-wpt y-wpt)
|
||||
(for/fold ([x-ship 0] [y-ship 0]
|
||||
[x-wpt 10] [y-wpt -1])
|
||||
([instr input])
|
||||
(move instr 0 1 x-ship y-ship x-wpt y-wpt))])
|
||||
(+ (abs x-ship) (abs y-ship))))
|
||||
(for/fold ([x-ship 0] [y-ship 0]
|
||||
[x-wpt 10] [y-wpt -1]
|
||||
#:result (+ (abs x-ship) (abs y-ship)))
|
||||
([instr input])
|
||||
(move instr 0 1 x-ship y-ship x-wpt y-wpt)))
|
||||
|
||||
(show-solution part1 part2)
|
||||
|
|
56
src/14.rkt
56
src/14.rkt
|
@ -17,9 +17,9 @@
|
|||
(match instr
|
||||
[(regexp #px"^mask = (\\w+)$" (list _ mask))
|
||||
(let* ([ormask (string->binary (string-replace mask "X" "0"))]
|
||||
[andmask (string->binary (regexp-replaces mask '([#rx"0" "1"] [#rx"X" "0"])))]
|
||||
[andmask (string->binary (string-replaces mask '(["0" "1"] ["X" "0"])))]
|
||||
[X-indices (indexes-of (string->list mask) #\X)]
|
||||
[X-ormasks (map #{expt 2 (sub1 (- (string-length mask) %))} X-indices)])
|
||||
[X-ormasks (map #{expt 2 (- (sub1 (string-length mask)) %)} X-indices)])
|
||||
(list 'mask ormask andmask X-ormasks))]
|
||||
[(regexp #px"^mem\\[(\\d+)\\] = (\\d+)" (list _ addr val))
|
||||
(list 'write (string->number addr) (string->number val))]))
|
||||
|
@ -32,35 +32,31 @@
|
|||
rest-addrs))))
|
||||
|
||||
(define part1
|
||||
(match-let-values
|
||||
([(mem _ _)
|
||||
(for/fold ([mem (hash)]
|
||||
[ormask 0]
|
||||
[andmask -1])
|
||||
([instr (map parse1 input)])
|
||||
(match instr
|
||||
[(list 'mask ormask andmask)
|
||||
(values mem ormask andmask)]
|
||||
[(list 'write addr val)
|
||||
(let ([val (bitwise-ior ormask (bitwise-and andmask val))])
|
||||
(values (hash-set mem addr val) ormask andmask))]))])
|
||||
(sum (hash-values mem))))
|
||||
(for/fold ([mem (hash)]
|
||||
[ormask 0]
|
||||
[andmask -1]
|
||||
#:result (sum (hash-values mem)))
|
||||
([instr (sequence-map parse1 input)])
|
||||
(match instr
|
||||
[(list 'mask ormask andmask)
|
||||
(values mem ormask andmask)]
|
||||
[(list 'write addr val)
|
||||
(let ([val (bitwise-ior ormask (bitwise-and andmask val))])
|
||||
(values (hash-set mem addr val) ormask andmask))])))
|
||||
|
||||
(define part2
|
||||
(match-let-values
|
||||
([(mem _ _ _)
|
||||
(for/fold ([mem (hash)]
|
||||
[ormask 0]
|
||||
[andmask -1]
|
||||
[X-ormasks '()])
|
||||
([instr (map parse2 input)])
|
||||
(match instr
|
||||
[(list 'mask ormask andmask X-ormasks)
|
||||
(values mem ormask andmask X-ormasks)]
|
||||
[(list 'write addr val)
|
||||
(let* ([addr (bitwise-ior ormask (bitwise-and andmask addr))]
|
||||
[mem (foldl #{hash-set %2 %1 val} mem (addrs addr X-ormasks))])
|
||||
(values mem ormask andmask X-ormasks))]))])
|
||||
(sum (hash-values mem))))
|
||||
(for/fold ([mem (hash)]
|
||||
[ormask 0]
|
||||
[andmask -1]
|
||||
[X-ormasks '()]
|
||||
#:result (sum (hash-values mem)))
|
||||
([instr (sequence-map parse2 input)])
|
||||
(match instr
|
||||
[(list 'mask ormask andmask X-ormasks)
|
||||
(values mem ormask andmask X-ormasks)]
|
||||
[(list 'write addr val)
|
||||
(let* ([addr (bitwise-ior ormask (bitwise-and andmask addr))]
|
||||
[mem (foldl #{hash-set %2 %1 val} mem (addrs addr X-ormasks))])
|
||||
(values mem ormask andmask X-ormasks))])))
|
||||
|
||||
(show-solution part1 part2)
|
||||
|
|
Loading…
Reference in New Issue