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

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

Determine triples that are valid triangle side lengths.

-}
module Main where

import Advent (format, chunks, countBy)
import Data.List (sort, transpose)

-- | >>> :main
-- 1050
-- 1921
main :: IO ()
IO ()
main =
 do input <- [format|2016 3 (( *%d)*%n)*|]
    print (countBy goodTriangle input)
    print (countBy goodTriangle (rearrange input))

rearrange :: [[a]] -> [[a]]
rearrange :: forall a. [[a]] -> [[a]]
rearrange = Int -> [a] -> [[a]]
forall a. Int -> [a] -> [[a]]
chunks Int
3 ([a] -> [[a]]) -> ([[a]] -> [a]) -> [[a]] -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[a]] -> [a]) -> ([[a]] -> [[a]]) -> [[a]] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[a]] -> [[a]]
forall a. [[a]] -> [[a]]
transpose

goodTriangle :: [Int] -> Bool
goodTriangle :: [Int] -> Bool
goodTriangle [Int]
xs = Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
z
  where
    [Int
x,Int
y,Int
z] = [Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort [Int]
xs