Refactored Day 12 and added solution using matrices.
This commit is contained in:
parent
62c1709042
commit
0a60d7e899
|
@ -0,0 +1,53 @@
|
|||
#lang racket
|
||||
|
||||
(require math/matrix
|
||||
"../lib.rkt")
|
||||
|
||||
(define (parse line)
|
||||
(match line
|
||||
[(regexp #px"([NESWLRF])(\\d+)" (list _ dir amt))
|
||||
(list (string->symbol dir) (string->number amt))]))
|
||||
|
||||
(define input (map parse (problem-input 12)))
|
||||
|
||||
(define N (col-matrix [0 -1]))
|
||||
(define E (col-matrix [1 0]))
|
||||
(define S (col-matrix [0 1]))
|
||||
(define W (col-matrix [-1 0]))
|
||||
(define R90 (matrix [[0 -1] [1 0]]))
|
||||
(define L90 (matrix [[0 1] [-1 0]]))
|
||||
|
||||
(define (move instr p1 p2 pos dir)
|
||||
(match instr
|
||||
[`(N ,amt) (values (matrix+ pos (matrix-scale N (* amt p1)))
|
||||
(matrix+ dir (matrix-scale N (* amt p2))))]
|
||||
[`(E ,amt) (values (matrix+ pos (matrix-scale E (* amt p1)))
|
||||
(matrix+ dir (matrix-scale E (* amt p2))))]
|
||||
[`(S ,amt) (values (matrix+ pos (matrix-scale S (* amt p1)))
|
||||
(matrix+ dir (matrix-scale S (* amt p2))))]
|
||||
[`(W ,amt) (values (matrix+ pos (matrix-scale W (* amt p1)))
|
||||
(matrix+ dir (matrix-scale W (* amt p2))))]
|
||||
[`(F ,amt) (values (matrix+ pos (matrix-scale dir amt)) dir)]
|
||||
[(or `(R 90) `(L 270)) (values pos (matrix* R90 dir))]
|
||||
[(or `(L 90) `(R 270)) (values pos (matrix* L90 dir))]
|
||||
[`(,_ 180) (values pos (matrix-scale dir -1))]))
|
||||
|
||||
(define part1
|
||||
(match-let-values
|
||||
([(pos dir)
|
||||
(for/fold ([pos (col-matrix [0 0])]
|
||||
[dir E])
|
||||
([instr input])
|
||||
(move instr 1 0 pos dir))])
|
||||
(matrix-1norm pos)))
|
||||
|
||||
(define part2
|
||||
(match-let-values
|
||||
([(ship wpt)
|
||||
(for/fold ([ship (col-matrix [0 0])]
|
||||
[wpt (col-matrix [10 -1])])
|
||||
([instr input])
|
||||
(move instr 0 1 ship wpt))])
|
||||
(matrix-1norm ship)))
|
||||
|
||||
(show-solution part1 part2)
|
78
src/12.rkt
78
src/12.rkt
|
@ -1,7 +1,6 @@
|
|||
#lang curly-fn racket
|
||||
#lang racket
|
||||
|
||||
(require threading
|
||||
"../lib.rkt")
|
||||
(require "../lib.rkt")
|
||||
|
||||
(define (parse line)
|
||||
(match line
|
||||
|
@ -10,58 +9,33 @@
|
|||
|
||||
(define input (map parse (problem-input 12)))
|
||||
|
||||
(define (turn curr-dir dir angle)
|
||||
(define dirs
|
||||
(if (symbol=? dir 'R)
|
||||
'(N E S W)
|
||||
'(N W S E)))
|
||||
(define index (index-of dirs curr-dir))
|
||||
(list-ref dirs (modulo (+ index (/ angle 90)) 4)))
|
||||
|
||||
(define (rotate x y dir amt)
|
||||
(cond
|
||||
[(= amt 180) (list (- x) (- y))]
|
||||
[(= amt 270) (rotate x y (if (symbol=? dir 'R) 'L 'R) 90)]
|
||||
[(symbol=? dir 'R) (list (- y) x)]
|
||||
[(symbol=? dir 'L) (list y (- x))]))
|
||||
|
||||
(define (move instr x y dir)
|
||||
(define (move instr p1 p2 x y dx dy)
|
||||
(match instr
|
||||
[`(N ,amt) (values x (- y amt) dir)]
|
||||
[`(E ,amt) (values (+ x amt) y dir)]
|
||||
[`(S ,amt) (values x (+ y amt) dir)]
|
||||
[`(W ,amt) (values (- x amt) y dir)]
|
||||
[`(F ,amt) (move `(,dir ,amt) x y dir)]
|
||||
[`(,lr ,amt) (values x y (turn dir lr amt))]))
|
||||
[`(N ,amt) (values x (- y (* amt p1)) dx (- dy (* amt p2)))]
|
||||
[`(E ,amt) (values (+ x (* amt p1)) y (+ dx (* amt p2)) dy)]
|
||||
[`(S ,amt) (values x (+ y (* amt p1)) dx (+ dy (* amt p2)))]
|
||||
[`(W ,amt) (values (- x (* amt p1)) y (- dx (* amt p2)) dy)]
|
||||
[`(F ,amt) (values (+ x (* dx amt)) (+ y (* dy amt)) dx dy)]
|
||||
[(or '(R 90) '(L 270)) (values x y (- dy) dx)]
|
||||
[(or '(L 90) '(R 270)) (values x y dy (- dx))]
|
||||
[`(,_ 180) (values x y (- dx) (- dy))]))
|
||||
|
||||
(define (move* instr x-ship y-ship x-wpt y-wpt)
|
||||
(match instr
|
||||
[`(N ,amt) (values x-ship y-ship x-wpt (- y-wpt amt))]
|
||||
[`(E ,amt) (values x-ship y-ship (+ x-wpt amt) y-wpt)]
|
||||
[`(S ,amt) (values x-ship y-ship x-wpt (+ y-wpt amt))]
|
||||
[`(W ,amt) (values x-ship y-ship (- x-wpt amt) y-wpt)]
|
||||
[`(F ,amt) (values (+ x-ship (* x-wpt amt)) (+ y-ship (* y-wpt amt)) x-wpt y-wpt)]
|
||||
[`(,lr ,amt)
|
||||
(match-let ([(list x-wpt y-wpt) (rotate x-wpt y-wpt lr amt)])
|
||||
(values x-ship y-ship x-wpt y-wpt))]))
|
||||
|
||||
(define (part1)
|
||||
(define-values (x y dir)
|
||||
(for/fold ([x 0]
|
||||
[y 0]
|
||||
[dir 'E])
|
||||
(define part1
|
||||
(match-let-values
|
||||
([(x y dx dy)
|
||||
(for/fold ([x 0] [y 0]
|
||||
[dx 1] [dy 0])
|
||||
([instr input])
|
||||
(move instr x y dir)))
|
||||
(+ (abs x) (abs y)))
|
||||
(move instr 1 0 x y dx dy))])
|
||||
(+ (abs x) (abs y))))
|
||||
|
||||
(define (part2)
|
||||
(define-values (x-ship y-ship x-wpt y-wpt)
|
||||
(for/fold ([x-ship 0]
|
||||
[y-ship 0]
|
||||
[x-wpt 10]
|
||||
[y-wpt -1])
|
||||
(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 x-ship y-ship x-wpt y-wpt)))
|
||||
(+ (abs x-ship) (abs y-ship)))
|
||||
(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)
|
||||
|
|
Loading…
Reference in New Issue