2022-12-14 00:21:42 +01:00
import Data.List
import Data.List.Split
import Data.Maybe
import qualified Data.Text as T
main :: IO ()
main = do
2022-12-14 01:47:09 +01:00
let toDigit = T . unpack . T . replace ( T . pack " 10 " ) ( T . pack " : " ) . T . pack
input <- map ( map toDigit . lines ) . splitOn " \ n \ n " <$> readFile " input "
2022-12-14 00:21:42 +01:00
print $
2022-12-14 01:47:09 +01:00
sum $ zipWith ( * ) [ 1 .. ] $ map ( fromEnum . isOrdered 0 ) input
2022-12-14 00:21:42 +01:00
let divider = [ " [[6]] " , " [[2]] " ]
let sorted = sortBy mySort ( divider ++ concat input )
print $ product $ map ( + 1 ) $ mapMaybe ( ` elemIndex ` sorted ) divider
isOrdered :: Int -> [ String ] -> Bool
isOrdered n [ l : ls , r : rs ]
| n < 0 && l == ',' = False
| n > 0 && r == ',' = True
| l == r = isOrdered n [ ls , rs ]
| l == ']' = ( r /= ',' ) || isOrdered ( succ n ) [ ls , r : rs ]
| r == ']' = l == ',' && isOrdered ( pred n ) [ l : ls , rs ]
| l == '[' = r /= ']' && isOrdered ( pred n ) [ ls , r : rs ]
| r == '[' = l == ']' || isOrdered ( succ n ) [ l : ls , rs ]
| l > r = False
| l < r = True
| otherwise = False
isOrdered _ [ [] , _ ] = True
isOrdered _ [ _ , [] ] = False
isOrdered _ _ = True
2022-12-14 01:47:09 +01:00
addBrackets :: [ String ] -> [ String ] -> [ String ]
addBrackets [ accl , accr ] [ l : ls , r : rs ]
| l == r = addBrackets [ l : accl , r : accr ] [ ls , rs ]
| l ` elem ` [ '0' .. ':' ] && r ` elem ` [ '0' .. ':' ] = addBrackets [ l : accl , r : accr ] [ ls , rs ]
| l == '[' = addBrackets [ l : accl , l : accr ] [ ls , r : rs ]
| r == '[' = addBrackets [ r : accl , r : accr ] [ l : ls , rs ]
| l == ']' = addBrackets [ accl , r : accr ] [ l : ls , rs ]
| r == ']' = addBrackets [ l : accl , accr ] [ ls , r : rs ]
addBrackets [ accl , accr ] [ " " , rs ] = map reverse [ accl , reverse rs ++ accr ]
addBrackets [ accl , accr ] [ ls , " " ] = map reverse [ reverse ls ++ accl , accr ]
addBrackets _ acc = map reverse acc
2022-12-14 00:21:42 +01:00
mySort :: String -> String -> Ordering
mySort x y =
2022-12-14 01:47:09 +01:00
if isOrdered 0 ( addBrackets [ " " , " " ] [ x , y ] )
2022-12-14 00:21:42 +01:00
then LT
else GT