Related
Given an arbitrary number, how can I process each digit of the number individually?
Edit
I've added a basic example of the kind of thing Foo might do.
For example, in C# I might do something like this:
static void Main(string[] args)
{
int number = 1234567890;
string numberAsString = number.ToString();
foreach(char x in numberAsString)
{
string y = x.ToString();
int z = int.Parse(y);
Foo(z);
}
}
void Foo(int n)
{
Console.WriteLine(n*n);
}
Have you heard of div and mod?
You'll probably want to reverse the list of numbers if you want to treat the most significant digit first. Converting the number into a string is an impaired way of doing things.
135 `div` 10 = 13
135 `mod` 10 = 5
Generalize into a function:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = digs (x `div` 10) ++ [x `mod` 10]
Or in reverse:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = x `mod` 10 : digs (x `div` 10)
This treats 0 as having no digits. A simple wrapper function can deal with that special case if you want to.
Note that this solution does not work for negative numbers (the input x must be integral, i.e. a whole number).
digits :: Integer -> [Int]
digits = map (read . (:[])) . show
or you can return it into []:
digits :: Integer -> [Int]
digits = map (read . return) . show
or, with Data.Char.digitToInt:
digits :: Integer -> [Int]
digits = map digitToInt . show
the same as Daniel's really, but point free and uses Int, because a digit shouldn't really exceed maxBound :: Int.
Using the same technique used in your post, you can do:
digits :: Integer -> [Int]
digits n = map (\x -> read [x] :: Int) (show n)
See it in action:
Prelude> digits 123
[1,2,3]
Does that help?
You could also just reuse digits from Hackage.
Textbook unfold
import qualified Data.List as L
digits = reverse . L.unfoldr (\x -> if x == 0 then Nothing else Just (mod x 10, div x 10))
You can use
digits = map (`mod` 10) . reverse . takeWhile (> 0) . iterate (`div` 10)
or for reverse order
rev_digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)
The iterate part generates an infinite list dividing the argument in every step by 10, so 12345 becomes [12345,1234,123,12,1,0,0..]. The takeWhile part takes only the interesting non-null part of the list. Then we reverse (if we want to) and take the last digit of each number of the list.
I used point-free style here, so you can imagine an invisible argument n on both sides of the "equation". However, if you want to write it that way, you have to substitute the top level . by $:
digits n = map(`mod` 10) $ reverse $ takeWhile (> 0) $ iterate (`div`10) n
Via list comprehension:
import Data.Char
digits :: Integer -> [Integer]
digits n = [toInteger (digitToInt x) | x <- show n]
output:
> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
I was lazy to write my custom function so I googled it and tbh I was surprised that none of the answers on this website provided a really good solution – high performance and type safe. So here it is, maybe somebody would like to use it. Basically:
It is type safe - it returns a type checked non-empty list of Word8 digits (all the above solutions return a list of numbers, but it cannot happen that we get [] right?)
This one is performance optimized with tail call optimization, fast concatenation and no need to do any reversing of the final values.
It uses special assignment syntax which in connection to -XStrict allows Haskell to fully do strictness analysis and optimize the inner loop.
Enjoy:
{-# LANGUAGE Strict #-}
digits :: Integral a => a -> NonEmpty Word8
digits = go [] where
go s x = loop (head :| s) tail where
head = fromIntegral (x `mod` 10)
tail = x `div` 10
loop s#(r :| rs) = \case
0 -> s
x -> go (r : rs) x
Here's an improvement on an answer above. This avoids the extra 0 at the beginning ( Examples: [0,1,0] for 10, [0,1] for 1 ). Use pattern matching to handle cases where x < 10 differently:
toDigits :: Integer -> [Integer] -- 12 -> [1,2], 0 -> [0], 10 -> [1,0]
toDigits x
| x < 10 = [x]
| otherwise = toDigits (div x 10) ++ [mod x 10]
I would have put this in a reply to that answer, but I don't have the needed reputation points :(
Applicative. Pointfree. Origami. Neat.
Enjoy:
import Data.List
import Data.Tuple
import Data.Bool
import Control.Applicative
digits = unfoldr $ liftA2 (bool Nothing) (Just . swap . (`divMod` 10)) (> 0)
I've been following next steps(based on this comment):
Convert the integer to a string.
Iterate over the string
character-by-character.
Convert each character back to an integer,
while appending it to the end of a list.
toDigits :: Integer -> [Integer]
toDigits a = [(read([m])::Integer) | m<-show(a)]
main = print(toDigits(1234))
For returning a list of [Integer]
import Data.Char
toDigits :: Integer -> [Integer]
toDigits n = map (\x -> toInteger (digitToInt x)) (show n)
The accepted answer is great but fails in cases of negative numbers since mod (-1) 10 evaluates to 9. If you would like this to handle negative numbers properly... which may not be the case the following code will allow for it.
digs :: Int -> [Int]
digs 0 = []
digs x
| x < 0 = digs ((-1) * x)
| x > 0 = digs (div x 10) ++ [mod x 10]
The accepted answer is correct except that it will output an empty list when input is 0, however I believe the output should be [0] when input is zero.
And I don't think it deal with the case when the input is negative. Below is my implementation, which solves the above two problems.
toDigits :: Integer -> [Integer]
toDigits n
| n >=0 && n < 10 = [n]
| n >= 10 = toDigits (n`div`10) ++ [n`mod`10]
| otherwise = error "make sure your input is greater than 0"
I would like to improve upon the answer of Dave Clarke in this page. It boils down to using div and mod on a number and adding their results to a list, only this time it won't appear reversed, nor resort to ++ (which is slower concatenation).
toDigits :: Integer -> [Integer]
toDigits n
| n <= 0 = []
| otherwise = numToDigits (n `mod` 10) (n `div` 10) []
where
numToDigits a 0 l = (a:l)
numToDigits a b l = numToDigits (b `mod` 10) (b `div` 10) (a:l)
This program was a solution to a problem in the CIS 194 course at UPenn that is available right here. You divide the number to find its result as an integer and the remainder as another. You pass them to a function whose third argument is an empty list. The remainder will be added to the list in case the result of division is 0. The function will be called again in case it's another number. The remainders will add in order until the end.
Note: this is for numbers, which means that zeros to the left won't count, and it will allow you to have their digits for further manipulation.
digits = reverse . unfoldr go
where go = uncurry (*>) . (&&&) (guard . (>0)) (Just . swap . (`quotRem` 10))
I tried to keep using tail recursion
toDigits :: Integer -> [Integer]
toDigits x = reverse $ toDigitsRev x
toDigitsRev :: Integer -> [Integer]
toDigitsRev x
| x <= 0 = []
| otherwise = x `rem` 10 : toDigitsRev (x `quot` 10)
So I spent the last hour or so trying to write up an effecient haskell function that checks if a number is prime or not. I came up with this algorithm that I'm rather happy with:
prime :: Int -> Bool
prime x
| x == 1 = False
| x == 2 = True
| x == 3 = True
| x `mod` 2 == 0 = False
| x `mod` 3 == 0 = False
| otherwise = all (\y -> x `mod` y /= 0) $ dividends x
where
dividends z =
takeWhile ((<=) . floor . sqrt . fromIntegral $ z)
$ concatMap (\x -> [x-1, x+1]) [6 * x | x <- [1..]]
I also uploaded a notebook that checks the run time of the algorithm and compares it to the sieve method in case anyone is interested that is here: https://anaconda.org/freemo/primes/notebook
My question is, as someone new to haskell how can I make this algorithm more idomatic. I have a feeling the anonymous functions I used can be eliminated, and there are probably other ways I can make it more concise without having a negative effect on the run time. How can I write this in an more idiomatic haskell way?
The thing I'd consider most unidiomatic here are the equality comparisons. In Haskell, we generally prefer pattern matching, which you can directly apply to the first three cases:
prime 1 = False
prime 2 = True
prime 3 = True
prime x
| ...
(The difference is cosmetic in this example, but often pattern matching makes code much safer, more succinct and sometimes also significantly more performant.)
Next, you're using both a list comprehension and concatMap. Both constructs do largely the same thing, and are equivalent to monadic binds. But a) it's usually benefitial to use only one of these syntaxes in a place, b) monad is actually stronger than necessary: applicative will do as well, and can be written quite nicely here.
import Control.Applicative
...
(6*) <$> [1..] <**> [pred, succ]
Then, I find this ((<=) . floor . sqrt . fromIntegral $ z) awkward. More natural would be in flipped form:
takeWhile (>= floor (sqrt $ fromIntegral z)) ...
...but generally speaking, better yet is to avoid the square root entirely:
takeWhile ((>=z) . (^2)) ...
The reason being, square-root is pretty expensive and has floating-point inaccuracies, so it's often better to square the other side of the equation instead. Unfortunately, this is actually not reliable here, because the squaring might lead to Int overflows, and Integer would make the performance probably worse than with float-sqrt, because it's done for every element of the list rather than just once. So, a square-root is actually sensible here.
The dividends function is actually superfluous since you only ever call it with x as the argument. (It might be argued that it's sensible to still give this a name, but at any rate you don't need to give it an argument.)
The predicate for the all is something I would consider making point-free.
Final version would then be:
prime :: Int -> Bool
prime 1 = False
prime 2 = True
prime 3 = True
prime x
| x `mod` 2 == 0 = False
| x `mod` 3 == 0 = False
| otherwise = all ((/= 0) . (x`mod`))
. takeWhile (>= floor (sqrt $ fromIntegral x))
$ (6*) <$> [1..]
<**> [pred, succ]
So I modified #leftaroundabout 's answer slightly and am using this. Just putting it up here in case anyone winds up using it.
import Control.Applicative
prime'' :: Int -> Bool
prime'' 1 = False
prime'' 2 = True
prime'' 3 = True
prime'' x
| x `mod` 2 == 0 = False
| x `mod` 3 == 0 = False
| otherwise = all
-- check if x is not divisibile by the divisors
((/= 0) . (x `mod`))
-- only take divisors less than or equal to sqrt(x)
. takeWhile (<=(floor . sqrt . fromIntegral $ x))
-- generate divisors as an infinite list 6n +/- 1
$ [6,12..] <**> [(-1+), (1+)]
I already have the following functions
toBin, auxBin :: Integer -> [Integer]
toBin 0 = [0]
toBin n = reverse (auxBin n)
auxBin 0 = []
auxBin n = n `mod` 2 : auxBin (n `div` 2)
fib :: Int -> Integer
fib n = fibs !! n
where
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci = [fib n | n <- [0..]]
But when I map the Fibonacci list with the toBin function, I obtained an incorrect list:
Becuase, I obtained this:
[[0],[1],[1],[1,0],[1,1],[1,0,1],[1,0,0,0],[1,1,0,1],[1,0,1,0,1],[1,0,0,0,1,0]]
But, I want this:
[0,1,10,101,1010,10101,101010,1010101,10101010,101010101]
Could you help me?
There are many ways to add digits together in order to get a number. Here's one way. Probably not the most efficient way, but on the other hand built up from smaller functions.
Values like [1,0,1],[1,0,0,0], and [1,1,0,1] are lists in their own right, so what we can do first is to index them. The only trouble is that we'd like to index them in descending order. You can do that by reversing them, indexing them, and then reverse them again, e.g.:
Prelude> reverse $ zip [0..] $ reverse [1,1,0,1]
[(3,1),(2,1),(1,0),(0,1)]
The first element in each tuple is the order of magnitude, so you just need to make it a power of ten:
Prelude> :m +Data.Bifunctor
Prelude Data.Bifunctor> reverse $ fmap (first (10 ^)) $ zip [0..] $ reverse [1,1,0,1]
[(1000,1),(100,1),(10,0),(1,1)]
Now you can simply multiply the elements of the tuples together:
Prelude Data.Bifunctor> reverse $ fmap (uncurry (*) . first (10 ^)) $ zip [0..] $ reverse [1,1,0,1]
[1000,100,0,1]
Finally, you can add all of those numbers together. In fact, you don't need to reverse the reversed list:
Prelude Data.Bifunctor> sum $ fmap (uncurry (*) . first (10 ^)) $ zip [0..] $ reverse [1,1,0,1]
1101
You can put such a combination in a function and map your values over it.
A more efficient solution would probably be to just be to do a left fold (foldl), e.g.:
Prelude> foldl (\acc x -> (10 * acc) + x) 0 [1,1,0,1]
1101
Prelude> foldl (\acc x -> (10 * acc) + x) 0 [1,1,1]
111
An idea could be to represent binary values in decimal notation. So we "transform" 2 into 10.
We can do that by writing a recursive function:
bintodec :: Integral i => i -> i
bintodec 0 = 0
bintodec i = (mod i 2) + 10 * bintodec (div i 2)
This only works for positive values, but that is not really a problem here, since Fibonacci numbers are positive numbers.
Now we already have a definition of the Fibonacci numbers, like in your answer:
fibs :: Num n => [n]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
So the only thing we still have to do is map every elements of fibs with bintodec:
binfibs :: Integral i => [i]
binfibs = map bintodec fibs
The first 15 numbers are then:
Prelude> take 15 binfibs
[0,1,1,10,11,101,1000,1101,10101,100010,110111,1011001,10010000,11101001,101111001]
The nice thing is here that we do not use any binary lists to process it, but keep working in the integer world, which is usually more safe.
Based on the second list however, this has nothing to do with Fibonacci numbers. There you start with 0, and you then shift a zero or a one in at the right end of the number.
We can use iterate for this:
iterate (\x -> 10 * x + 1-(mod x 2)) 0
which produces:
Prelude> take 15 $ iterate (\x -> 10 * x + 1-(mod x 2)) 0
[0,1,10,101,1010,10101,101010,1010101,10101010,101010101,1010101010,10101010101,101010101010,1010101010101,10101010101010]
I'm currently stuck on setting upper limits in list comprehensions.
What I'm trying to do is to find all Fibonacci numbers below one million.
For this I had designed a rather simple recursive Fibonacci function
fib :: Int -> Integer
fib n
n == 0 = 0
n == 1 = 1
otherwise = fib (n-1) + fib (n-2)
The thing where I'm stuck on is defining the one million part. What I've got now is:
[ fib x | x <- [0..35], fib x < 1000000 ]
This because I know that the 35th number in the Fibonacci sequence is a high enough number.
However, what I'd like to have is to find that limit via a function and set it that way.
[ fib x | x <- [0..], fib x < 1000000 ]
This does give me the numbers, but it simply doesn't stop. It results in Haskell trying to find Fibonacci numbers below one million further in the sequence, which is rather fruitless.
Could anyone help me out with this? It'd be much appreciated!
The check fib x < 1000000 in the list comprehension filters away the fib x values that are less than 1000000; but the list comprehension has no way of knowing that greater values of x imply greater value of fib x and hence must continue until all x have been checked.
Use takeWhile instead:
takeWhile (< 1000000) [ fib x | x <- [0..35]]
A list comprehension is guaranteed to look at every element of the list. You want takeWhile :: (a -> Bool) -> [a] -> [a]. With it, your list is simply takeWhile (< 1000000) $ map fib [1..]. The takeWhile function simply returns the leading portion of the list which satisfies the given predicate; there's also a similar dropWhile function which drops the leading portion of the list which satisfies the given predicate, as well as span :: (a -> Bool) -> [a] -> ([a], [a]), which is just (takeWhile p xs, dropWhile p xs), and the similar break, which breaks the list in two when the predicate is true (and is equivalent to span (not . p). Thus, for instance:
takeWhile (< 3) [1,2,3,4,5,4,3,2,1] == [1,2]
dropWhile (< 3) [1,2,3,4,5,4,3,2,1] == [3,4,5,4,3,2,1]
span (< 3) [1,2,3,4,5,4,3,2,1] == ([1,2],[3,4,5,4,3,2,1])
break (> 3) [1,2,3,4,5,4,3,2,1] == ([1,2,3],[4,5,4,3,2,1])
It should be mentioned that for such a task the "canonical" (and faster) way is to define the numbers as an infinite stream, e.g.
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
takeWhile (<100) fibs
--[0,1,1,2,3,5,8,13,21,34,55,89]
The recursive definition may look scary (or even "magic") at first, but if you "think lazy", it will make sense.
A "loopy" (and in a sense more "imperative") way to define such an infinite list is:
fibs = map fst $ iterate (\(a,b) -> (b,a+b)) (0,1)
[Edit]
For an efficient direct calculation (without infinite list) you can use matrix multiplication:
fib n = second $ (0,1,1,1) ** n where
p ** 0 = (1,0,0,1)
p ** 1 = p
p ** n | even n = (p `x` p) ** (n `div` 2)
| otherwise = p `x` (p ** (n-1))
(a,b,c,d) `x` (q,r,s,t) = (a*q+b*s, a*r+b*t,c*q+d*s,c*r+d*t)
second (_,f,_,_) = f
(That was really fun to write, but I'm always grateful for suggestions)
The simplest thing I can think of is:
[ fib x | x <- [1..1000000] ]
Since fib n > n for all n > 3.
I'm new to Haskell, and I'm trying a bit:
isPrime :: Integer->Bool
isPrime x = ([] == [y | y<-[2..floor (sqrt x)], mod x y == 0])
I have a few questions.
Why when I try to load the .hs, WinHugs say: Instances of (Floating Integer, RealFrac Integer) required for definition of isPrime?
When the interpreter finds one element in the right set, it immediately stops or it computes all the set? I think you know what I mean.
Sorry about my english.
1) The problem is that sqrt has the type (Floating a) => a -> a, but you try to use an Integer as argument. So you have to convert your Integer first to a Floating, e.g. by writing sqrt (fromIntegral x)
2) I see no reason why == shouldn't be lazy, but for testing for an empty collection you can use the null function (which is definitely lazy, as it works on infinite lists):
isPrime :: Integer->Bool
isPrime x = null [y | y<-[2..floor (sqrt (fromIntegral x))], x `mod` y == 0]
But in order to get an more idiomatic solution, break the problem into smaller sub-problems. First, we need a list of all elements y with y*y <= x:
takeWhile (\y -> y*y <= x) [2..]
Then we need only the elements that divide x:
filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..])
Then we need to check if that list is empty:
isPrime x = null (filter (\y -> x `mod`y == 0) (takeWhile (\y -> y*y <= x) [2..]))
And if this looks to lispy to you, replace some of the parens with $
isPrime x = null $ filter (\y -> x `mod` y == 0) $ takeWhile (\y -> y*y <= x) [2..]
For additional clarity you can "outsource" the lambdas:
isPrime x = null $ filter divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
You can make it almost "human readable" by replacing null $ filter with not $ any:
isPrime x = not $ any divisible $ takeWhile notTooBig [2..] where
divisible y = x `mod`y == 0
notTooBig y = y*y <= x
Because sqrt has the type Floating a => a -> a. This means the input has to be a Floating type and the output will be the same type. In other words x needs to be a Floating type. However you declared x to be of type Integer, which is not a Floating type. In addition floor needs a RealFrac type, so x needs to be that as well.
The error message suggests that you fix that by making Integer a Floating type (by defining an instance Floating Integer (and the same for RealFrac).
Of course this is not the correct approach in this case. Rather you should use fromIntegral to convert x to a Real (which is an instance of Floating and RealFrac) and then give that to sqrt.
Yes. As soon as == sees that the right operand has at least one element, it knows it is not equal to [] and thus returns False.
That being said, null is a more idiomatic way to check whether a list is empty than [] ==.
Regarding the second point, it stops, for example:
[] == [x | x <- [1..]]
Returns False
Landei's solution is great, however, if you want a more efficient¹ implementation we have (thanks to BMeph):
-- list of all primes
primes :: [Integer]
primes = sieve (2 : 3 : possible [1..]) where
sieve (p : xs) = p : sieve [x | x <- xs, x `mod` p > 0]
possible (x:xs) = 6*x-1 : 6*x+1 : possible xs
isPrime :: Integer -> Bool
isPrime n = shortCircuit || (not $ any divisible $ takeWhile inRangeOf primes) where
shortCircuit = elem n [2,3] || (n < 25 && ((n-1) `mod` 6 == 0 || (n+1) `mod` 6 == 0))
divisible y = n `mod` y == 0
inRangeOf y = y * y <= n
The 'efficiency' comes from the use of constant primes. It improves the search in two ways:
The Haskell runtime could cache the results so subsequent invocations are not evaluated
It eliminates a range of numbers by logic
note that the sieve value is simply a recursive table, where says the head of
the list is prime, and adds it to it. For the rest of the lists if there is no
other value already in the list that composes the number then its also prime
possible is list of all possible primes, since all possible primes are in the
form 6*k-1 or 6*k-1 except 2 and 3
The same rule is applied for shortCircuit too to quickly bail out of calculations
Footnote by D.F.
¹ It's still a terribly inefficient way to find primes. Don't use trial division if you need primes larger than a few thousand, use a sieve instead. There are several far more efficient implementations on hackage.
I think WinHugs needs to import a module for Integer and etc... Try Int
The interpreter will not compute anything until you call e.g. isPrime 32 then it will lazily compute the expression.
PS your isPrime implementation is not the best implementation!