Related
I'm trying to solve the following problem in Haskell: given an integer return the list of its digits. The constraint is I have to only use one of the fold* functions (* = {r,l,1,l1}).
Without such constraint, the code is simple:
list_digits :: Int -> [Int]
list_digits 0 = []
list_digits n = list_digits r ++ [n-10*r]
where
r = div n 10
But how do I use fold* to, essentially grow a list of digits from an empty list?
Thanks in advance.
Is this a homework assignment? It's pretty strange for the assignment to require you to use foldr, because this is a natural use for unfoldr, not foldr. unfoldr :: (b -> Maybe (a, b)) -> b -> [a] builds a list, whereas foldr :: (a -> b -> b) -> b -> [a] -> b consumes a list. An implementation of this function using foldr would be horribly contorted.
listDigits :: Int -> [Int]
listDigits = unfoldr digRem
where digRem x
| x <= 0 = Nothing
| otherwise = Just (x `mod` 10, x `div` 10)
In the language of imperative programming, this is basically a while loop. Each iteration of the loop appends x `mod` 10 to the output list and passes x `div` 10 to the next iteration. In, say, Python, this'd be written as
def list_digits(x):
output = []
while x > 0:
output.append(x % 10)
x = x // 10
return output
But unfoldr allows us to express the loop at a much higher level. unfoldr captures the pattern of "building a list one item at a time" and makes it explicit. You don't have to think through the sequential behaviour of the loop and realise that the list is being built one element at a time, as you do with the Python code; you just have to know what unfoldr does. Granted, programming with folds and unfolds takes a little getting used to, but it's worth it for the greater expressiveness.
If your assignment is marked by machine and it really does require you to type the word foldr into your program text, (you should ask your teacher why they did that and) you can play a sneaky trick with the following "id[]-as-foldr" function:
obfuscatedId = foldr (:) []
listDigits = obfuscatedId . unfoldr digRem
Though unfoldr is probably what the assignment meant, you can write this using foldr if you use foldr as a hylomorphism, that is, building up one list while it tears another down.
digits :: Int -> [Int]
digits n = snd $ foldr go (n, []) places where
places = replicate num_digits ()
num_digits | n > 0 = 1 + floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n, ds) = let (q,r) = n `quotRem` 10 in (q, r : ds)
Effectively, what we're doing here is using foldr as "map-with-state". We know ahead of time
how many digits we need to output (using log10) just not what those digits are, so we use
unit (()) values as stand-ins for those digits.
If your teacher's a stickler for just having a foldr at the top-level, you can get
away with making go partial:
digits' :: Int -> [Int]
digits' n = foldr go [n] places where
places = replicate num_digits ()
num_digits | n > 0 = floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n:ds) = let (q,r) = n `quotRem` 10 in (q:r:ds)
This has slightly different behaviour on non-positive numbers:
>>> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits' 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits 0
[]
>>> digits' 0
[0]
>>> digits (negate 1234567890)
[]
>>> digits' (negate 1234567890)
[-1234567890]
I am trying to learn concurrency and parallelism in Haskell.
And I just started Simon Marlow's book. Not everything is clear though.
And there aren't many (if any) simple examples on the internet.
This is just a simple prime search function for learning purposes.
Can this be parallelised? And if yes, can someone show an example with this function.
main = mapM_ print [x | x <- [2..], isPrime x]
isPrime :: Integer -> Bool
isPrime n = odd n && all (\ f -> n `mod` f /= 0) [3..(ceiling $ sqrt $ fromIntegral n)]
I understand that I can use Strategies to map through a list in parallel.
How, for instance, would I test factors in the list in batches of 8, doing 8 tests in parallel?
I would love an example please.
Thanks.
This answer is also available as a .lhs file at http://lpaste.net/143207
The basic idea is that whenever you have an expression like:
map f xs
you can replace it with:
parMap strat f xs
to spawn off the map computation as sparks so that it will
be executed in parallel in the threaded runtime.
A typical choice for strat is rdeepseq - see Basic Strategies for other options.
The problem is that spawning every single call to f as
a spark may not be cost effective. To realize any speedup
you may have to organize the work so that a spark is responsible
for calling f on a range of elements of the list.
Let's write isPrime like this:
-- original version
isPrime0 n = and $ map notfactor [2..limit]
where limit = div n 2
notfactor f = mod n f /= 0
(I've purposely extended the factor testing range so we don't
have to use large prime numbers for our tests.)
The first idea would be to simply change the map into parMap rdeepseq:
-- spawn each call to notfactor as a spark
isPrime1 n = and $ parMap rdeepseq notfactor [2..limit]
where limit = div n 2
notfactor f = mod n f /= 0
If you benchmark this, however, you'll find
out this runs a lot slower than the sequential version.
The next idea is to break up the range [2..limit] into
a small number of chunks like this:
-- evaluate the notfactor calls in ranges -- not parallized
isPrime2 n = and $ map (\r -> all notfactor r) ranges
where limit = div n 2 -- ceiling $ sqrt $ fromIntegral n
notfactor f = mod n f /= 0
ranges = chunks 3 limit 10
Here chunks a b k is a function which splits the
list [a..b] into k equal sized ranges.
To get a parallized version, we change the map call
into parMap rdeepseq:
-- evaluate the notfacto calls in ranges - parallelized
isPrime3 n = and $ parMap rdeepseq (\r -> all notfactor r) ranges
where limit = div n 2
notfactor f = mod n f /= 0
ranges = chunks 3 limit 10
Some rough timings (in seconds) for the prime 15485863 and
RTS option -N1 vs. -N2:
-N1 -N2
isPrime0 0.624 0.673
isPrime1 12.--- 12.---
isPrime2 0.573 0.603
isPrime3 0.563 0.365
As you can see, isPrime3 does exhibit some speedup. The timing for isPrime1 is due to the fact that it is creating several million sparks compared to isPrime3 which only creates 10 sparks.
For completeness, here's the code for chunks and the
program driver.
-- divide a range into equal size chunks
chunks :: Integer -> Integer -> Integer -> [[Integer]]
chunks a b k =
let (q,r) = divMod (b - a) k
sizes = replicate (fromIntegral r) (q+1) ++ replicate (fromIntegral (k-r)) q
go x [] = []
go x (y:ys) = [x..x+y-1] : go (x+y) ys
in go a sizes
main :: IO ()
main = do
( which : ps : _ ) <- getArgs
let p = read ps
case which of
"0" -> print $ isPrime0 p
"1" -> print $ isPrime1 p
"2" -> print $ isPrime2 p
"3" -> print $ isPrime3 p
I'm new to haskell world and wanted to know, given any positive integer and number of digits between 1-9 how can I find the combination of numbers that sum into the positive integer using the provided number of digits in Haskell. For example,
4 using two digits can be represented as a list of [[2,2],[3,1]] using three digits as a list of [[1,1,2]],
5 using two digits can be represented as a list of [[2,3],[4,1]] using three digits as a list of [[1,1,3],[2,2,1]]
Assuming that you want to avoid a brute-force approach, this can be regarded as a typical dynamic-programming problem:
import Data.Array
partitions :: Int -> Int -> [[Int]]
partitions m n = table ! (m, n, 9)
where
table = listArray ((1, 1, 1), (m, n, 9)) l
l = [f i j k | i <- [1 .. m], j <- [1 .. n], k <- [1 .. 9]]
f i 1 k = if i > k `min` 9 then [] else [[i]]
f i j k = [d : ds | d <- [1 .. k `min` pred i], ds <- table ! (i - d, j - 1, d)]
The idea is to construct a three-dimensional lazy array table in which a cell with index (i, j, k) contains all partitions ds of the positive integer i into lists of j digits drawn from [1 .. k] such that sum ds == i.
For example:
> partitions 4 2
[[2,2],[3,1]]
> partitions 4 3
[[2,1,1]]
> partitions 5 2
[[3,2],[4,1]]
> partitions 5 3
[[2,2,1],[3,1,1]]
If you really don't want to think about the problem, and you really should because dynamic programming is good brain food, then you can ask the computer to be smart on your behalf. For example, you could use a tool called an SMT solver to which the sbv package gives you easy access.
Encoding Partitioning in SBV
A great advantage of solvers is you merely need to express the problem and not the solution. In this case lets declare some number of integers (identified by len) which are values 1..9 that sum to a known result (sumVal):
intPartitions :: Int -> Int -> IO AllSatResult
intPartitions sumVal len = allSat $ do
xs <- mapM exists [show i | i <- [1..len]] :: Symbolic [SWord32]
mapM (constrain . (.< 10)) xs
mapM (constrain . (.> 0)) xs
return $ sum xs .== fromIntegral sumVal
Calling this function is rather simple we just have to import the right libraries and print out what are called the satisfying "models" for our problem:
import Data.SBV
import Data.List (nub,sort)
main = do
res <- intPartitions 5 3
print (nub (map sort (extractModels res :: [[Word32]])))
Notice I sorted and eliminated duplicate solutions because you didn't seem to care that [1,1,3], [3,1,1] etc were all solutions - you just want one permutation of the resulting assignments.
For these hard-coded values we have a result of:
[[1,1,3],[1,2,2]]
Well a simple brute force does the trick:
import Data.List
import Control.Monad
sums :: Int -> Int -> [[Int]]
sums number count = nub . map sort . filter ((==number) . sum) $ replicateM count [1..number+1-count]
Note that this is very inefficient. The usage of nub . map sort only shortens the result by removing doubled elements.
This is usually solved by using dynamic programming to avoid recomputing common sub-problems. But this is not the most important problem here: you need to start by coming up with the recursive algorithm! You will have plenty of time to think about producing an efficient solution once you've solved that problem. Hence this answer in two steps. The whole gist without comments is available here.
I start off by giving names to types because I'd get confused with all the Ints floating around and I consider types to be documentation. You might be more clever than I am and not need all this extra stuff.
type Target = Int
type Digits = Int
type MaxInt = Int
Now, the bruteforce solution: We're given the number of Digits left to partition a number, the Target number and the MaxInt we may use in this partition.
partitionMaxBrute :: Digits -> Target -> MaxInt -> [[Int]]
partitionMaxBrute d t m
If we have no digits left and the target is zero, we're happy!
| d == 0 && t == 0 = [[]]
If the product of Digits by MaxInt is smaller than Target or if the MaxInt itself is smaller than zero, there is no way we may succeed accumulating Digits non-zero numbers! :(
| d * m < t || m <= 0 = []
If MaxInt is bigger than our Target then we better decrease MaxInt if we want to have a solution. It does not make sense to decrease it to anything bigger than Target + 1 - Digits.
| t < m = partitionMaxBrute d t (t + 1 - d)
Finally, we may either lower MaxInt (we are not using that number) or substract MaxInt from Target and keep going (we are using MaxInt at least once):
| otherwise = partitionMaxBrute d t (m - 1)
++ fmap (m :) (partitionMaxBrute (d - 1) (t - m) m)
Given that solution, we can get our brute force partition: it's the one where the MaxInt we start with is Target + 1 - Digits which makes sense given that we are expecting a list of Digits non-zero numbers.
partitionBrute :: Digits -> Target -> [[Int]]
partitionBrute d t = partitionMaxBrute d t (t + 1 - d)
Now comes the time of memoization: dynamic programming is taking advantage of the fact that the smaller problems we solve are discovered through a lot of different paths and we do not need to recompute the answer over and over again. Easy caching is made possible by the memoize package. We simply write the same function with its recursive calls abstracted:
partitionMax :: (Digits -> Target -> MaxInt -> [[Int]]) ->
Digits -> Target -> MaxInt -> [[Int]]
partitionMax rec d t m
| d == 0 && t == 0 = [[]]
| d * m < t || m <= 0 = []
| t < m = rec d t (t + 1 - d)
| otherwise = rec d t (m - 1)
++ fmap (m :) (rec (d - 1) (t - m) m)
And make sure that we cache the values:
partition :: Digits -> Target -> [[Int]]
partition d t = memoPM d t (t + 1 - d)
where memoPM = memoize3 $ partitionMax memoPM
You can produce all partitions directly:
type Count = Int
type Max = Int
type Target = Int
partitions :: Count -> Max -> Target -> [[Int]]
partitions 0 m 0 = [[]]
partitions k m n = do
let m' = min m (n - k + 1)
d <- takeWhile (\d -> n <= k * d) [m', m' - 1 .. 1]
map (d:) $ partitions (k - 1) d (n - d)
It's easy to check, that there are no redundant cases. We just need to replace do with redundant $ do, where redundant is
redundant [] = [[]]
redundant xs = xs
If partitions (k - 1) d (n - d) returned [], then redundant would make [[]] from it, and then map (d:) $ partitions (k - 1) d (n - d) would be equal to [d]. But output doesn't change with the redundant function, so all partitions are generated directly.
The code is pretty simple and fast, since you want to produce partitions, rather than count them.
I've just started learning a bit of Haskell and functional programming, but I find it very difficult getting a hang of it :)
I am trying to translate a small piece of ruby code to Haskell (because I like the concept functional programming and Haskell proposes and even more because I come from a mathematics field and Haskell seems very mathematical):
class Integer
def factorial
f = 1; for i in 1..self; f *= i; end; f
end
end
boundary = 1000
m = 0
# Brown Numbers - pair of integers (m,n) where n factorial is equal with square root of m
while m <= boundary
n = 0
while n <= boundary
puts "(#{m},#{n})" if ((n.factorial + 1) == (m ** 2))
n += 1
end
m += 1
end
I could only figure out how to do factorials:
let factorial n = product [1..n]
I cannot figure out how to do the while loops or equivalent in Haskell, even though I found some examples that were far to confusing for me.
The idea is that the loops start from 0 (or 1) and continue (with an increment of 1) until it reaches a boundary (in my code is 1000). The reason there is a boundary is because I was thinking of starting parallel tasks that do the same operation but on different intervals so the results that I expect are returned faster (one operation would be done on 1 to 10000, another on 10000 to 100000, etc.).
I would really appreciate it if anyone could help out with this :)
Try this:
let results = [(x,y) | x <- [1..1000], y <- [1..1000] ,1 + fac x == y*y]
where fac n = product [1..n]
This is a list comprehension. More on that here.
To map it to your Ruby code,
The nested loops in m and n are replaced with x and y. Basically there is iteration over the values of x and y in the specified ranges (1 to 1000 inclusive in this case).
The check at the end is your filter condition for getting Brown numbers.
where allows us to create a helper function to calculate the factorial.
Note that instead of a separate function, we could have computed the factorial in place, like so:
(1 + product[1..x]) == y * y
Ultimately, the (x,y) on the left side means that it returns a list of tuples (x,y) which are your Brown numbers.
OK, this should work in your .hs file:
results :: [(Integer, Integer)] --Use instead of `Int` to fix overflow issue
results = [(x,y) | x <- [1..1000], y <- [1..1000] , fac x == y*y]
where fac n = product [1..n]
To add to shree.pat18's answer, maybe an exercise you could try is to translate the Haskell solution back into Ruby. It should be possible, because Ruby has ranges, Enumerator::Lazy and Enumerable#flat_map. The following rewritten Haskell solution should perhaps help:
import Data.List (concatMap)
results :: [(Integer, Integer)]
results = concatMap (\x -> concatMap (\y -> test x y) [1..1000]) [1..1000]
where test x y = if fac x == y*y then [(x,y)] else []
fac n = product [1..n]
Note that Haskell concatMap is more or less the same as Ruby Enumerable#flat_map.
hi im trying to make a function in haskell that takes a number a makes a partion of it using lists i.e. for number 4 it would create [[1,1,1,1],[1,1,2],[1,3],[2,2],[4]]. I was thinking of using list comprehension for this where it would create list x and then create further lists using numbers from [1...n] (n being the partition number I would want) where the sum of the list created would be equal to n.
The code I have created so far is-
partions (n:xs) = [[x|x<-[1...n], sum[x]==n]]|xs<-[1..]]
but obiviously it doesnt work, any suggestions?
thanks.
I suggest trying recursion: To obtain the partitions of n, iterate over the numbers i = 1 to n, and recursively generate the partitions of (n-i), the base case being that the only partition of 1 is 1 itself, and the partition of 0 is the empty list.
How about this...
import Data.List (nub, sort)
parts :: Int -> [[Int]]
parts 0 = []
parts n = nub $ map sort $ [n] : [x:xs | x <- [1..n`div`2], xs <- parts(n - x)]
Trying it:
*Main Control.Monad> forM [1..5] (print . parts)
[[1]]
[[2],[1,1]]
[[3],[1,2],[1,1,1]]
[[4],[1,3],[1,1,2],[1,1,1,1],[2,2]]
[[5],[1,4],[1,1,3],[1,1,1,2],[1,1,1,1,1],[1,2,2],[2,3]]
I think it's correct, if not efficient.
I found it helpful to define an auxiliary function, partitionsCap, which does not let any of the items be larger than a given value. Used recursively, it can be used to only produce the monotonically decreasing results you want (i.e. no [1,3,1] when you already have [1,1,3]):
partitions :: Int -> [[Int]]
partitions n = partitionsCap n n
partitionsCap :: Int -> Int -> [[Int]]
partitionsCap cap n
| n < 0 = error "partitions: negative number"
| n == 0 = [[]]
| n > 0 = [i : p | i <- [hi,hi-1..1], p <- partitionsCap i (n-i)]
where hi = min cap n
At the heart of the algorithm is the idea that, when partitioning N, you take i from n down to 1, and prepend i to the partitions of n-i. Simplified:
concat [map (i:) $ partitions (n-i) | i <- [n,n-1..1]]
but wrong:
> partitions 3
[[3],[2,1],[1,2],[1,1,1]]
We want that [1,2] to go away. Hence, we need to cap the partitions we're prepending to so they won't go above i:
concat [map (i:) $ partitionsCap i (n-i) | i <- [hi,hi-1..1]]
where hi = min cap n
Now, to clean it up: that concat and map so close together got my attention. A little background: list comprehensions and the list monad are very closely related, and concatMap is the same as >>= with its arguments flipped, in the list monad. So I wondered: can those concat and map somehow turn into a >>=, and can that >>= somehow sweet-talk its way into the list comprehension?
In this case, the answer is yes :-)
[i : p | i <- [hi,hi-1..1], p <- partitionsCap i (n-i)]
where hi = min cap n
I'm a little rusty with Haskell, but maybe the following code can guide you to find the solution.
parts :: Int -> Int -> [[Int]]
parts 0 p = [[]]
parts x p = [(y:ys) | y <-[p..x], ys <- (parts (x - y) y)]
And then you would have to call parts with x = n, and p = 1.
EDIT
I've fixed the base case when x equals 0 to return a list with a single item, being that item an empty list. Now it works fine :)