{-|
Module      : Main
Description : Day 10 solution
Copyright   : (c) Eric Mertens, 2015
License     : ISC
Maintainer  : emertens@gmail.com

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

-}
module Main where

import Advent.Input (getInputLines)
import Data.List (group)

-- |
-- >>> :main
-- 252594
-- 3579328
main :: IO ()
IO ()
main =
  do [String
start] <- Int -> Int -> IO [String]
getInputLines Int
2015 Int
10
     let steps :: [String]
steps = (String -> String) -> String -> [String]
forall a. (a -> a) -> a -> [a]
iterate String -> String
lookAndSay String
start
     Int -> IO ()
forall a. Show a => a -> IO ()
print (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([String]
steps [String] -> Int -> String
forall a. HasCallStack => [a] -> Int -> a
!! Int
40))
     Int -> IO ()
forall a. Show a => a -> IO ()
print (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([String]
steps [String] -> Int -> String
forall a. HasCallStack => [a] -> Int -> a
!! Int
50))

-- | Look and say process.
--
-- >>> lookAndSay "1"
-- "11"
--
-- >>> lookAndSay "11"
-- "21"
--
-- >>> lookAndSay "21"
-- "1211"
--
-- >>> lookAndSay "1211"
-- "111221"
--
-- >>> lookAndSay "111221"
-- "312211"
lookAndSay :: String -> String
lookAndSay :: String -> String
lookAndSay = (String -> String -> String) -> String -> [String] -> String
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr String -> String -> String
aux [] ([String] -> String) -> (String -> [String]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
forall a. Eq a => [a] -> [[a]]
group
  where
  aux :: String -> String -> String
aux String
xs = Int -> String -> String
forall a. Show a => a -> String -> String
shows (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
xs)
         (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> String -> String
showChar (String -> Char
forall a. HasCallStack => [a] -> a
head String
xs)