Project Euler 42

http://projecteuler.net/index.php?section=problems&id=42


三角数の判定は、

(n2 + n) / 2 = m
n2 + n - 2m = 0
n = (-1 + √(1 + 8m)) / 2

だから、1 + 8mが平方数かどうか。
sqrtが使えるが、sqrtの引数は実数でなければならないので型変換する必要がある。整数型から変換するのはfromIntegralで、逆はfloorでよい。整数型全般で使えるので、型指定が必要。

int_sqrt :: Int -> Int
int_sqrt n = floor (sqrt (fromIntegral n))
is_square n = m * m == n where m = int_sqrt(n)
import Char

split_core buff [] = []
split_core [] (c:cs) = case c of
                        '\"'        -> split_core [] cs
                        ','         -> split_core [] cs
                        otherwise   -> split_core [c] cs
split_core buff (c:cs) = case c of
                        '\"'        -> [buff] ++ (split_core [] cs)
                        otherwise   -> split_core (buff ++ [c]) cs
split s = split_core [] s

int_sqrt :: Int -> Int
int_sqrt n = floor (sqrt (fromIntegral n))
is_square n = m * m == n where m = int_sqrt(n)
is_triangle n = is_square (1 + 8 * n)

base = (Char.ord 'A') - 1
convert [] = 0
convert (c:cs) = (Char.ord c) - base + (convert cs)

main = do
    cs <- readFile "words.txt"
    print(length (filter is_triangle (map convert (split cs))))