From 637477664a19c5a212235b44a83a20fd643854a6 Mon Sep 17 00:00:00 2001 From: Jonathan Chan Date: Sat, 12 Dec 2020 00:52:32 -0800 Subject: [PATCH] Refactored Day 12 and added solution using matrices. --- src/12-alt.rkt | 53 ++++++++++++++++++++++++++++++++ src/12.rkt | 82 +++++++++++++++++--------------------------------- 2 files changed, 81 insertions(+), 54 deletions(-) create mode 100644 src/12-alt.rkt diff --git a/src/12-alt.rkt b/src/12-alt.rkt new file mode 100644 index 0000000..7a346e8 --- /dev/null +++ b/src/12-alt.rkt @@ -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) diff --git a/src/12.rkt b/src/12.rkt index 3a45ffe..0f1825b 100644 --- a/src/12.rkt +++ b/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 + (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)))) -(define (part1) - (define-values (x y dir) - (for/fold ([x 0] - [y 0] - [dir 'E]) - ([instr input]) - (move instr x y dir))) - (+ (abs x) (abs y))) +(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)))) -(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]) - ([instr input]) - (move* instr x-ship y-ship x-wpt y-wpt))) - (+ (abs x-ship) (abs y-ship))) - -(show-solution (part1) (part2)) +(show-solution part1 part2)