import Data.List
import Data.List.Split
import Data.Maybe
import qualified Data.Text as T

main :: IO ()
main = do
  let toDigit = T.unpack . T.replace (T.pack "10") (T.pack ":") . T.pack
  input <- map (map toDigit . lines) . splitOn "\n\n" <$> readFile "input"
  print $ sum $ zipWith (*) [1 ..] $ map (fromEnum . isOrdered 0) input
  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

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

mySort :: String -> String -> Ordering
mySort x y =
  if isOrdered 0 (addBrackets ["", ""] [x, y])
    then LT
    else GT
