module Day5

import Prelude
import Node
import Aoc

Range : U
Range = Int × Int

record Problem where
  constructor MkP
  pairs : List Range
  avail : List Int


parse : String → Either String Problem
parse text = do

  let (a :: b :: Nil) = split (trim text) "\n\n"
    | cs => Left "got \{show $ length cs} chunks"
  pairs <- traverse parsePair $ split a "\n"
  let avail = map stringToInt $ split b "\n"
  Right $ MkP pairs avail
  where
    parsePair : String → Either String Range
    parsePair s = do
      let (a :: b :: Nil) = map stringToInt $ split s "-"
        | _ => Left "not a  pair '\{show s}'"
      Right (a,b)

part1 : Problem → Int
part1 prob = length' $ filter (isFresh prob.pairs) prob.avail
  where
    isFresh : List Range → Int → Bool
    isFresh ((a,b) :: pairs) v = if a <= v && v <= b then True else isFresh pairs v
    isFresh Nil v = False

part2 : List Range → Int
part2 pairs = foldl _+_ 0 $ map size $ merge $ qsort (\a b => a < b) pairs
    where
      size : Range → Int
      size (a,b) = b - a + 1

      merge : List Range → List Range
      merge ((s,e) :: (s', e') :: xs) =
        if e < s' then (s,e) :: merge ((s', e') :: xs)
          else merge ((s, max e e') :: xs)
      merge xs = xs

run : String -> IO Unit
run fn = do
  putStrLn fn
  text <- readFile fn
  let (Right prob) = parse text | Left msg => putStrLn msg
  putStrLn $ "part1 " ++ show (part1 prob)
  putStrLn $ "part2 " ++ show (part2 prob.pairs)

main : IO Unit
main = do
  run "aoc2025/day5/eg.txt"
  run "aoc2025/day5/input.txt"
