I'm expecting luhn 5594589764218858 = True but it is always False
-- Get the last digit from a number
lastDigit :: Integer -> Integer
lastDigit 0 = 0
lastDigit n = mod n 10
-- Drop the last digit from a number
dropLastDigit :: Integer -> Integer
dropLastDigit n = div n 10
toRevDigits :: Integer -> [Integer]
toRevDigits n
| n <= 0 = []
| otherwise = lastDigit n : toRevDigits (dropLastDigit n)
-- Double every second number in a list starting on the left.
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x : []) = [x]
doubleEveryOther (x : y : z) = x : (y * 2) : doubleEveryOther z
-- Calculate the sum of all the digits in every Integer.
sumDigits :: [Integer] -> Integer
sumDigits [] = 0
sumDigits (x : []) = x
sumDigits (x : y) = (lastDigit x) + (dropLastDigit x) + sumDigits y
-- Validate a credit card number using the above functions.
luhn :: Integer -> Bool
luhn n
| sumDigits (doubleEveryOther (toRevDigits n)) `div` 10 == 0 = True
| otherwise = False
I know it can be done easier but I'm following a Haskell introductory. I think my only problem is in the luhn function. The course mentions problems may occur because toRevDigits reverses the number but I think it should work anyways.
The snippet x `div` 10 == 0 is not a correct check that x is divisible by ten; you should use `mod` instead. Also, this equation is incorrect:
sumDigits (x : []) = x
(Try, e.g. sumDigits [10].) It can be fixed, but deleting it is simpler and still correct.
Related
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)]
Define a function nohundred :: Int -> Int such that for a positive number n nohundred n is the nth positive number such that "100" does not occur as a substring in its binary expansion.
decToBin :: Int -> [Int]
decToBin x = reverse $ decToBin' x
where
decToBin' :: Int -> [Int]
decToBin' 0 = []
decToBin' y = let (a,b) = quotRem y 2 in [b] ++ decToBin' a
check :: [Int] -> Bool
check (z:zs)
|((z == 1) && (head (zs) == 0) && (head (tail zs) == 0)) = True
| otherwise = check zs
binToDec :: [Int] -> Int
binToDec l = sumlist (zipWith (*) (iterate f 1) (reverse l))
where
sumlist :: [Int] -> Int
sumlist [] = 0
sumlist (x:xs) = x + (sumlist xs)
f :: Int -> Int
f j = (2 * j)
nohundred :: Int -> Int
nohundred n = if ((check fun) == True) then (binToDec (fun)) else (nohundred (n+1))
where
fun = decToBin n
The above code gives error :-
*Main> nohundred 10
*** Exception: Prelude.head: empty list...
The desired output is 14.
*Main> nohundred 100
100
The desired output is 367...
Can anyone suggest the cause of error?
This function is partial:
check (z:zs)
|((z == 1) && (head (zs) == 0) && (head (tail zs) == 0)) = True
| otherwise = check zs
When called with a one- or two-element list, the first check will call head on an empty list. Additionally, it does not cover the empty-list case. The idiomatic way to write this is:
check (1:0:0:zs) = True
check (z:zs) = check zs
check [] = False
Additionally, your nohundred function takes a number and finds the next higher non-hundred number; but you want the nth non-hundred number, which is a very different thing.
The goal is to validate a list of numbers (credit card number for example ) to first initiate it, reverse it, and then double it, and that would give the sum. Then it would tell if it is valid or in-valid. I have written the code but it wont compile right. It keeps saying this: test.hs:22:1: Parse error in pattern: sumNum.
Here is my code:
main = do
toDigits :: Integer -> [Integer]
toDigitsRev :: Integer -> [Integer]
toDigitsRev n
where
n <= 0 = []
otherwise = n `mod` 10 : toDigitsRev (n `div` 10)
toDigits = reverse . toDigitsRev
double :: [Integer] -> [Integer]
double [] = []
double (x:[]) = [x]
double (x:y:zs) = x : (2 * y) : double zs
doubleRev = reverse . double . reverse
sumNum :: [Integer] -> Integer
sumNum [] = 0
sumNum (x:xs)
x < 10 = x + sumNum xs
otherwise = (x `mod` 10) + (x `div` 10) + sum xs
validate :: Integer -> Bool
validate n = (mod (sumNum (doubleRev (toDigits n))) 10) == 0
You forgot the guard bars:
sumNum (x:xs)
| x < 10 = ...
| otherwise = ...
Without the pipe characters, the compiler sees it as sumNum (x:xs) x < 10 = x + sumNum xs, which doesn't make sense as a pattern, since it seems to suggest you have 3 more arguments, namely x, < and 10, although < does not make sense as a name by itself. Alternatively you could just skip the guard altogether, since
> map (`mod` 10) [0..9] == [0..9]
True
> map (`div` 10) [0..9] == replicate 10 0
True
So all you save is a little efficiency. Since you're working with very small inputs you don't really need to worry about this, so you could just use sumNum [] = 0; sumNum (x:xs) = (x `mod` 10) + (x `div` 10) + sum xs, or more simply sumNum = sum . map (\x -> (x `mod` 10) + (x `div` 10)).
I was trying to create a typeclass with a function named primeFib that when called with n, returns the n first primes on the Fibonacci sequence.
Here is my code:
class PrimeirosPrimos x where
primeFib :: x -> [x]
primeFat :: x -> [x]
fib :: x -> x -> x -> [x]
ePrimo :: x -> x -> x -> Bool
instance PrimeirosPrimos Integer where
primeFib n = fib 2 3 n
fib a b 0 = []
fib a b n = if ePrimo a (sqrt a) 2
then [a] ++ fib b (a+b) (n-1)
else fib b (a+b) n
ePrimo a lim num | num>lim = True
| a/num <= 0 = False
| otherwise = ePrimo a lim (num+1)
But when I try to compile it, ghci returns:
qt.hs:11:5: parse error on input 'fib'
Failed, modules loaded: none.
What I'm doing wrong?
I'm solving some classic problems in Haskell to develop my functional
skills and I have a problem to implement an optimization suggested at this "Programming Praxis" site:
I have three solutions to this problem and the third one is too slow
compared to the second solution. Can someone suggest some improvements to
my code?
My implementations are:
-- primeira implementação
primes n
| n < 2 = []
| n == 2 = [2]
| n `mod` 2 == 0 = primes'
| otherwise = if (find (\x -> n `mod` x == 0) primes') == Nothing then
n:primes'
else
primes'
where primes' = primes (n - 1)
-- segunda implementação
primes' :: Integer -> [Integer]
primes' n = sieve $ 2 : [3,5..n]
where sieve :: [Integer] -> [Integer]
sieve [] = []
sieve l#(x:xs)
| x*x >= n = l
| otherwise = x : sieve list'
where list' = filter (\y -> y `mod` x /= 0) xs
-- terceira implementação
primes'' :: Integer -> [Integer]
primes'' n = 2 : sieve 3 [3,5..n]
where sieve :: Integer -> [Integer] -> [Integer]
sieve _ [] = []
sieve m l#(x:xs)
| m*m >= n = l
| x < m*m = x : sieve m xs
| otherwise = sieve (m + 2) list'
where list'= filter (\y -> y `mod` m /= 0) l
Looks to me like the problem with your third revision is how you choose the next element to sift on.
You indiscriminately increment by 2. The problem is that you then sift on unnecessary numbers.
for example, in this version your eventually going to pass 9 as m, and you're going to do an extra recursion to filter on 9, even though it isn't even in the list, and thus you should have never picked it in the first place (since it would have been removed in the very first filter on 3)
Even though the second version doesn't start the filtering past the square of the number it sifts on, it never chooses an unnecessary sifting value.
In other words, I think you end up sifting on every odd number between 3 and n. Instead you should be sifting on every odd number that hasn't already been removed by a previous pass.
I think to correctly implement the optimization of starting the sieve at the square of the current sift value, you have to retain the front of the list while sifting on the back where back contains the elements >= the square of the sift value. I think this would force you to use concatenations, and I'm not so sure that the optimization is good enough to cancel out the overhead induced by using ++.
First of all, mod is slow so use rem in situations where it doesn't matter (when you aren't dealing with negatives, basically). Secondly, use Criterion to show (to yourself) what is faster and what changes are actually optimizations. I know I'm not giving a full answer to you question with this, but its a good place for you (and other potential answerers) to start, so here's some code:
import List
import Criterion.Main
main = do
str <- getLine
let run f = length . f
input = read str :: Integer
defaultMain [ bench "primes" (nf (run primes) input)
, bench "primes'" (nf (run primes') input)
, bench "primes''" (nf (run primes'') input)
, bench "primesTMD" (nf (run primesTMD) input)
, bench "primes'TMD" (nf (run primes'TMD) input)
, bench "primes''TMD" (nf (run primes''TMD) input)
]
putStrLn . show . length . primes'' $ (read str :: Integer)
-- primeira implementação
primes n
| n < 2 = []
| n == 2 = [2]
| n `mod` 2 == 0 = primes'
| otherwise = if (find (\x -> n `mod` x == 0) primes') == Nothing then
n:primes'
else
primes'
where primes' = primes (n - 1)
primesTMD n
| n < 2 = []
| n == 2 = [2]
| n `mod` 2 == 0 = primes'
| otherwise = if (find (\x -> n `rem` x == 0) primes') == Nothing then
n:primes'
else
primes'
where primes' = primesTMD (n - 1)
-- segunda implementação
primes' :: Integer -> [Integer]
primes' n = sieve $ 2 : [3,5..n]
where sieve :: [Integer] -> [Integer]
sieve [] = []
sieve l#(x:xs)
| x*x >= n = l
| otherwise = x : sieve list'
where list' = filter (\y -> y `mod` x /= 0) xs
primes'TMD :: Integer -> [Integer]
primes'TMD n = sieve $ 2 : [3,5..n]
where sieve :: [Integer] -> [Integer]
sieve [] = []
sieve l#(x:xs)
| x*x >= n = l
| otherwise = x : sieve list'
where list' = filter (\y -> y `rem` x /= 0) xs
-- terceira implementação
primes'' :: Integer -> [Integer]
primes'' n = 2 : sieve 3 [3,5..n]
where sieve :: Integer -> [Integer] -> [Integer]
sieve _ [] = []
sieve m l#(x:xs)
| m*m >= n = l
| x < m*m = x : sieve m xs
| otherwise = sieve (m + 2) list'
where list'= filter (\y -> y `mod` m /= 0) l
primes''TMD :: Integer -> [Integer]
primes''TMD n = 2 : sieve 3 [3,5..n]
where sieve :: Integer -> [Integer] -> [Integer]
sieve _ [] = []
sieve m l#(x:xs)
| m*m >= n = l
| x < m*m = x : sieve m xs
| otherwise = sieve (m + 2) list'
where list'= filter (\y -> y `rem` m /= 0) l
Notice the improved runtime of the variants using rem:
$ ghc --make -O2 sieve.hs
$./sieve
5000
...
benchmarking primes
mean: 23.88546 ms, lb 23.84035 ms, ub 23.95000 ms
benchmarking primes'
mean: 775.9981 us, lb 775.4639 us, ub 776.7081 us
benchmarking primes''
mean: 837.7901 us, lb 836.7824 us, ub 839.0260 us
benchmarking primesTMD
mean: 16.15421 ms, lb 16.11955 ms, ub 16.19202 ms
benchmarking primes'TMD
mean: 568.9857 us, lb 568.5819 us, ub 569.4641 us
benchmarking primes''TMD
mean: 642.5665 us, lb 642.0495 us, ub 643.4105 us
While I see you are doing this for your own education, its worth noting the related links of Primes on Haskell.org and the fast Primes package on hackage.
This is not optimized but expressive implementation: check video Sieve of Eratosthenes in haskell
import qualified Data.Set as Set(fromList,difference)
kr n l = (*n) <$> [2..l `div` n]
g n = difference (fromList [2..n]) (fromList $ concat $ ((flip kr) n) <$> [2..n])