This code either returns the first factor of an Integer starting from 2 or returns nothing if it's a prime.
Example: firstFactorOf 24 returns "Just 2"
Example: firstFactorOf 11 returns "Nothing"
My question is, how would I return the value 2 rather than "Just 2" if there is a factor or return the value x if there is no factor.
firstFactorOf x
| m == Nothing = m
| otherwise = m
where m =(find p [2..x-1])
p y = mod x y == 0
//RETURNS:
ghci> firstFactorOf 24
Just 2
ghci> firstFactorOf 11
Nothing
Haskell is statically typed, meaning that you can define a function Maybe a -> a, but the question is what to do with the Nothing case.
Haskell has two functions that can be helpful here: fromMaybe and fromJust:
fromMaybe :: a -> Maybe a -> a
fromJust :: Maybe a -> a
fromJust simply assumes that you will always provide it a Just x, and return x, in the other case, it will throw an exception.
fromMaybe on the other hand expects two parameters, the first - an a is the "default case" the value that should be returned in case of Nothing. Next it is given a Maybe a and in case it is a Just x, x is returned. In the other case (Nothing) as said before the default is returned.
In your comment you say x should be returned in case no such factor exists. So I propose you define a new function:
firstFactorOfJust :: Integral a => a -> a
firstFactorOfJust x = fromMaybe x $ firstFactorOf x
So this function firstFactorOfJust calls your firstFactorOf function and if the result is Nothing, x will be returned. In the other case, the outcome of firstFactorOf will be returned (but only the Integral part, not the Just ... part).
EDIT (simplified)
Based on your own answer that had the intend to simplify things a bit, I had the idea that you can simplify it a bit more:
firstFactorOf x | Just z <- find ((0 ==) . mod x) [2..x-1] = z
| otherwise = x
and since we are all fan of optimization, you can already stop after sqrt(x) iterations (a well known optimization in prime checking):
isqrt :: Int -> Int
isqrt = floor . sqrt . fromIntegral
firstFactorOf x | Just z <- find ((0 ==) . mod x) [2..isqrt x] = z
| otherwise = x
Simplified question
For some reason there was some peculiarly complicated aspect in your question:
firstFactorOf x
| m == Nothing = m
| otherwise = m
where m =(find p [2..x-1])
p y = mod x y == 0
Why do you use guards to make a distinction between two cases that generate the exact same output? You can fold this into:
firstFactorOf x = m
where m = (find p [2..x-1])
p y = mod x y == 0
and even further:
firstFactorOf x = find p [2..x-1]
where p y = mod x y == 0
If you want it to return the first factor of x, or x, then this should work:
firstFactorOf x =
let
p y = mod x y == 0
m = (find p [2..x-1])
in
fromMaybe x m
import Data.List
import Data.Maybe
firstFactorOf x
| m == Nothing = x
| otherwise = fromJust m
where m =(find p [2..x-1])
p y = mod x y == 0
This was what I was after. Not sure why you guys made this so complicated.
Related
I am trying to solve the problems from Project Euler using Haskell, but I got sucked at #24
I'm trying to use factorials to solve problem but just can't work for the last three digits, here is my code:
import Data.List
fact n = product [n, n-1 .. 1]
recur :: Int -> Int -> [Int] -> [Int]
recur x y arr
| y > 1 = arr !! d : recur r (y-1) (delete (arr !! d) arr)
| otherwise = arr
where d = x `div` fact y
r = x `mod` fact y
main::IO()
main = print(recur 1000000 9 [0..9])
(I know it is now not really "functional")
I managed to get result [2,7,8,3,9,1,4,5,0,6], while the right answer I accidently figured out by hand is 2783915460.
I just want to know why this algorithm doesn't work for the last three digits. Thanks.
Unadulterated divMod is wrong for this algorithm. You need
dvm x facty | r == 0 = (d-1, facty)
| otherwise = (d, r)
where
(d, r) = divMod x facty
instead:
recur x y arr
.......
.......
where (d, r) = x `dvm` fact y
We cannot have zero combinations to do left. Zero means none.
Also the pattern guard condition should be changed to y > 0. Only when the length of the remaining choices list is 1 (at which point y is 0) there's no more choices to be made and we just use the last available digit left.
count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+(count_instances x ts)
| otherwise = count_instances x ts
i just want to know whats so good about using guards in this Question ?
A guard can be a way to write only one half of an if-then-else expression; you can omit the else and have a partial function.
-- Leave the function undefined for x /= y
foo x y | x == y = ...
You can do the same with a case statement, but it's more verbose
foo x y = case x == y of
True -> ...
It's also easier to list several unrelated conditions as a set of alternatives than it is with a nested if-then-else or case expressions.
foo x y | p1 x y = ...
foo x y | p2 x y = ...
foo x y | p3 x y = ...
foo x y = ...
vs
foo x y = if p1 x y then ...
else (if p2 x y then ...
else (if p3 x y then ... else ...))
Patterns with guards are probably the most concise way to write code that otherwise would require nested case/if expressions.
Not the least advantage is that a where clause applies to all the guards right hand sides. This is why your example could be even more concise:
count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+rest
| otherwise = rest
where rest = count_instances x ts
A guard is haskell's most general conditional statement, like if/then/else in other languages.
Your code shows a straight forward implementation of counting contents of a list equal to a given parameter. This is a good example to learn how haskell's recursion works.
An alternative implementation would be
count_instances :: Int -> [Int] -> Int
count_instances i = length . filter (==i)
that reuses already existing functions from the Prelude module. This is shorter and probably more readable.
I was reading the Haskell Prelude and finding it pretty understandable, then I stumbled upon the exponention definition:
(^) :: (Num a, Integral b) => a -> b -> a
x ^ 0 = 1
x ^ n | n > 0 = f x (n-1) x
where f _ 0 y = y
f x n y = g x n where
g x n | even n = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
_ ^ _ = error "Prelude.^: negative exponent"
I do not understand the need for two nested wheres.
What I understood so far:
(^) :: (Num a, Integral b) => a -> b -> a
The base must be a number and the exponent intege, ok.
x ^ 0 = 1
Base case, easy.
g x n | even n = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
Exponention by squaring... kind of ... Why is the f helper needed? Why are f and g given single letter names? Is it just optimization, am I missing something obvious?
_ ^ _ = error "Prelude.^: negative exponent"
N > 0 was checked before, N is negative if we arrived here, so error.
My implementation would be a direct translation to code of:
Function exp-by-squaring(x, n )
if n < 0 then return exp-by-squaring(1 / x, - n );
else if n = 0 then return 1; else if n = 1 then return x ;
else if n is even then return exp-by-squaring(x * x, n / 2);
else if n is odd then return x * exp-by-squaring(x * x, (n - 1) / 2).
Pseudocode from wikipedia.
To illustrate what #dfeuer is saying, note that the way f is written it either:
f returns a value
or, f calls itself with new arguments
Hence f is tail recursive and therefore can easily be transformed into a loop.
On the other hand, consider this alternate implementation of exponentiation by squaring:
-- assume n >= 0
exp x 0 = 1
exp x n | even n = exp (x*x) (n `quot` 2)
| otherwise = x * exp x (n-1)
The problem here is that in the otherwise clause the last operation performed is a multiplication. So exp either:
returns 1
calls itself with new arguments
calls itself with some new arguments and multiplies the result by x.
exp is not tail recursive and therefore cannot by transformed into a loop.
f is indeed an optimization. The naive approach would be "top down", calculating x^(n `div` 2) and then squaring the result. The downside of this approach is that it builds a stack of intermediate computations. What f lets this implementation do is to first square x (a single multiplication) and then raise the result to the reduced exponent, tail recursively. The end result is that the function will likely operate entirely in machine registers. g seems to help avoid checking for the end of the loop when the exponent is even, but I'm not really sure if it's a good idea.
As far as I understand it exponentiation is solved by squaring as long as the exponent is even.
This leads to the answer why f is needed in case of an odd number - we use f to return the result in the case of g x 1, in every other odd case we use f to get back in the g-routine.
You can see it best I think if you look at an example:
x ^ n | n > 0 = f x (n-1) x
where f _ 0 y = y
f x n y = g x n
where g x n | even n = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
2^6 = -- x = 2, n = 6, 6 > 0 thus we can use the definition
f 2 (6-1) 2 = f 2 5 2 -- (*)
= g 2 5 -- 5 is odd we are in the "otherwise" branch
= f 2 4 (2*2) -- note that the second '2' is still in scope from (*)
= f 2 4 (4) -- (**) for reasons of better readability evaluate the expressions, be aware that haskell is lazy and wouldn't do that
= g 2 4
= g (2*2) (4 `quot` 2) = g 4 2
= g (4*4) (2 `quot` 2) = g 16 1
= f 16 0 (16*4) -- note that the 4 comes from the line marked with (**)
= f 16 0 64 -- which is the base case for f
= 64
Now to your question of using single letter function names - that's the kind of thing you have to get used to it is a way most people in the community write. It has no effect on the compiler how you name your functions - as long as they start with a lower case letter.
As others noted, the function is written using tail-recursion for efficiency.
However, note that one could remove the innermost where while preserving tail-recursion as follows: instead of
x ^ n | n > 0 = f x (n-1) x
where f _ 0 y = y
f x n y = g x n
where g x n | even n = g (x*x) (n `quot` 2)
| otherwise = f x (n-1) (x*y)
we can use
x ^ n | n > 0 = f x (n-1) x
where f _ 0 y = y
f x n y | even n = f (x*x) (n `quot` 2) y
| otherwise = f x (n-1) (x*y)
which is also arguably more readable.
I have however no idea why the authors of the Prelude chose their variant.
Consider the modified Euler problem #4 -- "Find the maximum palindromic number which is a product of two numbers between 100 and 9999."
rev :: Int -> Int
rev x = rev' x 0
rev' :: Int -> Int -> Int
rev' n r
| n == 0 = r
| otherwise = rev' (n `div` 10) (r * 10 + n `mod` 10)
pali :: Int -> Bool
pali x = x == rev x
main :: IO ()
main = print . maximum $ [ x*y | x <- nums, y <- nums, pali (x*y)]
where
nums = [9999,9998..100]
This Haskell solution using -O2 and ghc 7.4.1 takes about 18
seconds.
The similar C solution takes 0.1 second.
So Haskell is 180 times
slower. What's wrong with my solution? I assume that this type of
problems Haskell solves pretty well.
Appendix - analogue C solution:
#define A 100
#define B 9999
int ispali(int n)
{
int n0=n, k=0;
while (n>0) {
k = 10*k + n%10;
n /= 10;
}
return n0 == k;
}
int main(void)
{
int max = 0;
for (int i=B; i>=A; i--)
for (int j=B; j>=A; j--) {
if (i*j > max && ispali(i*j))
max = i*j; }
printf("%d\n", max);
}
The similar C solution
That is a common misconception.
Lists are not loops!
And using lists to emulate loops has performance implications unless the compiler is able to eliminate the list from the code.
If you want to compare apples to apples, write the Haskell structure more or less equivalent to a loop, a tail recursive worker (with strict accumulator, though often the compiler is smart enough to figure out the strictness by itself).
Now let's take a more detailed look. For comparison, the C, compiled with gcc -O3, takes ~0.08 seconds here, the original Haskell, compiled with ghc -O2 takes ~20.3 seconds, with ghc -O2 -fllvm ~19.9 seconds. Pretty terrible.
One mistake in the original code is to use div and mod. The C code uses the equivalent of quot and rem, which map to the machine division instructions and are faster than div and mod. For positive arguments, the semantics are the same, so whenever you know that the arguments are always non-negative, never use div and mod.
Changing that, the running time becomes ~15.4 seconds when compiling with the native code generator, and ~2.9 seconds when compiling with the LLVM backend.
The difference is due to the fact that even the machine division operations are quite slow, and LLVM replaces the division/remainder with a multiply-and-shift operation. Doing the same by hand for the native backend (actually, a slightly better replacement taking advantage of the fact that I know the arguments will always be non-negative) brings its time down to ~2.2 seconds.
We're getting closer, but are still a far cry from the C.
That is due to the lists. The code still builds a list of palindromes (and traverses a list of Ints for the two factors).
Since lists cannot contain unboxed elements, that means there is a lot of boxing and unboxing going on in the code, that takes time.
So let us eliminate the lists, and take a look at the result of translating the C to Haskell:
module Main (main) where
a :: Int
a = 100
b :: Int
b = 9999
ispali :: Int -> Bool
ispali n = go n 0
where
go 0 acc = acc == n
go m acc = go (m `quot` 10) (acc * 10 + (m `rem` 10))
maxpal :: Int
maxpal = go 0 b
where
go mx i
| i < a = mx
| otherwise = go (inner mx b) (i-1)
where
inner m j
| j < a = m
| p > m && ispali p = inner p (j-1)
| otherwise = inner m (j-1)
where
p = i*j
main :: IO ()
main = print maxpal
The nested loop is translated to two nested worker functions, we use an accumulator to store the largest palindrome found so far. Compiled with ghc -O2, that runs in ~0.18 seconds, with ghc -O2 -fllvm it runs in ~0.14 seconds (yes, LLVM is better at optimising loops than the native code generator).
Still not quite there, but a factor of about 2 isn't too bad.
Maybe some find the following where the loop is abstracted out more readable, the generated core is for all intents and purposes identical (modulo a switch of argument order), and the performance of course the same:
module Main (main) where
a :: Int
a = 100
b :: Int
b = 9999
ispali :: Int -> Bool
ispali n = go n 0
where
go 0 acc = acc == n
go m acc = go (m `quot` 10) (acc * 10 + (m `rem` 10))
downto :: Int -> Int -> a -> (a -> Int -> a) -> a
downto high low acc fun = go high acc
where
go i acc
| i < low = acc
| otherwise = go (i-1) (fun acc i)
maxpal :: Int
maxpal = downto b a 0 $ \m i ->
downto b a m $ \mx j ->
let p = i*j
in if mx < p && ispali p then p else mx
main :: IO ()
main = print maxpal
#axblount is at least partly right; the following modification makes the program run almost three times as fast as the original:
maxPalindrome = foldl f 0
where f a x | x > a && pali x = x
| otherwise = a
main :: IO ()
main = print . maxPalindrome $ [x * y | x <- nums, y <- nums]
where nums = [9999,9998..100]
That still leaves a factor 60 slowdown, though.
This is more true to what the C code is doing:
maxpali :: [Int] -> Int
maxpali xs = go xs 0
where
go [] m = m
go (x:xs) m = if x > m && pali(x) then go xs x else go xs m
main :: IO()
main = print . maxpali $ [ x*y | x <- nums, y <- nums ]
where nums = [9999,9998..100]
On my box this takes 2 seconds vs .5 for the C version.
Haskell may be storing that entire list [ x*y | x <- nums, y <- nums, pali (x*y)] where as the C solution calculates the maximum on the fly. I'm not sure about this.
Also the C solution will only calculate ispali if the product beats the previous maximum. I would bet Haskell calculates are palindrome products regardless of whether x*y is a possible max.
It seems to me that you are having a branch prediction problem. In the C code, you have two nested loops and as soon as a palindrome is seen in the inner loop, the rest of the inner loop will be skipped very fast.
The way you feed this list of products instead of the nested loops I am not sure that ghc is doing any of this prediction.
Another way to write this is to use two folds, instead of one fold over the flattened list:
-- foldl g0 0 [x*y | x<-[b-1,b-2..a], y<-[b-1,b-2..a], pali(x*y)] (A)
-- foldl g1 0 [x*y | x<-[b-1,b-2..a], y<-[b-1,b-2..a]] (B)
-- foldl g2 0 [ [x*y | y<-[b-1,b-2..a]] | x<-[b-1,b-2..a]] (C)
maxpal b a = foldl f1 0 [b-1,b-2..a] -- (D)
where
f1 m x = foldl f2 m [b-1,b-2..a]
where
f2 m y | p>m && pali p = p
| otherwise = m
where p = x*y
main = print $ maxpal 10000 100
Seems to run much faster than (B) (as in larsmans's answer), too (only 3x - 4x slower then the following loops-based code). Fusing foldl and enumFromThenTo definitions gets us the "functional loops" code (as in DanielFischer's answer),
maxpal_loops b a = f (b-1) 0 -- (E)
where
f x m | x < a = m
| otherwise = g (b-1) m
where
g y m | y < a = f (x-1) m
| p>m && pali p = g (y-1) p
| otherwise = g (y-1) m
where p = x*y
The (C) variant is very suggestive of further algorithmic improvements (that's outside the scope of the original Q of course) that exploit the hidden order in the lists, destroyed by the flattening:
{- foldl g2 0 [ [x*y | y<-[b-1,b-2..a]] | x<-[b-1,b-2..a]] (C)
foldl g2 0 [ [x*y | y<-[x, x-1..a]] | x<-[b-1,b-2..a]] (C1)
foldl g0 0 [ safehead 0 . filter pali $
[x*y | y<-[x, x-1..a]] | x<-[b-1,b-2..a]] (C2)
fst $ until ... (\(m,s)-> (max m .
safehead 0 . filter pali . takeWhile (> m) $
head s, tail s))
(0,[ [x*y | y<-[x, x-1..a]] | x<-[b-1,b-2..a]]) (C3)
safehead 0 $ filter pali $ mergeAllDescending
[ [x*y | y<-[x, x-1..a]] | x<-[b-1,b-2..a]] (C4)
-}
(C3) can stop as soon as the head x*y in a sub-list is smaller than the currently found maximum. It is what short-cutting functional loops code could achieve, but not (C4), which is guaranteed to find the maximal palindromic number first. Plus, for list-based code its algorithmic nature is more visually apparent, IMO.
I'm writing a bit of code to help me with some math stuff. I'm trying to implement the Miller test, not Miller-Rabin, and I need to make a list of a bunch of exponents. Here's the code so far. It inserts the last result twice for some reason, and I don't know why. I must not understand how the until function works.
import Math.NumberTheory.Powers
divides::Integer->Integer->Bool
divides x y = y `mod` x == 0
factorcarmichael::Integer->(Integer,Integer)
factorcarmichael n = until (\(_, s) -> not $ divides 2 s)
(\(r, s) -> (r+1, div s 2))
(0, n-1)
second::((Integer,Integer),[Integer])->[Integer]
second (x,xs) = xs
millerlist::Integer->Integer->[Integer]
millerlist a n = second $ until (\((r,s), xs) -> r<0)
(\((r,s), xs) -> ((r-1,s), (powerMod a ((2^r)*s) n):xs))
(factoredcarmichael, [])
where
factoredcarmichael = factorcarmichael n
Also, the millerlist function is a little kludgy. If someone can suggest an alternative, that would be nice.
The output I'm getting for
millerlist 8888 9746347772161
repeats the last element twice.
That is because
7974284540860^2 ≡ 7974284540860 (mod 9746347772161)
so the number appears twice in the list. But your list is one too long, I believe. I think you only want the remainder of a^(2^k*s) modulo n for 0 <= k < r.
As for alternatives, is there a particular reason why you're not using Math.NumberTheory.Primes.isStrongFermatPP? If you're only interested in the outcome, that's less work coding.
If you want to generate the list, what about
millerlist a n = go r u
where
(r,s) = factorcarmichael n
u = powerMod a s n
go 0 m = []
go k m = m : go (k-1) ((m*m) `mod` n)
or
millerlist a n = take (fromInteger r) $ iterate (\m -> (m*m) `mod` n) u
where
(r,s) = factorcarmichael n
u = powerMod a s n