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

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

Sledding down a slope counting trees.

-}
module Main where

import Advent (countBy, getInputArray)
import Advent.Coord (Coord(C))
import Data.Array.Unboxed qualified as A

-- |
-- >>> :main
-- 240
-- 2832009600
main :: IO ()
IO ()
main =
  do inp <- Int -> Int -> IO (UArray Coord Char)
getInputArray Int
2020 Int
3
     print $ solve 3 1 inp
     print $ solve 1 1 inp
           * solve 3 1 inp
           * solve 5 1 inp
           * solve 7 1 inp
           * solve 1 2 inp

solve :: Int -> Int -> A.UArray Coord Char -> Int
solve :: Int -> Int -> UArray Coord Char -> Int
solve Int
dx Int
dy UArray Coord Char
grid
  = (Coord -> Bool) -> [Coord] -> Int
forall (f :: * -> *) a. Foldable f => (a -> Bool) -> f a -> Int
countBy (\Coord
c -> Char
'#' Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== UArray Coord Char
grid UArray Coord Char -> Coord -> Char
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
A.! Coord
c)
    [ Int -> Int -> Coord
C Int
y (Int
xlo Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
xoff Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Int
width)
    | Int
xoff <- [Int
0, Int
dx ..]
    | Int
y    <- [Int
ylo, Int
yloInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
dy .. Int
yhi]]
  where
    width :: Int
width = Int
xhi Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
xlo Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
    (C Int
ylo Int
xlo, C Int
yhi Int
xhi) = UArray Coord Char -> (Coord, Coord)
forall i. Ix i => UArray i Char -> (i, i)
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> (i, i)
A.bounds UArray Coord Char
grid