{-|
Module      : Advent.Coord
Description : Day 19 solution
Copyright   : (c) Eric Mertens, 2017
License     : ISC
Maintainer  : emertens@gmail.com

<https://adventofcode.com/2017/day/19>

Day 19 has us follow an ASCII art trail and report on the letters
we find along the way as well as the total trail path length.

-}
module Main where

import Advent.Input (getInputArray)
import Advent.Coord (Coord(..), north, east, south, west)
import Data.Char (isAlpha)
import Data.Array.Unboxed (UArray, (!), assocs)

-- | Print the solutions to both parts of day 19. Input file can be
-- overridden via the command-line arguments.
main :: IO ()
IO ()
main =
 do input <- Int -> Int -> IO (UArray Coord Char)
getInputArray Int
2017 Int
19

    let start:_ = [c | (c@(C 0 _), '|') <- assocs input]
        path = UArray Coord Char -> Coord -> Coord -> String
toPath UArray Coord Char
input Coord
south Coord
start

    putStrLn (filter isAlpha path)
    print (length path)

-- | Return the path given a map, current travel direction,
-- and current location.
toPath ::
  UArray Coord Char {- ^ map       -} ->
  Coord             {- ^ direction -} ->
  Coord             {- ^ location  -} ->
  String            {- ^ path      -}
toPath :: UArray Coord Char -> Coord -> Coord -> String
toPath UArray Coord Char
grid Coord
d Coord
c =
  let isPath :: Coord -> Bool
isPath Coord
d' = UArray Coord Char
grid UArray Coord Char -> Coord -> Char
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! (Coord
c Coord -> Coord -> Coord
forall a. Num a => a -> a -> a
+ Coord
d') Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
' '
      next :: Coord -> String
next Coord
d'   = UArray Coord Char -> Coord -> Coord -> String
toPath UArray Coord Char
grid Coord
d' (Coord
c Coord -> Coord -> Coord
forall a. Num a => a -> a -> a
+ Coord
d') in
  case UArray Coord Char
grid UArray Coord Char -> Coord -> Char
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Coord
c of
    Char
' '                            -> []
    Char
'+' | Coord
d Coord -> Coord -> Bool
forall a. Eq a => a -> a -> Bool
/= Coord
south, Coord -> Bool
isPath Coord
north -> Char
'+' Char -> String -> String
forall a. a -> [a] -> [a]
: Coord -> String
next Coord
north
        | Coord
d Coord -> Coord -> Bool
forall a. Eq a => a -> a -> Bool
/= Coord
north, Coord -> Bool
isPath Coord
south -> Char
'+' Char -> String -> String
forall a. a -> [a] -> [a]
: Coord -> String
next Coord
south
        | Coord
d Coord -> Coord -> Bool
forall a. Eq a => a -> a -> Bool
/= Coord
west,  Coord -> Bool
isPath Coord
east  -> Char
'+' Char -> String -> String
forall a. a -> [a] -> [a]
: Coord -> String
next Coord
east
        | Coord
d Coord -> Coord -> Bool
forall a. Eq a => a -> a -> Bool
/= Coord
east,  Coord -> Bool
isPath Coord
west  -> Char
'+' Char -> String -> String
forall a. a -> [a] -> [a]
: Coord -> String
next Coord
west
    Char
a                              -> Char
a   Char -> String -> String
forall a. a -> [a] -> [a]
: Coord -> String
next Coord
d