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

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

-}
module Main (main) where

import Advent.Format (format)
import Data.List (find)
import Intcode (intcodeToList)

-- | >>> :main
-- 211
-- 8071006
main :: IO ()
IO ()
main =
  do [Int]
inp <- [format|2019 19 %d&,%n|]
     let f :: Int -> Int -> Bool
f Int
x Int
y = Int
1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Int] -> Int
forall a. HasCallStack => [a] -> a
head ([Int] -> [Int] -> [Int]
intcodeToList [Int]
inp [Int
x,Int
y])
     Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ [()] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ () | Int
x <- [Int
0..Int
49], Int
y <- [Int
0..Int
49], Int -> Int -> Bool
f Int
x Int
y]
     Int -> IO ()
forall a. Show a => a -> IO ()
print (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> Bool) -> Int -> Int -> Int
part2 Int -> Int -> Bool
f Int
0 Int
100

part2 :: (Int -> Int -> Bool) -> Int -> Int -> Int
part2 :: (Int -> Int -> Bool) -> Int -> Int -> Int
part2 Int -> Int -> Bool
f Int
x0 Int
y
  | Int -> Int -> Bool
f (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
99) (Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
99) = Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10000 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
99
  | Bool
otherwise       = (Int -> Int -> Bool) -> Int -> Int -> Int
part2 Int -> Int -> Bool
f Int
x (Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
  where
    Just Int
x = (Int -> Bool) -> [Int] -> Maybe Int
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (Int -> Int -> Bool
`f` Int
y) [Int
x0..]