Haskell cyclic behavior detection

I am making another projecteuler question in Haskell, where should I find if the sum of the factorials of each digit in a number is equal to the original number. If you do not repeat the process until the original number is reached. The next part is to find the number of starting numbers below 1 million, which have 60 non-repeating units. I got to this:

prob74 = length [ x | x <- [1..999999], 60 == ((length $ chain74 x)-1)]

factorial n = product [1..n]

factC x = sum $ map factorial (decToList x)

chain74 x  | x == 0 = []
           | x == 1 = [1]
           | x /= factC x = x : chain74 (factC x)

But what I don't know how to do is stop it as soon as the value for xbecomes cyclic. How can I stop chain74when it returns to the original number?

+3
source share
4 answers

, , , . . , , , .

, :

uniqlength :: (Eq a) => [a] -> Int
uniqlength l = uniqlength_ l []
   where uniqlength_ [] ls = length ls
         uniqlength_ (x:xs) ls
            | x `elem` ls = length ls
            | otherwise   = uniqlength_ xs (x:ls)

( , .)

+2

(, y) 74 .

: EDIT:

[.. ((length $ chain74 x x False)-1)]



chain74 x y not_first  | x == y && not_first = replace_with_stop_value_:-)
                       | x == 0 = []
                       | x == 1 = [1]
                       | x == 2 = [2]
                       | x /= factC x = x : chain74 (factC x) y True
+1

Haskell . , :

http://coder.bsimmons.name/blog/2009/04/cycle-detection/

String Bool.

EDIT: , :

cycling :: (Show a, Eq a) => Int -> [a] -> Bool
cycling k []     = False --not cycling
cycling k (a:as) = find 0 a 1 2 as
    where find _ _ c _  [] = False
          find i x c p (x':xs) 
            | c >  k    =  False  -- no cycles after k elements
            | x == x'   =  True   -- found a cycle 
            | c == p    = find c x' (c+1) (p*2) xs 
            | otherwise = find i x  (c+1) p xs

"k", , .

EDIT2: , :

prob74 = length [ x | x <- [1..999999], let chain = chain74 x, not$ cycling 999 chain, 60 == ((length chain)-1)]
+1

. , " " , , :

chains = [] : let f x = x : takeWhile (x /=) (chains !! factC x) in (map f [1..])

:

take 4 chains == [[],[1],[2],[3,6,720,5043,151,122,5,120,4,24,26,722,5044,169,363601,1454]]

map head $ filter ((== 60) . length) (take 10000 chains) 
is 
[1479,1497,1749,1794,1947,1974,4079,4097,4179,4197,4709,4719,4790,4791,4907,4917
,4970,4971,7049,7094,7149,7194,7409,7419,7490,7491,7904,7914,7940,7941,9047,9074
,9147,9174,9407,9417,9470,9471,9704,9714,9740,9741]

, "C" , . ( ), takeWhile, , ( , corecursion ).

, :

decycle :: Eq a => [a] -> [a]
decycle = dc []
    where
        dc _ [] = []
        dc xh (x : xs) = if elem x xh then [] else x : dc (x : xh) xs

decycle [1, 2, 3, 4, 5, 3, 2] == [1, 2, 3, 4, 5]
+1

Source: https://habr.com/ru/post/1718716/


All Articles