Various refactorings.
This commit is contained in:
parent
5a6bc1e053
commit
a6085863c6
131
lib.rkt
131
lib.rkt
|
@ -10,59 +10,11 @@
|
||||||
read-file))
|
read-file))
|
||||||
|
|
||||||
(provide (all-from-out threading)
|
(provide (all-from-out threading)
|
||||||
|
(all-defined-out))
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
;; Function helpers ;;
|
;; Function helpers ;;
|
||||||
|
|
||||||
(define ∘ compose)
|
(define ∘ compose)
|
||||||
(define ∂ curry)
|
(define ∂ curry)
|
||||||
(define ∂r curryr)
|
(define ∂r curryr)
|
||||||
|
@ -103,18 +55,35 @@
|
||||||
|
|
||||||
;; Grid helpers ;;
|
;; Grid helpers ;;
|
||||||
;; A grid of values might be stored in three different ways:
|
;; 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 vector of vectors of values; or
|
||||||
;; - As a list of lists of values.
|
;; - 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
|
;; make-vector-grid : number -> number -> number -> vector-grid
|
||||||
(define (make-vector-grid width height [default 0])
|
(define (make-vector-grid width height [default 0])
|
||||||
(build-vector height (λ (_) (make-vector width default))))
|
(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)
|
;; Set the vector grid to given value at position (row, col)
|
||||||
(define (vector-grid-update vector-grid pos value)
|
(define (vector-grid-update vector-grid coord value)
|
||||||
(vector-set! (vector-ref vector-grid (car pos)) (cdr pos) 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
|
;; lists->vectors : list-grid -> vector-grid
|
||||||
(define (lists->vectors list-grid)
|
(define (lists->vectors list-grid)
|
||||||
|
@ -131,24 +100,24 @@
|
||||||
(for*/fold ([hash-grid (hash)])
|
(for*/fold ([hash-grid (hash)])
|
||||||
([x (in-range width)]
|
([x (in-range width)]
|
||||||
[y (in-range length)])
|
[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
|
;; 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.
|
;; the vector-grid takes on the default value.
|
||||||
(define (hash->vectors hash-grid [default 0])
|
(define (hash->vectors hash-grid [default 0])
|
||||||
(let* ([keys (hash-keys hash-grid)]
|
(let* ([keys (hash-keys hash-grid)]
|
||||||
[xs (map car keys)]
|
[xs (map first keys)]
|
||||||
[ys (map cdr keys)]
|
[ys (map second keys)]
|
||||||
[min-x (apply min xs)]
|
[min-x (apply min xs)]
|
||||||
[min-y (apply min ys)]
|
[min-y (apply min ys)]
|
||||||
[width (add1 (- (apply max xs) min-x))]
|
[width (add1 (- (apply max xs) min-x))]
|
||||||
[height (add1 (- (apply max ys) min-y))]
|
[height (add1 (- (apply max ys) min-y))]
|
||||||
[vector-grid (make-vector-grid width height default)])
|
[vector-grid (make-vector-grid width height default)])
|
||||||
(hash-for-each
|
(hash-for-each
|
||||||
hash-grid (λ (pos val)
|
hash-grid (λ (coord val)
|
||||||
(let ([x (- (car pos) min-x)]
|
(let ([x (- (first coord) min-x)]
|
||||||
[y (- (cdr pos) min-y)])
|
[y (- (second coord) min-y)])
|
||||||
(vector-set! (vector-ref vector-grid y) x val))))
|
(vector-set! (vector-ref vector-grid y) x val))))
|
||||||
vector-grid))
|
vector-grid))
|
||||||
|
|
||||||
|
@ -169,7 +138,7 @@
|
||||||
(show-vector-grid char-hash (hash->vectors hash-grid default)))
|
(show-vector-grid char-hash (hash->vectors hash-grid default)))
|
||||||
|
|
||||||
|
|
||||||
;; Conversion helpers ;;
|
;; String helpers ;;
|
||||||
|
|
||||||
;; string->number* : (or/c string? #f) -> (or/c number? #f)
|
;; string->number* : (or/c string? #f) -> (or/c number? #f)
|
||||||
(define (string->number* s)
|
(define (string->number* s)
|
||||||
|
@ -179,6 +148,23 @@
|
||||||
(define (string->symbol* s)
|
(define (string->symbol* s)
|
||||||
(and (string? s) (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 ;;
|
;; Char helpers ;;
|
||||||
|
|
||||||
|
@ -236,12 +222,6 @@
|
||||||
(if (empty? ns) n
|
(if (empty? ns) n
|
||||||
(loop (+ (* n 10) (car ns)) (cdr ns)))))
|
(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 ;;
|
;; List helpers ;;
|
||||||
|
|
||||||
|
@ -327,21 +307,6 @@
|
||||||
failure-result
|
failure-result
|
||||||
(vector-ref vec pos)))
|
(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)
|
;; vector-set!* : (vectorof any) -> number -> any -> (vectorof any)
|
||||||
;; Set the value at given index in a new vector, then return that vector
|
;; Set the value at given index in a new vector, then return that vector
|
||||||
;; If the index is beyond the indices of the vector,
|
;; If the index is beyond the indices of the vector,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#lang curly-fn racket
|
#lang curly-fn racket
|
||||||
|
|
||||||
(require threading
|
(require "../lib.rkt")
|
||||||
"../lib.rkt")
|
|
||||||
|
|
||||||
(define input (lists->vectors (map string->list (problem-input 11))))
|
(define input (lists->vectors (map string->list (problem-input 11))))
|
||||||
(define width (vector-length (vector-ref input 0)))
|
(define width (vector-length (vector-ref input 0)))
|
||||||
|
|
16
src/12.rkt
16
src/12.rkt
|
@ -21,21 +21,17 @@
|
||||||
[`(,_ 180) (values x y (- dx) (- dy))]))
|
[`(,_ 180) (values x y (- dx) (- dy))]))
|
||||||
|
|
||||||
(define part1
|
(define part1
|
||||||
(match-let-values
|
|
||||||
([(x y dx dy)
|
|
||||||
(for/fold ([x 0] [y 0]
|
(for/fold ([x 0] [y 0]
|
||||||
[dx 1] [dy 0])
|
[dx 1] [dy 0]
|
||||||
|
#:result (+ (abs x) (abs y)))
|
||||||
([instr input])
|
([instr input])
|
||||||
(move instr 1 0 x y dx dy))])
|
(move instr 1 0 x y dx dy)))
|
||||||
(+ (abs x) (abs y))))
|
|
||||||
|
|
||||||
(define part2
|
(define part2
|
||||||
(match-let-values
|
|
||||||
([(x-ship y-ship x-wpt y-wpt)
|
|
||||||
(for/fold ([x-ship 0] [y-ship 0]
|
(for/fold ([x-ship 0] [y-ship 0]
|
||||||
[x-wpt 10] [y-wpt -1])
|
[x-wpt 10] [y-wpt -1]
|
||||||
|
#:result (+ (abs x-ship) (abs y-ship)))
|
||||||
([instr input])
|
([instr input])
|
||||||
(move instr 0 1 x-ship y-ship x-wpt y-wpt))])
|
(move instr 0 1 x-ship y-ship x-wpt y-wpt)))
|
||||||
(+ (abs x-ship) (abs y-ship))))
|
|
||||||
|
|
||||||
(show-solution part1 part2)
|
(show-solution part1 part2)
|
||||||
|
|
24
src/14.rkt
24
src/14.rkt
|
@ -17,9 +17,9 @@
|
||||||
(match instr
|
(match instr
|
||||||
[(regexp #px"^mask = (\\w+)$" (list _ mask))
|
[(regexp #px"^mask = (\\w+)$" (list _ mask))
|
||||||
(let* ([ormask (string->binary (string-replace mask "X" "0"))]
|
(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-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))]
|
(list 'mask ormask andmask X-ormasks))]
|
||||||
[(regexp #px"^mem\\[(\\d+)\\] = (\\d+)" (list _ addr val))
|
[(regexp #px"^mem\\[(\\d+)\\] = (\\d+)" (list _ addr val))
|
||||||
(list 'write (string->number addr) (string->number val))]))
|
(list 'write (string->number addr) (string->number val))]))
|
||||||
|
@ -32,35 +32,31 @@
|
||||||
rest-addrs))))
|
rest-addrs))))
|
||||||
|
|
||||||
(define part1
|
(define part1
|
||||||
(match-let-values
|
|
||||||
([(mem _ _)
|
|
||||||
(for/fold ([mem (hash)]
|
(for/fold ([mem (hash)]
|
||||||
[ormask 0]
|
[ormask 0]
|
||||||
[andmask -1])
|
[andmask -1]
|
||||||
([instr (map parse1 input)])
|
#:result (sum (hash-values mem)))
|
||||||
|
([instr (sequence-map parse1 input)])
|
||||||
(match instr
|
(match instr
|
||||||
[(list 'mask ormask andmask)
|
[(list 'mask ormask andmask)
|
||||||
(values mem ormask andmask)]
|
(values mem ormask andmask)]
|
||||||
[(list 'write addr val)
|
[(list 'write addr val)
|
||||||
(let ([val (bitwise-ior ormask (bitwise-and andmask val))])
|
(let ([val (bitwise-ior ormask (bitwise-and andmask val))])
|
||||||
(values (hash-set mem addr val) ormask andmask))]))])
|
(values (hash-set mem addr val) ormask andmask))])))
|
||||||
(sum (hash-values mem))))
|
|
||||||
|
|
||||||
(define part2
|
(define part2
|
||||||
(match-let-values
|
|
||||||
([(mem _ _ _)
|
|
||||||
(for/fold ([mem (hash)]
|
(for/fold ([mem (hash)]
|
||||||
[ormask 0]
|
[ormask 0]
|
||||||
[andmask -1]
|
[andmask -1]
|
||||||
[X-ormasks '()])
|
[X-ormasks '()]
|
||||||
([instr (map parse2 input)])
|
#:result (sum (hash-values mem)))
|
||||||
|
([instr (sequence-map parse2 input)])
|
||||||
(match instr
|
(match instr
|
||||||
[(list 'mask ormask andmask X-ormasks)
|
[(list 'mask ormask andmask X-ormasks)
|
||||||
(values mem ormask andmask X-ormasks)]
|
(values mem ormask andmask X-ormasks)]
|
||||||
[(list 'write addr val)
|
[(list 'write addr val)
|
||||||
(let* ([addr (bitwise-ior ormask (bitwise-and andmask addr))]
|
(let* ([addr (bitwise-ior ormask (bitwise-and andmask addr))]
|
||||||
[mem (foldl #{hash-set %2 %1 val} mem (addrs addr X-ormasks))])
|
[mem (foldl #{hash-set %2 %1 val} mem (addrs addr X-ormasks))])
|
||||||
(values mem ormask andmask X-ormasks))]))])
|
(values mem ormask andmask X-ormasks))])))
|
||||||
(sum (hash-values mem))))
|
|
||||||
|
|
||||||
(show-solution part1 part2)
|
(show-solution part1 part2)
|
||||||
|
|
Loading…
Reference in New Issue