Haskell Century From Year
centuryFromYear :: Int -> Int
centuryFromYear year = ceiling (fromIntegral year / 100 :: Double)

This converts a year into its century. Years 1-100 are century 1, 101-200 are century 2, and so on.

Haskell Check Palindrome
checkPalindrome :: String -> Bool
checkPalindrome inputString = reverse inputString == inputString

This compares the string with its reverse. If they match, it is a palindrome.

Haskell Chocolates By Numbers
chocolatesByNumbers :: Int -> Int -> Int
chocolatesByNumbers n m = (n * m) `div` gcd n m `div` m

This uses the greatest common divisor to figure out how many chocolates get eaten before the pattern repeats.

Haskell Common Prime Divisors
commonPrimeDivisors :: [Int] -> [Int] -> Int
commonPrimeDivisors as bs = length (filter matches (zip as bs))
  where
    matches (x, y) =
      let d = gcd x y
      in strip x d == 1 && strip y d == 1

    strip n m
      | n == 1    = 1
      | d == 1    = n
      | otherwise = strip (n `div` d) m
      where
        d = gcd n m

This checks whether two numbers are built from the same prime factors by repeatedly dividing out their shared parts.

Haskell Count Div
countDiv :: Int -> Int -> Int -> Int
countDiv a b k = (lastDiv - firstDiv) `div` k + 1
  where
    firstDiv = if a `mod` k == 0 then a else a + (k - a `mod` k)
    lastDiv  = b - b `mod` k

This counts how many numbers in a range are divisible by K without looping through every value.

Haskell Count Factors
countFactors :: Int -> Int
countFactors n = finalize (loop 1 0)
  where
    loop i count
      | i * i < n = loop (i + 1) (if n `mod` i == 0 then count + 2 else count)
      | otherwise = (i, count)

    finalize (i, count) = if i * i == n then count + 1 else count

This checks divisors in pairs up to the square root, which keeps the work much smaller than testing every number.

Haskell Count Non Divisible
import qualified Data.Map.Strict as Map

countNonDivisible :: [Int] -> [Int]
countNonDivisible a = map (\v -> size - divisorCount v) a
  where
    size = length a
    occ  = Map.fromListWith (+) [(v, 1 :: Int) | v <- a]
    occCount v = Map.findWithDefault 0 v occ

    divisorCount v =
      sum
        [ occCount i + (if v `div` i /= i then occCount (v `div` i) else 0)
        | i <- takeWhile (\i -> i * i <= v) [1 ..]
        , v `mod` i == 0
        ]

This counts how often each value appears, then subtracts the divisor matches so you get the non-divisible count for each item.

Haskell Count Semi Primes
import Control.Monad (forM_, when)
import Control.Monad.ST (runST)
import Data.Array (Array, listArray, (!))
import Data.Array.ST (newArray, readArray, runSTUArray, writeArray)
import Data.Array.Unboxed (UArray)

isPrimeArr :: Int -> UArray Int Bool
isPrimeArr n = runSTUArray $ do
  arr <- newArray (0, n) True
  forM_ [2 .. floor (sqrt (fromIntegral n :: Double))] $ \i -> do
    p <- readArray arr i
    when p $ forM_ [i * i, i * i + i .. n] $ \k -> writeArray arr k False
  return arr

semiPrimeArr :: Int -> UArray Int Bool -> UArray Int Bool
semiPrimeArr n primes = runSTUArray $ do
  arr <- newArray (0, n) False
  forM_ [k | k <- [2 .. floor (sqrt (fromIntegral n :: Double))], primes ! k] $ \k ->
    forM_ (takeWhile (\i -> i * k <= n) [2 ..]) $ \i ->
      when (primes ! i) $ writeArray arr (k * i) True
  return arr

prefixCounts :: Int -> UArray Int Bool -> Array Int Int
prefixCounts n semi =
  listArray (0, n) (scanl1 (+) (0 : [if semi ! i then 1 else 0 | i <- [1 .. n]]))

countSemiPrimes :: Int -> [Int] -> [Int] -> [Int]
countSemiPrimes n p q = [prefix ! qi - prefix ! (pi' - 1) | (pi', qi) <- zip p q]
  where
    primes = isPrimeArr n
    semi   = semiPrimeArr n primes
    prefix = prefixCounts n semi

This precomputes semiprimes and prefix sums so each range query becomes a quick subtraction.

Haskell Cyclic Rotation
cyclicRotation :: [Int] -> Int -> [Int]
cyclicRotation [] _ = []
cyclicRotation a k  = back ++ front
  where
    n             = length a
    r             = k `mod` n
    (front, back) = splitAt (n - r) a

This rotates the array to the right by K steps and keeps the wrap-around values in the correct order.

Haskell Distinct
import qualified Data.Set as Set

distinct :: [Int] -> Int
distinct a = Set.size (Set.fromList a)

This counts unique values by tracking what has already been seen.