-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathMain.hs
91 lines (82 loc) · 2.72 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
import Data.List.Split (splitOn)
import qualified Data.Map as Map
import Debug.Trace
import System.IO
data Direction
= North
| South
| East
| West
main :: IO ()
main = do
content <- readFile "input.txt"
let s = splitOn ", " content
let res = fn1 s North 0 0
print res
let map = Map.empty
let res = fn2 map s North 0 0 0 0
print res
fn1 :: [String] -> Direction -> Int -> Int -> Int
fn1 [] _ row col = abs row + abs col
fn1 (x:xs) dir row col = do
let (to, count) = parse x
let dir2 = turn dir to
let (row2, col2) = move dir2 count row col
fn1 xs dir2 row2 col2
fn2 :: Map.Map (Int, Int) Bool -> [String] -> Direction -> Int -> Int -> Int -> Int -> Int
fn2 _ [] _ _ _ 0 0 = error "no result"
fn2 map [] dir row col remainingRow remainingCol =
let v = Map.lookup (row, col) map
in if v /= Nothing
then abs row + abs col
else do
let map2 = Map.insert (row, col) True map
let (row2, col2, deltaRow2, deltaCol2) = moveOne row col remainingRow remainingCol
fn2 map2 [] dir row2 col2 deltaRow2 deltaCol2
fn2 map (x:xs) dir row col remainingRow remainingCol =
let v = Map.lookup (row, col) map
map2 = Map.insert (row, col) True map
in if v /= Nothing
then abs row + abs col
else if remainingRow /= 0 || remainingCol /= 0
then do
let (row2, col2, deltaRow2, deltaCol2) = moveOne row col remainingRow remainingCol
fn2 map2 (x : xs) dir row2 col2 deltaRow2 deltaCol2
else do
let (to, count) = parse x
let dir2 = turn dir to
let (deltaRow, deltaCol) = delta dir2 count
let (row2, col2, deltaRow2, deltaCol2) = moveOne row col deltaRow deltaCol
fn2 map2 (xs) dir2 row2 col2 deltaRow2 deltaCol2
parse :: String -> (Char, Int)
parse s = (head s, read (drop 1 s) :: Int)
turn North turn =
case turn of
'R' -> East
'L' -> West
turn West turn =
case turn of
'R' -> North
'L' -> South
turn East turn =
case turn of
'R' -> South
'L' -> North
turn South turn =
case turn of
'R' -> West
'L' -> East
move North count row col = (row - count, col)
move South count row col = (row + count, col)
move East count row col = (row, col + count)
move West count row col = (row, col - count)
delta North count = (-count, 0)
delta South count = (count, 0)
delta East count = (0, count)
delta West count = (0, -count)
moveOne :: Int -> Int -> Int -> Int -> (Int, Int, Int, Int)
moveOne row col deltaRow deltaCol
| deltaRow > 0 = (row + 1, col, deltaRow - 1, 0)
| deltaRow < 0 = (row - 1, col, deltaRow + 1, 0)
| deltaCol > 0 = (row, col + 1, 0, deltaCol - 1)
| otherwise = (row, col - 1, 0, deltaCol + 1)