Haskell: prime number detector - haskell

I am trying to learn Haskell and I am stuck at a problem with recursion. What i need to do is find wether a number is prime or not. This is my attempt so far. but it does not work. It gives "False" for non prime numbers, but it gets stuck on an infinite loop when the number is prime.
isPrime :: Int -> Bool
isPrime num = primeTest num 2
where
primeTest :: Int -> Int -> Bool
primeTest num x
| x == num = True
| num `mod` x == 0 = False
| otherwise = primeTest num (x + 1)
where
x = 2

You dont need
where
x = 2
This is why it is running into an infinite loop. For example, Consider the input 2, num mod x will return 0, so it will return False. Consider input 5, num mod x will return 1 (since x is 1 in this case). So, it goes to the otherwise part, where primeTest num (x + 1) is called with assigning x = 2. So, always this loop will run infinitely, with the x value 3.

The where x=2 at the end causes every instance of x after primeTest num x to be 2, regardless of the value that was passed to primeTest in the x "slot." Get rid of the where x=2.

Related

Haskell - show function cuts the first element zero from the Int-Value - how to avoid it?

I have the following exercise:
I need do write a function which checks if the entered Int-value is >= 4 and <= 6 and does not start with 0. Then the function should give back a True.
This is the function I have to implement: (pinCheck :: Int -> Bool is given)
pinCheck :: Int -> Bool
pinCheck x
| (( last (ab)) /= '0' ) && len <= 6 && len >= 4 = True
| otherwise = False
where
len = length (digs x)
ab = reverse (show x)
digs :: Integral x => x -> [x]
digs 0 = []
digs x = digs (x `div`10) ++ [x `mod` 10]
I have to check a testcase with the given Int-value 0323. It has to give out false, but it gives out true.
I wanted to convert the Int to a String and then check with head if the first value is /= 0. But while converting, it cuts off the 0 automatically.
I didn't know that the show function did that, so I wanted first to reverse the converted string and then check the last element if it is /= 0 but...
Now my question: Is it with my fundamental program code possible to solve this problem?
No, it is not possible. If you want to preserve presentational details about the number, have pinCheck take a String instead of an Int.

List with numbers, whose digits are only 2, 4, 6

The task is to generate list with numbers, whose digits are only 2,4,6.
Example:[2,4,6,22,24,26,42,44,46,62,64,66,222,224,226,...]
I have already solved this task via brute force:
numberHasOnly246 :: Integer -> Bool
numberHasOnly246 0 = False
numberHasOnly246 n = result
where
result = helper True (abs n)
helper :: Bool -> Integer -> Bool
helper result n
| (div n 10 == 0) = condition && result
| (div n 10 > 0) = helper (condition && result) (div n 10)
where
condition = mod n 10 == 4 || mod n 10 == 6 || mod n 10 == 2
series246 :: [Integer]
series246 = numbers[1..]
where
numbers(e : ls) = e : (numbers [ x | x <- ls, (numberHasOnly246 x == True)])
But it seems that this solution is too slow.
Also, I've read, that there is tying the knot method for generating infinite lists in Haskell, but here I cannot find how to solve it via tying the knot. Is this method suitable here?
Instead of a generate-and-test approach, you can only generate numbers that are valid.
For a single digit this is thus:
digits :: [Int]
digits = [2, 4, 6]
for numbers, we can make use of recursion here:
numbers = [ 10*t + d | t <- (0:numbers), d <- digits ]
Here t is thus the values we multiply with 10, and we start with 0. d are the digits that we then can append. This thus gives us:
Prelude> numbers
[2,4,6,22,24,26,42,44,46,62,64,66,222,224,226,242,244,246,262,264,266,422,424,426,442, …

Haskell function that return the next prime number after given n

Learning Haskell. Trying to write a function called nextPrime n that will return the next prime number after n.
I have the following:
-- Generate a list of all factors of n
factors :: Integral a => a -> [a]
factors n = [x | x <- [1..n], n `mod` x == 0]
-- True iff n is prime
isPrime :: Integral a => a -> Bool
isPrime n = factors n == [1, n]
So far the function is set up like so:
nextPrime :: Integral a => a -> a
nextPrime n =
I presume I have to do a sort of while loop maybe but not sure how. I am totally new to functional programming. Any help is appreciated
I assumed that nextPrime n means "get me the first prime number that's greater than n".
Here's an idea:
nextPrime :: Integral a => a -> a
nextPrime n = nextPrime' (n + 1)
where nextPrime' m = ...
You want to fill in the blanks for nextPrime'. Here's a hint:
fun n = if n <= 0
then 0
else n + fun (n - 1)
This is a recursive function that calculates the sum 1 + 2 + 3 + ... + n, though it does it starting with n and going down from there. nextPrime' will have to go up.

Recursive function to find if a number is prime or not

I need to implement a recursive function that returns 1 if the number is prime or 0 otherwise. The homework problem says that I can't use '%' mod. Haskell should be something like this... I'm not sure.
isprime x = prime(x sqrt(x))
prime x i = | i==1 = 1
| mod(x i)==0 = 0
| otherwise = prime(x i-1)
mod num div | num<div = n
| otherwise = mod(num-div div)
I tested an algorithm in C because I don't have a Haskell compiler on my Mac, but there's something wrong because it's returning false positive on primes-1. idk why.
int main (int argc, const char * argv[]){
int a=0,b=31;
printf("\n Prime numbers between %d and %d \n",a,b);
for(int a=0; a<=b; a++){
if(isPrime(a)==0){
printf("%d, ",a);
}
}
return 0;
}
int isPrime(int x){
return prime(x, sqrt(x));
}
int prime(int x, int i){
if(i==0){
return 0;
}
else if(mod(x,i)==1){
return 1;
}
else{
return prime(x, i-1);
}
}
int mod(int num, int div){
if(num<div) return num;
else return mod(num-div, div);
}
The algorithm is returning this:
Prime numbers between 0 and 31
0, 1, 2, 3, 4, 6, 8, 12, 14, 18, 20, 24, 30,
Program ended with exit code: 0
Your basic idea is fine. In Haskell you can use lists instead of iteration. Here's what you need to look into:
Install and play with ghci.
If you have no idea how to do anything in Haskell, visit Learn You a Haskell for Great Good http://learnyouahaskell.com/
List comprehensions. Lean what [n^2 | n <- [1..10]] means and play with similar lists.
Look up functions like sqrt on hoogle http://www.haskell.org/hoogle/
Because Haskell is statically typed you will need to convert some numerical types between Integer and Float. Look up Float -> Integer and Integer -> Float when you do. DON'T use unsafeCoerce - it's unsafe and will break things badly.
Use hoogle to look up [Bool] -> Bool. Why did I suggest that? How would [Bool] help, and how would you make one anyway? (Revise list comprehension again.)
Come back with more specific questions once you've found out more and had a go.
Always start your assignments early, especially if you've missed classes!
You were set this homework not because the department was stuck for a way of deciding whether 102659473841923461 is prime, but because they want you to learn some Haskell. Try not to try to solve the problem without doing the learning - it'll only make the next assignment even harder! (This is why I've resisted the temptation to translate the "pseudocode" in another answer into Haskell.)
(apparently, there's a new policy regarding homework, viz. "If you don't want a fully vetted, complete and testable answer, Stack Overflow is not the place to ask - by Tim Post", so here goes).
Basically, your code is almost correct (1 is not a prime), sans some syntax issues.
isprime x = prime x (floor $ sqrt $ fromIntegral x) where
prime x i | i==1 && x > 1 = 1
| x == i*div x i = 0
| otherwise = prime x (i-1)
-- mod x i = x - i*div x i
-- mod x i == 0 = x == i*div x i
fromIntegral is just some adaptor which lets us use an Integral value as an argument to sqrt which expects a Floating argument. Try using :i sqrt or :i Integral etc. at the GHCi prompt (also read some documentation google around).
But algorithmically there's place for improvement. First of all, it's much better to try out the divisors in the other direction, from 2 up to the number's sqrt, because any given number is more likely to have a smaller factor than a larger one. Second, after trying out 2, there's no need to try out any other even number as a possible divisor. This gives us
isprime x | x == 2 = 1
| x < 2 || even x = 0
| otherwise = go 3
where
r = floor $ sqrt $ fromIntegral x
go i | i > r = 1
| x == i*div x i = 0 -- really, | rem x i == 0 = 0
| otherwise = go (i+2)
This would normally be written down using Bools, and a higher-order function like and which captures the recursions and testing pattern (so it is not recursive anymore):
isprime x = if isPrime x then 1 else 0
isPrime x = x==2 || x>2 && odd x &&
and [rem x d /= 0 | d <- [3,5..floor $ sqrt $ fromIntegral x]]
There's some redundancy in there still: after we've tested by 3, there's no need to test by any of its multiples too (just like we did with 2 and evens). We really just need to test by prime factors:
isPrime x = x>1 && and
[rem x d /= 0 | d <- takeWhile (<= (floor $ sqrt $ fromIntegral x)) primes]
primes = filter isPrime [2..]
= 2 : filter isPrime ([3..] `minus` [4,6..])
= 2 : filter isPrime [3,5..]
= 2 : 3 : filter isPrime ([5,7..] `minus` [9,15..])
= 2 : 3 : 5 : filter isPrime (([7,9..]`minus`[9,15..])`minus`[25,35..])
...........
Here we see the emergence of the sieve of Eratosthenes, P = {3,5, ...} \ U {{p2, p2 + 2p, ...} | p in P} (w/out the 2).
see also:
http://en.wikipedia.org/wiki/Haskell_features#Prime_numbers
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
http://www.haskell.org/haskellwiki/Prime_numbers
I don't know Haskell, and I don't want to hand you the answer, but I can offer a method.
if you check all the numbers from 2 to sqrt(n), and none of them are factors of n, then n is prime.
So maybe a function call with the following pseudo code might work:
def isPrime(n):
return isPrimeHelper(n,sqrt(n))
def isPrimeHelper(n,counter):
if counter == 1 return True
if n % counter == 0 return False
else return isPrime(n,counter-1)

How to recursively compare the digits in a number in Haskell

I am doing problem 112 on Project Euler and came up with the following to test the example case (I'll change the number in answer to 0.99 to get the real answer):
isIncre x | x == 99 = False
| otherwise = isIncre' x
where
isIncre' x = ???
isDecre x = isIncre (read $ reverse $ show x :: Int)
isBouncy x = (isIncre x == False) && (isDecre x == False)
bouncers x = length [n|n<-[1..x],isBouncy n]
nonBouncers x = length [n|n<-[1..x],(isBouncy n) == False]
answer = head [x|x<-[1..],((bouncers x) / (nonBouncers x)) == 0.5]
But what I don't know how to do is define a function isIncre' which tests to see if the digits in a number are greater than or equal to the one on their left. I know it needs to be done recursively but how?
On a side note, I know I can only use / on two floating point numbers but how can I make the output of bouncers to be floating point number instead of an integer?
Edit:
Thanks for the help, but it didn't like the = when I changed isIncre to:
isIncre x | x <= 99 = False
| otherwise = isIncre' (mshow x)
where
isIncre' (x:y:xs) = (x <= y) && (isIncre' (y:xs))
isIncre' _ = True
The number 0.99 cannot be represented exactly in base 2. Hence you may want to avoid the use of floating point numbers for this assignment. Instead, to see whether exactly 99% of the numbers <= x are bouncers, test whether
100 * (x - bouncers x) == x
This works because it is (mathematically) the same as (x - bouncers x) == x / 100, which is true if (x - bouncers x) (the number of non-bouncy numbers) is 1% of x. Observe that there is thus no need to define nonBouncers.
Also, another way to define bouncers is
bouncers x = length $ filter isBouncy [1..x]
However, you should reconsider your design. Currently you are recalculating the number of bouncy numbers up to x, for every x that you try. So a lot of work is being done over and over. What you may instead want to do, is generate a sequence of tuples (x, n), where n is the number of bouncy numbers <= x. Observe that if there are n bouncy numbers <= x, then there are either n or n + 1 bouncy number <= x + 1.
More specifically, to calculate (x + 1, n'), all you need is (x, n) and the output of isbouncy (x + 1).
If you have a string representation of an integer number, you could write the isIncre function like this (ord converts a character to an integer and string is just a list of chars):
isIncre (x:y:xs) = ord x <= ord y && isIncre (y:xs)
isIncre _ = True
It could be even nicer to write the isIncre function without ord, working on any ordered type, then combine it with "map ord" when you call it instead. The implementation would then be just:
isIncre (x:y:xs) = x <= y && isIncre (y:xs)
isIncre _ = True
That could be called like this, if x is an integer number
isIncre (map ord (show x))
I would use really nice functional version of isIncre if you have string representation of intetger.
isIncre :: (Ord a) => [a] -> Bool
isIncre list = and $ zipWith (<=) list (tail list)
If not, just compose it with show.
isIncreNum :: Integer -> Bool
isIncreNum = isIncre . show

Resources