これは圏です(はてな使ったら負けだとおもっていた)

きっと何者にもなれないつぎの読者につづく。

素因数分解器異常発見

よく見たら何故か使う素数の上限が12迄になってました……orz
と、云うわけで修正版です。

module Main where
import List
import Maybe
import System
import Numeric

erat (x:xs) = x:erat [y | y <- xs, y `mod` x /= 0]
primes =  erat (2:[3,5..])

factorize n = findDividers n $ take (fromInteger (floor $ sqrt $fromInteger n)) primes

findDividers                  :: Integer -> [Integer] -> [Integer]
findDividers n divs | n == 1    = []
                    | otherwise = [x] ++ (findDividers (n `div` x) divs) where
                                      f y = (==) 0 $ mod n y
                                      x = let m = find f divs 
                                            in if (isJust  m) then fromJust m else n

factorToStr (Factor a b) = show a ++ "^" ++ show b

toExp   :: [Integer] -> String
toExp x = foldl1 (++) (intersperse " * " (map factorToStr (arrangeFact x)))
          where aryToFact a = Factor a 1
                arrangeFact []      = []
                arrangeFact (x:xs)  = if (xs/=[]) then (makeFactor x xs) : (arrangeFact $ filter (/=x) xs) else [Factor x 1]
                makeFactor = ?a as -> Factor a $ toInteger (length  (a: filter (==a) as))


data Factor a b = Factor a b
power (Factor a b)  = b

base (Factor a b)  = a

instance (Show a, Show b) => Show (Factor a b) where
  show (Factor a b) = "{" ++ show a  ++ "^" ++ show b ++ "}"

instance (Eq a) => Eq (Factor a b) where
  (Factor b1 p1) == (Factor b2 p2)  = (b1 == b2)

usage = putStrLn "usage: factorize [number]"

main  = do  args <- getArgs
            case args of
              x:_ -> putStrLn $ toExp $ factorize $ read x
              _       -> usage