{-# 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 UArray Coord Char
inp <- Int -> Int -> IO (UArray Coord Char)
getInputArray Int
2020 Int
3
     Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> Int -> UArray Coord Char -> Int
solve Int
3 Int
1 UArray Coord Char
inp
     Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> Int -> UArray Coord Char -> Int
solve Int
1 Int
1 UArray Coord Char
inp
           Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int -> Int -> UArray Coord Char -> Int
solve Int
3 Int
1 UArray Coord Char
inp
           Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int -> Int -> UArray Coord Char -> Int
solve Int
5 Int
1 UArray Coord Char
inp
           Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int -> Int -> UArray Coord Char -> Int
solve Int
7 Int
1 UArray Coord Char
inp
           Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int -> Int -> UArray Coord Char -> Int
solve Int
1 Int
2 UArray Coord Char
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