summaryrefslogtreecommitdiff
path: root/day06/day06.hs
blob: fa022f71d8d60cd8cf0b81f02e3265c53a094eca (plain)
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
import Data.List
import Data.Maybe

data Cell = Clr | Obs deriving (Show, Eq)
type Grid = [[Cell]]
type Coo = (Int, Int)
data Dir = U | R | D | L deriving (Show, Eq)
type Guard = (Coo, Dir)

(!?) :: Grid -> Coo -> Maybe Cell
grid !? (row, col)
  | row < 0                     = Nothing
  | row >= length grid          = Nothing
  | col < 0                     = Nothing
  | col >= (length $ head grid) = Nothing
  | otherwise                   = Just (grid !! row !! col)

findGuard :: Int -> [[Char]] -> Guard
findGuard r (h:t)
  | c == Nothing = findGuard (r + 1) t
  | otherwise    = ((r, (fromJust c)), U)
  where c = elemIndex '^' h

consume :: [Char] -> (Grid, Guard)
consume file =
  let toCell = \ln -> case ln of
                        '#' -> Obs
                        otherwise -> Clr
      grid = map (map toCell) (lines file)
      guard = findGuard 0 (lines file) in
        (grid, guard)

step :: Grid -> Guard -> Maybe Guard
step grid (coo@(r,c), U)
  | cell == Nothing = Nothing
  | cell == Just Obs = Just (coo, R)
  | cell == Just Clr = Just (ncoo, U)
  where
    ncoo = (r - 1, c)
    cell = grid !? ncoo
step grid (coo@(r,c), R)
  | cell == Nothing = Nothing
  | cell == Just Obs = Just (coo, D)
  | cell == Just Clr = Just (ncoo, R)
  where
    ncoo = (r, c + 1)
    cell = grid !? ncoo
step grid (coo@(r,c), D)
  | cell == Nothing = Nothing
  | cell == Just Obs = Just (coo, L)
  | cell == Just Clr = Just (ncoo, D)
  where
    ncoo = (r + 1, c)
    cell = grid !? ncoo
step grid (coo@(r,c), L)
  | cell == Nothing = Nothing
  | cell == Just Obs = Just (coo, U)
  | cell == Just Clr = Just (ncoo, L)
  where
    ncoo = (r, c - 1)
    cell = grid !? ncoo

(?:) :: Eq a => a -> [a] -> [a]
el ?: arr
  | el `elem` arr = arr
  | otherwise = el:arr

route :: Grid -> [Coo] -> Guard -> [Coo]
route grid seen guard@(coo, dir)
  | nguard == Nothing     = coo ?: seen
  | otherwise = route grid (coo ?: seen) (fromJust nguard)
  where
    nguard = step grid guard

part1 :: Grid -> Guard -> Int
part1 grid guard = length $ route grid [] guard

main = do
  file <- readFile "day06.input"
  let (grid, guard) = consume file
  putStrLn ("Part 1: " ++ (show $ part1 grid guard))
  --putStrLn ("Part 2: " ++ (show $ part2 lns))