module Day12

import Prelude
import Node
import Aoc
import Parser
import Data.List1

data Row = MkR Int Int (List Int)
data Gift = MkG Int


record Problem where
  gifts : List Int
  rows : List Row



parse : String → Either String Problem
parse txt = do
  let chunks = split (trim txt) "\n\n"
  let (c :: cs) = chunks | _ => Left "no chunks"
  let (gifts, prob) = unsnoc (c ::: cs)
  let lines = split prob "\n"
  rows <- traverse parseRow lines
  Right $ MkProblem (map weight gifts) rows
  where
    weight : String → Int
    weight line = length' $ filter (_==_ '#') $ unpack line

    parseRow : String → Either String Row
    parseRow line = do
      let (a :: b :: Nil) = split line ": " | _ => Left "no colon: \{show line}"
      let ns = nums b
      let (w :: h :: Nil) = nums' "x" a | _ => Left "bad dims \{show a}"
      Right $ MkR w h ns

part1 : String → IO Unit
part1 text = do
  let (Right prob) = parse text
    | Left err => putStrLn {IO} err
  printLn prob.gifts
  let rows = prob.rows
  let (easy, rest) = partition isEasy rows
  let (maybe, imp) = partition (isPossible prob.gifts) rest
  printLn "\{show $ length rows} rows, \{show $ length' easy} easy, \{show $ length' maybe} maybe, \{show $ length' imp} impossible"
  -- and there is nothing to do for the input, the "maybe" group is empty.
  pure MkUnit
  where
    isEasy : Row → Bool
    isEasy (MkR w h boxes) =
      let bw = w / 3
          bh = h / 3
          tbox = foldl _+_ 0 boxes
       in tbox <= bw * bh

    isPossible : List Int → Row → Bool
    isPossible gifts (MkR w h boxes) =
      let weight = foldl _+_ 0 $ map (uncurry _*_) $ zip boxes gifts
       in weight <= w * h

part2 : String → Int

run : String -> IO Unit
run fn = do
  putStrLn fn
  text <- readFile fn
  part1 text

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