diff --git a/app/FactorizationUI.hs b/app/FactorizationUI.hs index eed7eb3..f09d15d 100644 --- a/app/FactorizationUI.hs +++ b/app/FactorizationUI.hs @@ -42,7 +42,11 @@ dixonUI = do n <- askNumber "Enter an integer n > 1:" b <- askNumber "Enter the bound B:" x <- askNumber "Enter the max random integer x:" - let (p, q) = dixon n b x - putStrLn ("n = " ++ show n) - putStrLn ("p = " ++ show p) - putStrLn ("q = " ++ show q) + + case dixon n b x of + Left err -> do + putStrLn ("Error: " ++ err) + Right (p, q) -> do + putStrLn ("n = " ++ show n) + putStrLn ("p = " ++ show p) + putStrLn ("q = " ++ show q) diff --git a/src/Factorization/Dixon.hs b/src/Factorization/Dixon.hs index 886bcab..a150d9e 100644 --- a/src/Factorization/Dixon.hs +++ b/src/Factorization/Dixon.hs @@ -14,10 +14,10 @@ factorOverBase primes a = go primes a [] in go ps num' (e : acc) -dixon :: Integer -> Integer -> Integer -> (Integer, Integer) +dixon :: Integer -> Integer -> Integer -> Either String (Integer, Integer) dixon n b maxX - | n <= 3 = error "n must be greater than 3" - | even n = (2, n `div` 2) + | n <= 3 = Left "n must be greater than 3" + | even n = Right (2, n `div` 2) | otherwise = let base = erathosteneSieve b numCols = length base @@ -33,21 +33,21 @@ dixon n b maxX Just exps <- [factorOverBase base a]] numCollected = length pairs in if numCollected <= numCols - then error $ "Not enough smooth squares found up to " ++ show maxX + then Left $ "Not enough smooth squares found up to " ++ show maxX else let xs = map fst pairs allExps = map snd pairs bitvecs = map (fromBools . map (\e -> e `mod` 2 == 1)) allExps in case gaussianEliminationMask numCols bitvecs of - Nothing -> error "No linear dependency found" + Nothing -> Left "No linear dependency found" Just mask -> let indices = maskToIndicesInt mask in if null indices - then error "Empty dependency" + then Left "Empty dependency" else let productX = foldl (\acc idx -> modMul acc (xs !! idx) n) 1 indices fs = [ sum [ (allExps !! idx !! j) | idx <- indices ] `div` 2 | j <- [0 .. numCols - 1] ] z = foldl (\acc (p, f) -> if f == 0 then acc else modMul (modExp p f n) acc n) 1 (zip base fs) diff = productX - z g = gcd (abs diff) n in if g == 1 || g == n - then error "non trivial factors not found, try larger b or maximum x" - else (g, n `div` g) + then Left "non trivial factors not found, try larger b or maximum x" + else Right (g, n `div` g)