From 4957f1164ef7ad7670289dc63013ea80adc4f974 Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Sat, 8 Aug 2020 13:53:17 +1000 Subject: [ch-071/jeongoon] add brute force method of haskell for task 1 --- challenge-072/jeongoon/haskell/ch-1.hs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/challenge-072/jeongoon/haskell/ch-1.hs b/challenge-072/jeongoon/haskell/ch-1.hs index 0775791436..7780f3ba55 100644 --- a/challenge-072/jeongoon/haskell/ch-1.hs +++ b/challenge-072/jeongoon/haskell/ch-1.hs @@ -15,30 +15,37 @@ https://stackoverflow.com/questions/940382/what-is-the-difference-between-dot-an ... and many more.. --} -factorial :: Integer -> Integer -factorial x = product [ 1.. x ] +factorial :: Int -> Integer +factorial x = product [ 1.. fromIntegral x ] -nthRootOfFive :: Integer -> Integer +nthRootOfFive :: Integer -> Int nthRootOfFive x | x `mod` 5 /= 0 = 0 | otherwise = 1 + nthRootOfFive ( x `div` 5 ) - -getN :: [String] -> Integer +getN :: [String] -> Int getN [] = 0 -getN (x:xs) = if all isNumber x then read x :: Integer else getN xs +getN (x:xs) = if all isNumber x then read x :: Int else getN xs -printGenTrim :: [String] -> Integer -> Integer -> IO () +printGenTrim :: [String] -> Int -> Int-> IO () printGenTrim x n a | ( "--show-divided" `elem` x ) = do putStrLn $ "N! = " ++ fnstr putStrLn $ "N! = " ++ take h fnstr ++ " | " ++ drop h fnstr | otherwise = return () where - fnstr = show $ factorial $ n + fnstr = show $ factorial n a' = fromIntegral a h = length fnstr - a' +calculateTrailingZero :: Int -> Int +calculateTrailingZero n = sum [ nthRootOfFive $ fromIntegral x | x <- [1 .. n] ] + +bruteforceTrailingZero :: Int -> Int +bruteforceTrailingZero n = + length $ takeWhile (\x -> nFact `mod` x == 0) (map (10^) [(1::Integer)..]) + where nFact = factorial $ fromIntegral n + main :: IO () main = do args <- getArgs -- IO [String] @@ -56,7 +63,9 @@ main = do else die "Could not find N (Not given or Invalid)" - putStrLn $ "Given Number: " ++ show n - let answer = sum [ nthRootOfFive x | x <- [ 1 .. n ] ] + putStrLn $ "Given Number: " ++ show n + let answer = calculateTrailingZero n + let answer' = bruteforceTrailingZero n printGenTrim args n answer - putStrLn $ "Answer: " ++ show answer + putStrLn $ "Calcuated: " ++ show answer + putStrLn $ "BruteForced: " ++ show answer' -- cgit From 5d7ff3b80829bb9353d30fceda6cb3a204e527a9 Mon Sep 17 00:00:00 2001 From: Myoungjin JEON Date: Mon, 10 Aug 2020 00:38:46 +1000 Subject: [ch-072/jeongoon] add brute force method of haskell for task1; [ch-069/jeongoon] add haskell/ch-1.hs --- challenge-069/jeongoon/haskell/ch-1.hs | 88 ++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 challenge-069/jeongoon/haskell/ch-1.hs diff --git a/challenge-069/jeongoon/haskell/ch-1.hs b/challenge-069/jeongoon/haskell/ch-1.hs new file mode 100644 index 0000000000..51d95a2bb4 --- /dev/null +++ b/challenge-069/jeongoon/haskell/ch-1.hs @@ -0,0 +1,88 @@ +import System.Environment +import System.Exit +import Data.Char +import Control.Monad + +{- Tested with: +ghc ch-1.hs +./ch-1 +-} +{- it was slow without compiling -} + +wikiStroboDigits :: [Int]; +wikiStroboDigits = [ 0, 1, 6, 8, 9 ]; +symmetricDigits :: [Int]; +symmetricDigits = [ 0, 1, 8 ]; + +lengthOfInt :: (Integral a, Integral b) => a -> b -> b +lengthOfInt x acc + | x' `mod` (10 ^n') == (toInteger x) = acc + | otherwise = lengthOfInt x $! (acc+1) + where + x' = toInteger x + n' = toInteger acc + +getOppStroboDigits :: (Integral a) => [a] -> [a] +getOppStroboDigits xs = [ case id x of { (6) -> 9; (9) -> 6; _ -> x } | x <- reverse xs ] + +generateStroboLeft :: (Integral a) => a -> a -> [[Int]] -> [[Int]] +generateStroboLeft halfLen clen acc -- clen initial value must be 1 + | halfLen == 0 = map (\x -> [x]) $ tail symmetricDigits -- XXX: totLen = 1 + | halfLen < 1 = [[]] + | halfLen == 1 = [ [x] | x <- tail wikiStroboDigits ] + | halfLen >= clen = + generateStroboLeft halfLen (clen+1) [ foldr (:) [stb] l | l <- acc + , stb <- stroboLeft ] + | otherwise = acc + where stroboLeft = if clen == 1 then tail wikiStroboDigits else wikiStroboDigits + +stroboNumbersWith :: (Eq a, Integral a) => a -> [[Int]] -> [Int] +stroboNumbersWith totLen leftOnlyAcc = + let left = generateStroboLeft halfLen 1 leftOnlyAcc + in + -- special case + if totLen == 1 then map concatInt left + else + if hasMiddle then + map concatInt [ foldr (:) (sym : (getOppStroboDigits l)) l | l <- left + , sym <- symmetricDigits ] + else map concatInt [ foldr (:) (getOppStroboDigits l) l | l <- left ] + where + hasMiddle = totLen `mod` 2 == 1 + halfLen = totLen `div` 2 + +concatInt :: [Int] -> Int +concatInt = foldl (\x y -> x*10+y) 0 + +filterRange :: Int -> Int -> [Int] -> [Int] +filterRange a b ls = filter (\x -> a <= x && x <= b ) ls + +stroboNumbersWithRange :: Int -> Int -> Int -> Int -> Int -> [Int] -> [Int] +stroboNumbersWithRange a b minLen maxLen len acc + | ( minLen /= minlen || maxLen /= maxlen ) || minLen > len = + stroboNumbersWithRange a b minlen maxlen minlen [] -- initializing + | len > maxLen = acc + | len == minLen || len == maxLen = + let acc' = filterRange a b $ stroboNumbersWith len [[]] -- not [] but [[]] + in stroboNumbersWithRange a b minLen maxLen (len+1) (acc ++ acc') + | otherwise = + let acc' = stroboNumbersWith len [[]] + in stroboNumbersWithRange a b minLen maxLen (len+1) (acc ++ acc') + where + minlen = (lengthOfInt a 1) + maxlen = (lengthOfInt b 1) + +main :: IO() +main = do + args <- getArgs + + if length args /= 2 then + die $ "[ERR] Wrnong Number of Args: " ++ (show (length args)) ++ "must be == 2" + else + return () + + let a = read ( args !! 0 ) :: Int + b = read ( args !! 1 ) :: Int + numbers = stroboNumbersWithRange a b 0 0 0 [] + + mapM_ (\x -> print x) numbers -- cgit