[Haskell] CodeWars|Integers: Recreation One

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 where

listSquared :: 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) x

check x
 | floor (sqrt $ fromIntegral s) ^ 2 == s = [(x, s)]
 | otherwise = []
 where s = square 1 x

listSquared m n
 | m > n = []
 | otherwise = (check m) ++ listSquared (m + 1) n
  1. 暴力法(改进版,map filter用起来)
module Codewars.G964.Sumdivsq where

listSquared :: Int -> Int -> [(Int, Int)]
check :: Int -> [(Int, Int)]
factorSum :: Int -> Int

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])))

check x
 | floor (sqrt $ fromIntegral s) ^ 2 == s = [(x, s)]
 | otherwise = []
 where s = factorSum x

listSquared m n = concatMap check [m..n]
  1. 暴力法(改进改进版)
module Codewars.G964.Sumdivsq where

listSquared :: 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])))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值