{-# Language ImportQualifiedPost, QuasiQuotes #-}
{-|
Module      : Main
Description : Day 3 solution
Copyright   : (c) Eric Mertens, 2021
License     : ISC
Maintainer  : emertens@gmail.com

<https://adventofcode.com/2015/day/3>

Follow up, down, left, right instructions to build a path.

>>> :main + ">\n"
2
2

>>> :main + "^v\n"
2
3

>>> :main + "^>v<\n"
4
3

>>> :main + "^v^v^v^v^v\n"
2
11

-}
module Main where

import Data.List (transpose)
import Data.Maybe (mapMaybe)

import Advent (chunks, counts, format, partialSums)
import Advent.Coord (Coord, origin, north, east, south, west, charToVec)

-- | >>> :main
-- 2572
-- 2631
main :: IO ()
IO ()
main =
 do String
input <- [format|2015 3 (^|v|<|>)*!%n|]
    let directions :: [Coord]
directions = (Char -> Maybe Coord) -> String -> [Coord]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Char -> Maybe Coord
charToVec String
input
    Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> [Coord] -> Int
countHouses Int
1 [Coord]
directions)
    Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> [Coord] -> Int
countHouses Int
2 [Coord]
directions)

countHouses :: Int {- ^ workers -} -> [Coord] -> Int
countHouses :: Int -> [Coord] -> Int
countHouses Int
n =
  Map Coord Int -> Int
forall a. Map Coord a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Map Coord Int -> Int)
-> ([Coord] -> Map Coord Int) -> [Coord] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Coord] -> Map Coord Int
forall (f :: * -> *) a. (Foldable f, Ord a) => f a -> Map a Int
counts ([Coord] -> Map Coord Int)
-> ([Coord] -> [Coord]) -> [Coord] -> Map Coord Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Coord] -> [Coord]) -> [[Coord]] -> [Coord]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [Coord] -> [Coord]
forall a. Num a => [a] -> [a]
partialSums ([[Coord]] -> [Coord])
-> ([Coord] -> [[Coord]]) -> [Coord] -> [Coord]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Coord]] -> [[Coord]]
forall a. [[a]] -> [[a]]
transpose ([[Coord]] -> [[Coord]])
-> ([Coord] -> [[Coord]]) -> [Coord] -> [[Coord]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Coord] -> [[Coord]]
forall a. Int -> [a] -> [[a]]
chunks Int
n