I'm trying to write a procedure that returns a list of all primes below a given number.
For example:
Prelude>primes 8
[2,3,5,7]
When I try to load the file I get Parse error in pattern Failed, modules loaded: none. If someone could point me in the right direction I would be grateful.
primes :: Int -> [Int]
primes x < 2 = []
primes x | isPrime x == True = primes (x - 1) ++ x
| otherwise = primes (x - 1)
isPrime :: Int -> Bool
isPrime x | x < 2 = False
| x == 2 || x == 3 = True
| divEven x == True = False
| divOdd x 3 == True = False
| otherwise = True
divEven :: Int -> Bool
divEven x | mod x 2 == 0 = True
| otherwise = False
divOdd :: Int Int -> Bool
divOdd x num | mod x num == 0 == True
| num <= x/2 = divOdd x (num + 2)
| otherwise = False
A collection of small mistakes.
Your syntax is incorrect.
primes x < 2 = []
Probably you meant
primes x | x < 2 = []
Similarly, where you write
divOdd x num | mod x num == 0 == True
you probably meant
divOdd x num | mod x num == 0 = True
The type signature
divOdd :: Int Int -> Bool
is not valid. You probably meant
divOdd :: Int -> Int -> Bool
x is of type Int, and (/) :: Fractional a => a -> a -> a cannot be applied to it. You probably mean num <= x `div` 2 or 2 * num <= x.
divOdd :: Int Int -> Bool
divOdd x num | mod x num == 0 == True
| num <= x/2 = divOdd x (num + 2)
| otherwise = False
x is of type Int, not [Int]. (++) :: [a] -> [a] -> [a] will not apply to it.
primes x | isPrime x == True = primes (x - 1) ++ x
Perhaps you meant
primes x | isPrime x == True = primes (x - 1) ++ [x]
Finally, this is a fairly inefficient way of generating primes. Have you considered a sieve? Prime numbers - HaskellWiki may be a bit difficult for you right now, but shows many different strategies.
Here's a re-write of your functions using list comprehensions (also in Wikipedia), perhaps this is more visually apparent:
primes :: Int -> [Int]
primes x | x<2 = []
| x<4 = [2..x]
| True = primes (x-1) ++ [x | isPrime x]
your isPrime is
isPrime x = x > 1 &&
( x < 4 ||
and [ rem x n /= 0 | n <- 2 : [3,5..(div x 2)+2] ] )
and is a function defined in standard Prelude. It will test entries in a list, left to right, to see if all are True. It will stop on the first False entry encountered, so the rest of them won't get explored.
Sometimes when the code is more visually apparent it is easier to see how to improve it.
Related
I have this function which takes an integer n and returns a list of type Maybe Int, containing the unique prime factors. I don't understand why it returns them with Just inside every element of the list.
I expect an output like this:
primeFactors 75 = Just [3,5]
But I have one that looks like this:
primeFactor 75 = [Just 5,Just 3,Just 1]
Here is my code:
divides :: Int -> Int -> Bool
divides m n = rem m n == 0
transform :: Int -> Int
transform n = (n*2) + 1
isComposite :: Int -> Bool
isComposite n = foldl (||) (divides n 2) (map (divides n) (map (transform) [1..(div n 4)]))
isPrime :: Int -> Bool
isPrime n
| n <= 0 = error "Makes no sense"
| n < 4 = True
| otherwise = not (isComposite n)
primeFactors :: Int -> [Maybe Int]
primeFactors 0 = [Nothing]
primeFactors n = primeFactors2 n ((div n 2)+1)
primeFactors2 :: Int -> Int -> [Maybe Int]
primeFactors2 n 0 = []
primeFactors2 n x
| divides n x && isPrime x = Just x:primeFactors2 n (x-1)
| otherwise = primeFactors2 n (x-1)
Here is a version of your code that I think will do what you want:
primeFactors :: Int -> Maybe [Int]
primeFactors n
| n <= 0 = Nothing
| otherwise = Just $ primeFactors2 n n
primeFactors2 :: Int -> Int -> [Int]
primeFactors2 n p
| n <= 1 || p <= 1 = []
| divides n p && isPrime p = p : primeFactors2 (n `div` p) p
| otherwise = primeFactors2 n (p-1)
isPrime :: Int -> Bool
isPrime n
| n <= 1 = False
| otherwise = not (isComposite n)
isComposite :: Int -> Bool
isComposite n =
any (divides n) [2..n-1]
divides :: Int -> Int -> Bool
divides m n =
rem m n == 0
Please note that (for clarity's sake I hope) I did remove some of your optimizations and made a major change: this one will report Just [2,2] as prime-factors for 4
(IMO you want product <$> primeFactors n == Just n).
If not (as your example indicates) it shouldn't be too hard to fix this (just take your version).
Anyway the only really interesting contribution is how primeFactor handles primeFactors2 to get you the Maybe result.
I am trying to convert the following function which test the number if it's prime to another one that test if the integer is a circular prime.
eg. 1193 is a circular prime, since 1931, 9311 and 3119 all are also prime.
So i need to rotate the digits of the integer and test if the number is prime or not. any ideas?
note: I am new to Haskell Programming
isPrime :: Integer -> Bool
isPrime 1 = False
isPrime 2 = True
isPrime n
| (length [x | x <- [2 .. n-1], n `mod` x == 0]) > 0 = False
| otherwise = True
isCircPrime :: Integer -> Bool
You can improve the efficiency and elegance of your isPrime function easily by implementing it as:
isPrime :: Integral i => i -> Bool
isPrime 1 = False
isPrime n = all ((/=) 0 . mod n) (takeWhile (\x -> x*x <= n) [2..])
In order to rotate numbers, we can make use of two helper functions here: one to convert a number to a list of digits, and one to convert a list of digits to a number, we do this in reverse, since that is more convenient to implement, but will not matter:
num2dig :: Integral i => i -> [i]
num2dig n | n < 10 = [n]
| otherwise = r : num2dig q
where (q, r) = quotRem n 10
dig2num :: (Foldable t, Num a) => t a -> a
dig2num = foldr ((. (10 *)) . (+)) 0
Now we can make a simple function to generate, for a list of items, all rotations:
import Control.Applicative(liftA2)
import Data.List(inits, tails)
rots :: [a] -> [[a]]
rots = drop 1 . liftA2 (zipWith (++)) tails inits
So we can use this to construct all rotated numbers:
rotnum :: Integral i => i -> [i]
rotnum = map dig2num . rots . num2dig
For example for 1425, the rotated numbers are:
Prelude Control.Applicative Data.List> rotnum 1425
[5142,2514,4251,1425]
I leave using isPrime on these numbers as an exercise.
Referencing your question here, you can achieve what you want by adding a single new function:
check :: Integer -> Bool
check n = and [isPrime (stringToInt cs) | cs <- circle (intToString n)]
This is to add an easier to understand solution from where you already were in your specific code, as I can see you were asking for that specifically. Usage:
*Main> check 1931
True
*Main> check 1019
False
Mind you, I have made some type-changes. I assume you want each function to be type-specific, due to their names. Full code, taken from your example:
circle :: String -> [String]
circle xs = take (length xs) (iterate (\(y:ys) -> ys ++ [y]) xs)
stringToInt :: String -> Integer
stringToInt x = read (x) :: Integer
intToString :: Integer -> String
intToString x = show x
isPrime :: Integer -> Bool
isPrime 1 = False
isPrime 2 = True
isPrime n
| (length [x | x <- [2 .. n-1], n `mod` x == 0]) > 0 = False
| otherwise = True
check :: Integer -> Bool
check n = and [isPrime (stringToInt cs) | cs <- circle (intToString n)]
I am trying to create a program that prints special prime numbers in Haskell
isSpecialPrime :: Integer -> Bool . The function should return if a number is a special prime number or not. A special prime number is a prime number that can be written as the sum of two neighboring prime numbers and 1. An example for a special prime number is 19 = 7 + 11 + 1.
I have managed to check if a number is prime or not here :
isPrime :: Integer -> Bool
isPrime 1 = False
isPrime 2 = True
isPrime n
| (length [x | x <- [2 .. n-1], n `mod` x == 0]) > 0 = False
| otherwise = True
Any ideas to tweak the code to return only the Special Primes
The output put should be something similar to this
> isSpecialPrime 19
True
If you use an aux function, you can do it like:
isPrime :: Integer -> Bool
isPrime 1 = False
isPrime 2 = True
isPrime n
| (length [x | x <- [2 .. n-1], n `mod` x == 0]) > 0 = False
| otherwise = True
isSpecialPrime :: Integer -> Bool
isSpecialPrime 1 = False
isSpecialPrime x =
let firstNeighboring = findNeighbore x in
isSpecialPrime' x firstNeighboring
isSpecialPrime' :: Integer -> Integer -> Bool
isSpecialPrime' _ 0 = False
isSpecialPrime' p x =
let firstNeighboring = findNeighbore x in
let secondNeighboring = findNeighbore firstNeighboring in
if (1 + firstNeighboring + secondNeighboring) == p
then True
else isSpecialPrime' p firstNeighboring
findNeighbore 0 = 0
findNeighbore x = if isPrime (x-1) then x-1 else findNeighbore (x-1)
primes :: [Integer]
primes = sieve (2 : [3, 5..])
where
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
As an example:
filter isSpecialPrime $ take 40 primes
=> [13,19,31,37,43,53,61,79,101,113,139,163,173]
A little optimization:
isSpecialPrime' :: Integer -> Integer -> Bool
isSpecialPrime' _ 1 = False
isSpecialPrime' p x =
let firstNeighboring = findNeighbore x in
let secondNeighboring = findNeighbore firstNeighboring in
let sumNeigh = secondNeighboring + firstNeighboring in
if (p `div` 3) > sumNeigh
then False else
if (1 + sumNeigh) == p
then True
else isSpecialPrime' p firstNeighboring
example:
filter isSpecialPrime $ take 100 primes
=> [13,19,31,37,43,53,61,79,101,113,139,163,173,199,211,223,241,269,277,331,353,373,397,457,463,509,521,541]
I have implemented the following two functions for establishing if n is a fermat prime number (will return n if its true, -1 if not), but it returns always -1, can't figure out why (gc is a funct taht calculates gcd)
fermatPT :: Int -> Int
fermatPT n = fermatPT' n list
where
list = [a | a <- [1..n-1]]
-- | heper function
fermatPT' :: Int -> [Int] -> Int
fermatPT' n l | gc (n, head l) == 1 && fermatTest n (head l) = fermatPT' n (tail l)
| null l = n
| otherwise = -1
where
fermatTest n a = mod (a^(n-1)) n == 1
Your function should return a boolean indicating if the given number is a prime. If you do that, you can use the all function to define this simply as
fermatPT :: Integer -> Bool
fermatPT n = all (fermatTest n) (filter (\a -> gcd n a == 1) [1..n-1])
where fermatTest n a = mod (a^(n-1)) n == 1
gcd is defined in the Prelude.
all avoids the explicit recursion that requires you to apply the test to one element of [1..n-1] at a time; its definition is effectively
all _ [] = True
all p (x:xs) = p x && all p xs
Note that mod (a ^ (n - 1)) n is inefficient, since it may require computing an absurdly large number before ultimately reducing it to the range [0..n-1]. Instead, take advantage of the fact that ab mod n == (a mod n * b mod n) mod n, and reduce the value after each multiplication. One way to implement this (not the fastest, but it's simple):
modN :: Integer -> Integer -> Integer -> Integer
modN a 0 _ = 1
modN a b n = ((a `mod` n) * (modN a (b - 1) n)) `mod` n
Then use
fermatTest n a = modN a (n-1) n == 1
Note that you could use this (with Int instead of Integer) to correctly implement fermatPT :: Int -> Bool; although the input would still be restricted to smaller integers, it won't suffer from overflow.
With gcd its fairly easy but i do not understand how to tie in all the functions to make it happen without.
kgv :: Int -> Int -> Int
kgv x y = abs ((x `quot` (gcd x y)) * y)
I got this function to find the prime factors which works (prime_factors) and I am working on making a function that takes the maximum number from one list and checks if its on the other list (comp):
prime_factors :: Int -> [Int]
prime_factors 1 = []
prime_factors n
| factors == [] = [n]
| otherwise = factors ++ prime_factors (n `div` (head factors))
where factors = take 1 $ filter (\x -> (n `mod` x) == 0) [2 .. n-1]
comp :: [Int]->Int
comp (ys)(x:xs)
|maximum prime_factors xs elem prime_factors ys == x
|otherwise tail x
kgv :: Int -> Int -> Int
kgv x y = abs ((x `quot` (comp x y)) * y)
Here's an absurdly simple and obscenely inefficient solution:
lcm m n = head [x | x <- [1..], x `rem` m == 0, x `rem` n == 0]
Of course, this relies on two different notions of "least" coinciding under the circumstances, which they do. A fully naive solution doesn't seem possible.
here is the (very) naive algorithm I was talking about:
kgv :: (Ord a, Num a) => a -> a -> a
kgv x y = find x y
where find i j
| i == j = i
| i < j = find (i+x) j
| i > j = find i (j+y)
it's basically what a school-child would do ;)
caution I ignored negative numbers and 0 - you'll probably have to handle those
perhaps another easy way is
import Data.List(intersect)
lcm m n = head $ intersect (series m n) (series n m)
where series a b = take a $ map (*b) [1..]
I figured it out myself mostly. Thanks for the ideas and pointers.
ggt n m | n > m = maximum [t | t <- [1 .. m], gt n m t]
| otherwise = maximum [t | t <- [1 .. n], gt n m t]
gt n m c = t n c && t m c
t n c | n >= c = (mod n c == 0)
| otherwise = False
kgv :: Int -> Int -> Int
kgv x y |x==0=0|y==0=0 |otherwise = abs ((x `quot` (ggt x y)) * y)