{-# Language QuasiQuotes #-}
module Main where
import Advent (format)
import Data.List (sort)
data Package = Package Int Int Int
data Face = Face Int Int
main :: IO ()
IO ()
main =
do [(Int, Int, Int)]
input <- [format|2015 2 (%ux%ux%u%n)*|]
let packages :: [Package]
packages = [Int -> Int -> Int -> Package
Package Int
x Int
y Int
z | (Int
x,Int
y,Int
z) <- [(Int, Int, Int)]
input]
Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (Package -> Int
part1 (Package -> Int) -> [Package] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Package]
packages))
Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (Package -> Int
part2 (Package -> Int) -> [Package] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Package]
packages))
part1 :: Package -> Int
part1 :: Package -> Int
part1 Package
p = Package -> Int
surfaceArea Package
p Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Face -> Int
area (Package -> Face
smallestFace Package
p)
part2 :: Package -> Int
part2 :: Package -> Int
part2 Package
p = Package -> Int
volume Package
p Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Face -> Int
perimeter (Package -> Face
smallestFace Package
p)
volume :: Package -> Int
volume :: Package -> Int
volume (Package Int
x Int
y Int
z) = Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
z
surfaceArea :: Package -> Int
surfaceArea :: Package -> Int
surfaceArea (Package Int
x Int
y Int
z) = Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
z Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
z)
smallestFace :: Package -> Face
smallestFace :: Package -> Face
smallestFace (Package Int
x Int
y Int
z) = let Int
a:Int
b:[Int]
_ = [Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort [Int
x,Int
y,Int
z] in Int -> Int -> Face
Face Int
a Int
b
area :: Face -> Int
area :: Face -> Int
area (Face Int
x Int
y) = Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
y
perimeter :: Face -> Int
perimeter :: Face -> Int
perimeter (Face Int
x Int
y) = Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
*(Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
y)