module Day2

import Prelude
import Node
import Aoc

parse : String → List (Int × Int)
parse text = map mkPair $ split text ","
  where
    mkPair : String → Int × Int
    mkPair t = case split t "-" of
      (a :: b :: Nil) => (stringToInt a, stringToInt b)
      bad => fatalError "BAD \{t}"

invalid : Int → Bool
invalid n =
  let s = show n
      l = slen s
      h = l / 2
  in if h * 2 /= l then False
  else go s 0 h
  where
    go : String → Int → Int → Bool
    go s i h = if i == h
      then True
      else if sindex s i == sindex s (i + h) then go s (i + 1) h else False

match : Int → Int → Bool
match f n = let v = mod n f in if v * 10 < f then False else go v n
  where
    go : Int → Int → Bool
    go pat 0 = True
    go pat n = if (mod n f) /= pat then False else go pat (n / f)

invalid2 : Int → Bool
invalid2 s = go 10 s
  where
    go : Int → Int → Bool
    go f n =
      if f * f > n * 10 then False
      else if match f n then True
      else go (f * 10) n

scan : (Int → Bool) → Int → Int → Int → Int
scan invalid a b acc =
  let acc = if invalid a then acc + a else acc in
  if a == b then acc else scan invalid (a + 1) b acc

part1 : String → Int
part1 text = foldl (\acc x => scan invalid (fst x) (snd x) acc) 0 $ parse text

part2 : String → Int
part2 text = foldl (\acc x => scan invalid2 (fst x) (snd x) acc) 0 $ parse text

run : String -> IO Unit
run fn = do
  putStrLn fn
  text <- readFile fn
  putStrLn $ "part1 " ++ show (part1 text)
  putStrLn $ "part2 " ++ show (part2 text)

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