summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-12-14 22:45:22 +0100
committerTom Smeding <tom.smeding@gmail.com>2020-12-14 22:45:22 +0100
commitb524b905c29a01660663223b24a1ece82ebd48b6 (patch)
tree64c01f526c8e71d53c178b728a3807ce7e7ac5e0
parent53a4634da0f767c16f35fe2255014bd2972f0693 (diff)
Day 12 part 1
-rw-r--r--2020/12.hs78
-rw-r--r--2020/12.in796
2 files changed, 874 insertions, 0 deletions
diff --git a/2020/12.hs b/2020/12.hs
new file mode 100644
index 0000000..92ce67c
--- /dev/null
+++ b/2020/12.hs
@@ -0,0 +1,78 @@
+module Main where
+
+import Data.List (foldl')
+
+import Input
+
+
+data V2 a = V2 a a deriving (Show)
+
+data M2 a = M2 a a a a deriving (Show)
+
+class LinMappable v where
+ vfmap :: (a -> b) -> v a -> v b
+ vzip :: (a -> b -> c) -> v a -> v b -> v c
+ vzero :: Num a => v a
+instance LinMappable V2 where
+ vfmap f (V2 a b) = V2 (f a) (f b)
+ vzip f (V2 a b) (V2 a' b') = V2 (f a a') (f b b')
+ vzero = V2 0 0
+instance LinMappable M2 where
+ vfmap f (M2 a b c d) = M2 (f a) (f b) (f c) (f d)
+ vzip f (M2 a b c d) (M2 a' b' c' d') = M2 (f a a') (f b b') (f c c') (f d d')
+ vzero = M2 0 0 0 0
+
+(!+!) :: (LinMappable v, Num a) => v a -> v a -> v a
+(!+!) = vzip (+)
+
+dot :: Num a => V2 a -> V2 a -> a
+dot (V2 a b) (V2 c d) = a * c + b * d
+
+(*$) :: (LinMappable v, Num a) => v a -> a -> v a
+v *$ s = vfmap (* s) v
+
+(*!) :: Num a => M2 a -> V2 a -> V2 a
+M2 a b c d *! v = V2 (V2 a b `dot` v) (V2 c d `dot` v)
+
+-- mathematical axes: X faces east, Y faces north
+-- Shift v: pos = pos + v
+-- Sail v m1 m2: direction' = m1 *! direction; pos = pos + v + m2 *! direction'
+data Instr = Sail (V2 Int) (M2 Int) (M2 Int)
+ deriving (Show)
+
+parseInstr :: String -> Instr
+parseInstr (c : ns) = case (c, read ns :: Int) of
+ ('N', n) -> Sail (V2 0 1 *$ n) idMat vzero
+ ('S', n) -> Sail (V2 0 (-1) *$ n) idMat vzero
+ ('E', n) -> Sail (V2 1 0 *$ n) idMat vzero
+ ('W', n) -> Sail (V2 (-1) 0 *$ n) idMat vzero
+ ('F', n) -> Sail vzero idMat (M2 1 0 0 1 *$ n)
+ ('R', 90) -> Sail vzero rotRightMat vzero
+ ('R', 180) -> Sail vzero mirrorMat vzero
+ ('R', 270) -> Sail vzero rotLeftMat vzero
+ ('L', 90) -> Sail vzero rotLeftMat vzero
+ ('L', 180) -> Sail vzero mirrorMat vzero
+ ('L', 270) -> Sail vzero rotRightMat vzero
+ _ -> error "Cannot parse instr"
+ where
+ idMat = M2 1 0 0 1
+ rotRightMat = M2 0 1 (-1) 0
+ rotLeftMat = rotRightMat *$ (-1)
+ mirrorMat = idMat *$ (-1)
+parseInstr _ = error "Cannot parse empty instr"
+
+data State = State { sPos :: V2 Int, sDir :: V2 Int }
+ deriving (Show)
+
+sail :: Instr -> State -> State
+sail (Sail offset dirm posm) (State pos dir) =
+ let dir' = dirm *! dir
+ in State (pos !+! offset !+! (posm *! dir')) dir'
+
+manhattan :: Num a => V2 a -> a
+manhattan (V2 a b) = abs a + abs b
+
+main :: IO ()
+main = do
+ input <- map parseInstr <$> getInput 12
+ print (manhattan . sPos $ foldl' (flip sail) (State (V2 0 0) (V2 1 0)) input)
diff --git a/2020/12.in b/2020/12.in
new file mode 100644
index 0000000..9ec324e
--- /dev/null
+++ b/2020/12.in
@@ -0,0 +1,796 @@
+W1
+L90
+F26
+S3
+W2
+N5
+L180
+S4
+F41
+W1
+F48
+W3
+F44
+F63
+W5
+N3
+E5
+F7
+R180
+W1
+N3
+W3
+R180
+F38
+N1
+E3
+L90
+F49
+S5
+F11
+E1
+R90
+W3
+N4
+E3
+R180
+W5
+F93
+S1
+F67
+L180
+W3
+S5
+N3
+L180
+E1
+N2
+F90
+S3
+W3
+N3
+E1
+F77
+W3
+N3
+L180
+E2
+F25
+N1
+W1
+S1
+E5
+S4
+R180
+W1
+F13
+L90
+W4
+S5
+F13
+N2
+R90
+F89
+R90
+W3
+L90
+W5
+N5
+E4
+S4
+F26
+N1
+R270
+N5
+E5
+L180
+R180
+W4
+R90
+W5
+F49
+S2
+F53
+W5
+L180
+F54
+L90
+N3
+F3
+W5
+R180
+S4
+L90
+F49
+W4
+S5
+F73
+L270
+W1
+S4
+F46
+S4
+W2
+S5
+E4
+N4
+F6
+E4
+S4
+F38
+F4
+E4
+R90
+N1
+W2
+F20
+N3
+F64
+R90
+S3
+W5
+N1
+W4
+N3
+F17
+R90
+F62
+E4
+E2
+F47
+R90
+W1
+N3
+R90
+N2
+R90
+F57
+L270
+N2
+W3
+S5
+W4
+E2
+S5
+F93
+F57
+S1
+L90
+F50
+N2
+F4
+N1
+L90
+F34
+N2
+L90
+N4
+W3
+N5
+R180
+S3
+L90
+W3
+S3
+L90
+F70
+L90
+E1
+F92
+N1
+F96
+F85
+S5
+L90
+W1
+L90
+W1
+F23
+L90
+S1
+R90
+W5
+S5
+F66
+W3
+L180
+W2
+L90
+N2
+E3
+R270
+R270
+N3
+W5
+R90
+S3
+E1
+R90
+F78
+E1
+S1
+R90
+S3
+F52
+S4
+F9
+L90
+W1
+N2
+F8
+R90
+N1
+F63
+E5
+F18
+E3
+F43
+E2
+F10
+R90
+F96
+S5
+F22
+W2
+S5
+F39
+R90
+F38
+S5
+R90
+E3
+L90
+W3
+N2
+F14
+L270
+S4
+F78
+F85
+L90
+N3
+E3
+S3
+F98
+E2
+S2
+F100
+S3
+S3
+W5
+W3
+S5
+F67
+L180
+S2
+E5
+S1
+L90
+N5
+E2
+W2
+R90
+E1
+N2
+L90
+F77
+W1
+F84
+L90
+S2
+E4
+R90
+E1
+R90
+S3
+S4
+F89
+R90
+N1
+E4
+R90
+N1
+F97
+L90
+S1
+W3
+R180
+F70
+S5
+E1
+L180
+W5
+F86
+S3
+F20
+R90
+S1
+W4
+R90
+W1
+F3
+S3
+R90
+F43
+L180
+F81
+E2
+N3
+F16
+L90
+S2
+F17
+E3
+F1
+E4
+F17
+W3
+N3
+W5
+S3
+W4
+F60
+E3
+E1
+S5
+L90
+E2
+S5
+F19
+E2
+R90
+F20
+R180
+S4
+F9
+R90
+N5
+W5
+F56
+N2
+L180
+N1
+E5
+L90
+F15
+W4
+F26
+R90
+W2
+F19
+S3
+W1
+R90
+W5
+R180
+W4
+N2
+F86
+N5
+E3
+W3
+N3
+L270
+W3
+F42
+N5
+W2
+R180
+W2
+R180
+S4
+R90
+F55
+S3
+R90
+S3
+E3
+R90
+F11
+S4
+F38
+W1
+L90
+F8
+R90
+E5
+R90
+W1
+W5
+S2
+F2
+F92
+S3
+F77
+S5
+R90
+F24
+E3
+R90
+N3
+F16
+L270
+W3
+F83
+L270
+E2
+F98
+L180
+F89
+E5
+F98
+S4
+E2
+L90
+N4
+L180
+F57
+S5
+R90
+L90
+S4
+W4
+S5
+S4
+W4
+F43
+N2
+F29
+W3
+R90
+F41
+R90
+N2
+F78
+R90
+E5
+N1
+W2
+F6
+L270
+W5
+F91
+W5
+N1
+S4
+F41
+W4
+F74
+E1
+R90
+N4
+F76
+W4
+S2
+L180
+N2
+R180
+W4
+F79
+R270
+W1
+F92
+W1
+L90
+F71
+N4
+L180
+W4
+F16
+W5
+F84
+S5
+F35
+W4
+R90
+F25
+L180
+N1
+E3
+F15
+S4
+R180
+F46
+S1
+W1
+R180
+E4
+N5
+R90
+S1
+W3
+S3
+L270
+F94
+R180
+N1
+W4
+N5
+W2
+S2
+W3
+F53
+L180
+S3
+F19
+N3
+F54
+L180
+S5
+F8
+S1
+N5
+L90
+E4
+N3
+F28
+R180
+F23
+E1
+L90
+E3
+F6
+W4
+R90
+N1
+F89
+S1
+W2
+S5
+F8
+N3
+F23
+N4
+F5
+L90
+N3
+R90
+W4
+L180
+S3
+F7
+N2
+W3
+R180
+E1
+L180
+S4
+R90
+S1
+F99
+N3
+F96
+W3
+R90
+F73
+W5
+F71
+R180
+S2
+F84
+N4
+F4
+W4
+R90
+F34
+E2
+W2
+F53
+N4
+R90
+N5
+E5
+R90
+F60
+N4
+F28
+S2
+W1
+N4
+F54
+R270
+F45
+S5
+F93
+L90
+F66
+R180
+F92
+N4
+F97
+R90
+W5
+S1
+W5
+F68
+S3
+L90
+E3
+F94
+S4
+F64
+R180
+F18
+N1
+S4
+E5
+E2
+F81
+N1
+L90
+F3
+R90
+F81
+W4
+S4
+E5
+N5
+R270
+E3
+S2
+W1
+L180
+S1
+F84
+W2
+L270
+F6
+N1
+R180
+E5
+F7
+E2
+L180
+E2
+F80
+N1
+L90
+F88
+R90
+W5
+N1
+F71
+R180
+N2
+E2
+R90
+N1
+W1
+L90
+E4
+S4
+L180
+F27
+L90
+F57
+F38
+W5
+L180
+S5
+R90
+S4
+W1
+S3
+L90
+F36
+S1
+W5
+R90
+F65
+R90
+E1
+N4
+E1
+F14
+L90
+F44
+R90
+F34
+S2
+L90
+R180
+F87
+W3
+L90
+F9
+R90
+W3
+L90
+S5
+F69
+S3
+W4
+N4
+F30
+W5
+F15
+R90
+L180
+W4
+F5
+R180
+E1
+F6
+R180
+S1
+F20
+E1
+S2
+E5
+F13
+N5
+F83
+W2
+L270
+E2
+R90
+S5
+F62
+R270
+N4
+R90
+F20
+L90
+N2
+E3
+L90
+F37
+N2
+N2
+F82
+L90
+F23
+E3
+F63
+R180
+F1
+N2
+R90
+F68
+E5
+F75
+R90
+W3
+R180
+E4
+E1
+N3
+R90
+N3
+L180
+F92
+R90
+S4
+F27
+R180
+S4
+L180
+W5
+F70
+S5
+L180
+F89
+R90
+W2
+N3
+F64
+L90
+E1
+L90
+F77
+E4
+F55
+E2
+L90
+W2
+F46
+N2
+R90
+F94
+S5
+R180
+F9
+L180
+S4
+L90
+F25