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.