-
Notifications
You must be signed in to change notification settings - Fork 3
/
Main.hs
107 lines (98 loc) · 3.35 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import Data.List (isPrefixOf)
import qualified Data.Map as Map
import Debug.Trace
import Lib.Directions
import Lib.Inputs
import Lib.Lists
import Lib.Strings
import System.IO
main :: IO ()
main = do
handle <- openFile "input.txt" ReadMode
contents <- hGetContents handle
let linesList = lines contents
let res = fn1 linesList
print res
let res = fn2 linesList
print res
data Line = Line
{ from :: Position
, to :: Position
, direction :: Direction
} deriving (Eq, Show)
fn1 :: [String] -> Int
fn1 s = length $ filter (\(_, v) -> v >= 2) (Map.toList grid)
where
lines = map toLine s
grid = toGrid lines Map.empty
toGrid :: [Line] -> Map.Map Position Int -> Map.Map Position Int
toGrid [] grid = grid
toGrid (line:xs) grid =
case d of
Just (deltaRow, deltaCol) ->
let grid2 = Map.insertWith (+) (from line) 1 grid
in toGrid xs $ updateGrid (deltaRow, deltaCol) grid2 (from line) (to line)
Nothing -> toGrid xs grid
where
d = deltaDir (direction line)
updateGrid :: (Int, Int) -> Map.Map Position Int -> Position -> Position -> Map.Map Position Int
updateGrid (deltaRow, deltaCol) grid cur to
| cur == to = grid
| otherwise = updateGrid (deltaRow, deltaCol) (Map.insertWith (+) cur 1 grid) (delta cur deltaRow deltaCol) to
deltaDir :: Direction -> Maybe (Int, Int)
deltaDir DirUp = Just (-1, 0)
deltaDir DirDown = Just (1, 0)
deltaDir DirLeft = Just (0, -1)
deltaDir DirRight = Just (0, 1)
deltaDir _ = Nothing
toLine :: String -> Line
toLine s = Line {from = from, to = to, direction = direction}
where
del = newDelimiter s " "
f = getString del 0
delF = newDelimiter f ","
from = newPosition (getInt delF 1) (getInt delF 0)
t = getString del 2
delT = newDelimiter t ","
to = newPosition (getInt delT 1) (getInt delT 0)
direction
| row from == row to =
if col from < col to
then DirRight
else DirLeft
| col from == col to =
if row from < row to
then DirDown
else DirUp
| col from < col to && row from < row to = DirDownRight
| col from < col to && row from > row to = DirUpRight
| col from > col to && row from < row to = DirDownLeft
| col from > col to && row from > row to = DirUpLeft
fn2 :: [String] -> Int
fn2 s = length $ filter (\(_, v) -> v >= 2) (Map.toList grid)
where
lines = map toLine s
grid = toGrid2 lines Map.empty
toGrid2 :: [Line] -> Map.Map Position Int -> Map.Map Position Int
toGrid2 [] grid = grid
toGrid2 (line:xs) grid =
case d of
Just (deltaRow, deltaCol) ->
let grid2 = Map.insertWith (+) (from line) 1 grid
in toGrid2 xs $ updateGrid (deltaRow, deltaCol) grid2 (from line) (to line)
Nothing -> toGrid xs grid
where
d = deltaDir2 (direction line)
updateGrid :: (Int, Int) -> Map.Map Position Int -> Position -> Position -> Map.Map Position Int
updateGrid (deltaRow, deltaCol) grid cur to
| cur == to = grid
| otherwise = updateGrid (deltaRow, deltaCol) (Map.insertWith (+) cur 1 grid) (delta cur deltaRow deltaCol) to
deltaDir2 :: Direction -> Maybe (Int, Int)
deltaDir2 DirUp = Just (-1, 0)
deltaDir2 DirDown = Just (1, 0)
deltaDir2 DirLeft = Just (0, -1)
deltaDir2 DirRight = Just (0, 1)
deltaDir2 DirUpLeft = Just (-1, -1)
deltaDir2 DirUpRight = Just (-1, 1)
deltaDir2 DirDownLeft = Just (1, -1)
deltaDir2 DirDownRight = Just (1, 1)