{-# 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 [[Int]]
input <- [format|2016 3 (( *%d)*%n)*|]
    Int -> IO ()
forall a. Show a => a -> IO ()
print (([Int] -> Bool) -> [[Int]] -> Int
forall (f :: * -> *) a. Foldable f => (a -> Bool) -> f a -> Int
countBy [Int] -> Bool
goodTriangle [[Int]]
input)
    Int -> IO ()
forall a. Show a => a -> IO ()
print (([Int] -> Bool) -> [[Int]] -> Int
forall (f :: * -> *) a. Foldable f => (a -> Bool) -> f a -> Int
countBy [Int] -> Bool
goodTriangle ([[Int]] -> [[Int]]
forall a. [[a]] -> [[a]]
rearrange [[Int]]
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