Project Euler #12: Highly divisible triangular number

  • + 0 comments

    Haskell

    import Control.Applicative
    import Control.Monad
    import System.IO
    import Prelude
    import Data.List
    
    isqrt :: Int -> Int -- Thanks StackOverflow
    isqrt = ceiling . sqrt . fromIntegral
    
    triangle_num :: Int -> Int
    triangle_num n = (n * (n + 1)) `div` 2
    
    triangle_nums = map triangle_num [1..]
    
    primes = 2 : [i | i <- [3..1000],  
                  and [rem i p > 0 | p <- takeWhile (\p -> p^2 <= i) primes]]
    
    num_subdivisions :: Int -> Int -> Int -> Int
    num_subdivisions num divisor rem
        | num `mod` divisor /= 0 = rem
        | otherwise = num_subdivisions (num `div` divisor)  divisor (rem+1)
    
    num_divisors :: Int -> Int
    num_divisors 1 = 1
    num_divisors n = product [((num_subdivisions n x 0) + 1) | x <- (filter (<= ((isqrt n) + 1)) primes), n `mod` x == 0]
    
    smallestTri :: Int -> [Int] -> Int
    smallestTri n xs
        | num_divisors (head xs) > n = head xs
        | otherwise = smallestTri n (tail xs)
    
    main :: IO ()
    main = do
        t_temp <- getLine
        let t = read t_temp :: Int
        forM_ [1..t] $ \a0  -> do
            n_temp <- getLine
            let n = read n_temp :: Int
            let smallTri = smallestTri n triangle_nums
            print(smallTri)