Haskell about how to separate the last number from a string number - haskell

I have a question about haskell in seperation the last number from a string number. For example, input is (1234), output is (123,4)
I have done a programming, but it does not work.
toDigits :: Int -> [Int]
toDigits n
| n <= 0 = []
| otherwise = toDigits(n `mod` 10) ++ [n `div` 10]

You just have div and mod swapped.
toDigits n | n <= 0 = []
| otherwise = toDigits (n `div` 10) ++ [n `mod` 10]

Related

Convert to binary notation in Haskell

Is there a better way to check n and c in this code, maybe with pattern matching or something more Haskell-like?
toBin :: Int -> Int -> [Int]
toBin n c
| n < 0 = []
| c <= 0 = []
toBin n c = toBin (n `div` 2) (c - 1) ++ [n `mod` 2]
Well, they're both boolean expressions, so you can combine them with ||
toBin n c | n < 0 || c <= 0 = []
It is better here to work with an accumulator, which prevents making O(n) appends that result in an O(n2) algorithm in your code:
toBin :: Int -> Int -> [Int]
toBin = go []
where go rs n c
| n < 0 || c <= 0 = rs
| otherwise = go (r:rs) q (c-1)
where (q,r) = quotRem n 2
We here thus start with an empty list, and each time prepend the list with the next remainder until the number is zero, or the number of bits is 0.

haskell list comprehension non termination

I have code:
import Data.List
triangles :: [Int]
triangles = takeWhile (\n -> factors n /= 0) [n * (n + 1) `div` 2 | n <- [1..]]
triangles' = takeWhile (/= 0) [n * (n + 1) `div` 2 | n <- [1..]]
intSqrt :: Int -> Int
intSqrt = floor . sqrt . fromIntegral
factors :: Int -> Int
factors n = 2 * length facs
where facs = takeWhile (<= intSqrt n) [x | x <- [1..], n `mod` x == 0]
triangles' prints a ton of numbers instantly, whereas triangles gets stuck before printing anything at all. I saw a similar problem which was caused by infinite mutual recursion, but I don't think I've introduced any recursion here.
The problem is that factors 1 doesn't terminate. The takeWhile looks at the input until it finds a factor greater than intSqrt 1, but there are no such factors.
You could simplify the list comprehension to avoid the takeWhile altogether:
facs = [x | x <- [1..intSqrt n], n `mod` x == 0]

What is the "Parse error in pattern" in my Credit Card Validation written in Haskell?

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)).

Prime factors in Haskell

I'm new to Haskell.
How to generate a list of lists which contains prime factors of next integers?
Currently, I only know how to generate prime numbers:
primes = map head $ iterate (\(x:xs) -> [y | y<-xs, y `mod` x /= 0 ]) [2..]
A simple approach to determine the prime factors of n is to
search for the first divisor d in [2..n-1]
if D exists: return d : primeFactors(div n d)
otherwise return n (since n is prime)
Code:
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]
This obviously could use a lot of optimization (search only from 2 to sqrt(N), cache the prime numbers found so far and compute the division only for these etc.)
UPDATE
A slightly modified version using case (as suggested by #user5402):
prime_factors n =
case factors of
[] -> [n]
_ -> factors ++ prime_factors (n `div` (head factors))
where factors = take 1 $ filter (\x -> (n `mod` x) == 0) [2 .. n-1]
Until the dividend m < 2,
take the first divisor n from primes.
repeat dividing m by n while divisible.
take the next divisor n from primes, and go to 2.
The list of all divisors actually used are prime factors of original m.
Code:
-- | prime factors
--
-- >>> factors 13
-- [13]
-- >>> factors 16
-- [2,2,2,2]
-- >>> factors 60
-- [2,2,3,5]
--
factors :: Int -> [Int]
factors m = f m (head primes) (tail primes) where
f m n ns
| m < 2 = []
| m `mod` n == 0 = n : f (m `div` n) n ns
| otherwise = f m (head ns) (tail ns)
-- | primes
--
-- >>> take 10 primes
-- [2,3,5,7,11,13,17,19,23,29]
--
primes :: [Int]
primes = f [2..] where f (p : ns) = p : f [n | n <- ns, n `mod` p /= 0]
Update:
This replacement code improves performance by avoiding unnecessary evaluations:
factors m = f m (head primes) (tail primes) where
f m n ns
| m < 2 = []
| m < n ^ 2 = [m] -- stop early
| m `mod` n == 0 = n : f (m `div` n) n ns
| otherwise = f m (head ns) (tail ns)
primes can also be sped up drastically, as mentioned in Will Ness's comment:
primes = 2 : filter (\n-> head (factors n) == n) [3,5..]
This is a good-performanced and easy-to-understand implementation, in which isPrime and primes are defined recursively, and primes will be cached by default. primeFactors definition is just a proper use of primes, the result will contains continuous-duplicated numbers, this feature makes it easy to count the number of each factor via (map (head &&& length) . group) and it's easy to unique it via (map head . group) :
isPrime :: Int -> Bool
primes :: [Int]
isPrime n | n < 2 = False
isPrime n = all (\p -> n `mod` p /= 0) . takeWhile ((<= n) . (^ 2)) $ primes
primes = 2 : filter isPrime [3..]
primeFactors :: Int -> [Int]
primeFactors n = iter n primes where
iter n (p:_) | n < p^2 = [n | n > 1]
iter n ps#(p:ps') =
let (d, r) = n `divMod` p
in if r == 0 then p : iter d ps else iter n ps'
And the usage:
> import Data.List
> import Control.Arrow
> primeFactors 12312
[2,2,2,3,3,3,3,19]
> (map (head &&& length) . group) (primeFactors 12312)
[(2,3),(3,4),(19,1)]
> (map head . group) (primeFactors 12312)
[2,3,19]
Haskell allows you to create infinite lists, that are mutually recursive. Let's take an advantage of this.
First let's create a helper function that divides a number by another as much as possible. We'll need it, once we find a factor, to completely eliminate it from a number.
import Data.Maybe (mapMaybe)
-- Divide the first argument as many times as possible by the second one.
divFully :: Integer -> Integer -> Integer
divFully n q | n `mod` q == 0 = divFully (n `div` q) q
| otherwise = n
Next, assuming we have somewhere the list of all primes, we can easily find factors of a numbers by dividing it by all primes less than the square root of the number, and if the number is divisible, noting the prime number.
-- | A lazy infinite list of non-trivial factors of all numbers.
factors :: [(Integer, [Integer])]
factors = (1, []) : (2, [2]) : map (\n -> (n, divisors primes n)) [3..]
where
divisors :: [Integer] -> Integer -> [Integer]
divisors _ 1 = [] -- no more divisors
divisors (p:ps) n
| p^2 > n = [n] -- no more divisors, `n` must be prime
| n' < n = p : divisors ps n' -- divides
| otherwise = divisors ps n' -- doesn't divide
where
n' = divFully n p
Conversely, when we have the list of all factors of numbers, it's easy to find primes: They are exactly those numbers, whose only prime factor is the number itself.
-- | A lazy infinite list of primes.
primes :: [Integer]
primes = mapMaybe isPrime factors
where
-- | A number is prime if it's only prime factor is the number itself.
isPrime (n, [p]) | n == p = Just p
isPrime _ = Nothing
The trick is that we start the list of factors manually, and that to determine the list of prime factors of a number we only need primes less then its square root. Let's see what happens when we consume the list of factors a bit and we're trying to compute the list of factors of 3. We're consuming the list of primes, taking 2 (which can be computed from what we've given manually). We see that it doesn't divide 3 and that since it's greater than the square root of 3, there are no more possible divisors of 3. Therefore the list of factors for 3 is [3]. From this, we can compute that 3 is another prime. Etc.
I just worked on this problem. Here's my solution.
Two helping functions are
factors n = [x | x <- [1..n], mod n x == 0]
isPrime n = factors n == [1,n]
Then using a list comprehension to get all prime factors and how many are they.
prime_factors num = [(last $ takeWhile (\n -> (x^n) `elem` (factors num)) [1..], x) | x <- filter isPrime $ factors num]
where
x <- filter isPrime $ factors num
tells me what prime factors the given number has, and
last $ takeWhile (\n -> (x^n) `elem` (factors num)) [1..]
tells me how many this factor is.
Examples
> prime_factors 36 -- 36 = 4 * 9
[(2,2),(2,3)]
> prime_factors 1800 -- 1800 = 8 * 9 * 25
[(3,2),(2,3),(2,5)]
More elegant codeļ¼Œuse 2 and odd numbers to divide the number.
factors' :: Integral t => t -> [t]
factors' n
| n < 0 = factors' (-n)
| n > 0 = if 1 == n
then []
else let fac = mfac n 2 in fac : factors' (n `div` fac)
where mfac m x
| rem m x == 0 = x
| x * x > m = m
| otherwise = mfac m (if odd x then x + 2 else x + 1)
Here's my version. Not as concise as the others, but I think it's very readable and easy to understand.
import Data.List
factor :: Int -> [Int]
factor n
| n <= 1 = []
| even n = 2 : factor(div n 2)
| otherwise =
let root = floor $ sqrt $ fromIntegral n
in
case find ((==) 0 . mod n) [3, 5.. root] of
Nothing -> [n]
Just fac -> fac : factor(div n fac)
I'm sure this code is ugly enough to drive a real Haskell programmer to tears, but it works in GHCI 9.0.1 to provide prime factors with a count of each prime factor.
import Data.List
factors n = [x | x <- [2..(n`div` 2)], mod n x == 0] ++ [n]
factormap n = fmap factors $ factors n
isPrime n = case factormap n of [a] -> True; _ -> False
primeList (x:xs) = filter (isPrime) (x:xs)
numPrimes n a = length $ (factors n) `intersect` (takeWhile ( <=n) $ iterate (a*) a)
primeFactors n = primeList $ factors n
result1 n = fmap (numPrimes n) (primeFactors n)
answer n = ((primeFactors n),(result1 n))
Example:
ghci> answer 504
([2,3,7],[3,2,1])
The answer is a list of prime factors and a second list showing how many times each
prime factor is in the submitted number.

Haskell. Numbers in binary numbers. words

import Data.Char
blockCode :: S
lett2num :: Char -> Int
lett2num y
| (or
num2bin :: Int -> [Int]
num2bin n: negative number"
where n2b 0 = []
n2b n = n `mod` 2 : n2b (n `div` 2)
You can use concatMap show to transform a list into a string:
Main> num2bin 8
[0,0,0,1]
Main> concatMap show $ num2bin 8
"0001"
but note that your function's output is reversed.
To do everything in one go, do
num2bin :: Int -> String
num2bin n
| n >= 0 = concatMap show $ reverse $ n2b n
| otherwise = error "num2bin: negative number"
where n2b 0 = []
n2b n = n `mod` 2 : n2b (n `div` 2)
Function converts integer to binary:
num2bin :: (Integral a, Show a) => a -> String
num2bin 0 = "0"
num2bin 1 = "1"
num2bin n
| n < 0 = error "Negative number"
| otherwise = num2bin (n `div` 2) ++ show (n `mod` 2)

Resources