[Haskell] CodeWars|Integers: Recreation One

来源:互联网 发布:logic studio mac 编辑:程序博客网 时间:2024/05/17 07:57

https://www.codewars.com/kata/55aa075506463dac6600010d/haskell

题目

42的因数有:1,2,3,6,7,14,21,42,平方后为1,4,9,36,49,196,441,1764,和为2500,是一个完全平方数(50×50)。
给定两个整数m,n(1mn),找出[m,n]中所有因数平方和为完全平方数的数(比如42)。

结果是数对的列表,数对的第一个元素是符合条件的数,第二个元素为该数的因数平方和。

样例

list_squared 1 250 = [(1, 1), (42, 2500), (246, 84100)]list_squared 42 250 = [(42, 2500), (246, 84100)]

题解

  1. 暴力法(C语言风格版。。一堆递归代替循环)
module Codewars.G964.Sumdivsq wherelistSquared :: Int -> Int -> [(Int, Int)]check :: Int -> [(Int, Int)]square d x | d * d == x = d ^ 2 | d * d > x = 0 | x `mod` d == 0 = square (d + 1) x + d ^ 2 + div x d ^ 2 | otherwise = square (d + 1) xcheck x | floor (sqrt $ fromIntegral s) ^ 2 == s = [(x, s)] | otherwise = [] where s = square 1 xlistSquared m n | m > n = [] | otherwise = (check m) ++ listSquared (m + 1) n
  1. 暴力法(改进版,map filter用起来)
module Codewars.G964.Sumdivsq wherelistSquared :: Int -> Int -> [(Int, Int)]check :: Int -> [(Int, Int)]factorSum :: Int -> IntfactorSum x = sum (map (^ 2) (filter ((==0) . mod x) ([1..floor (sqrt (fromIntegral x))] >>= \k -> if k * k == x then [k] else [k, div x k])))check x | floor (sqrt $ fromIntegral s) ^ 2 == s = [(x, s)] | otherwise = [] where s = factorSum xlistSquared m n = concatMap check [m..n]
  1. 暴力法(改进改进版)
module Codewars.G964.Sumdivsq wherelistSquared :: Int -> Int -> [(Int, Int)]listSquared m n = filter (isSquare . snd) $ map (\x -> (x, factorSum x)) [m..n]    where        isSquare x = floor (sqrt $ fromIntegral x) ^ 2 == x        factorSum x = sum (map (^ 2) (filter ((==0) . mod x) ([1..floor (sqrt (fromIntegral x))] >>= \k -> if k * k == x then [k] else [k, div x k])))