I'm trying to write Karatsuba Algorithm using the divide and conquer approach in Haskell. I did it with merge sort algorithm but can't figure it out here and it's a little bit embarrassing at this point.
My main function looks like this:
dz test end divide combine x =
if test x then end x
else combine(map(dz test end divide combine) (divide x))
I test it for values 1234 and 5678: dz test end divide combine [1234, 5678,2].
So I have to write test, end, divide and combine functions.
lengthNumb x = length . show $ x
test (x:x1:xs) = (lengthNumb x) < 4 || (lengthNumb x1) < 4
end (x:y:z:xs) = [x * y, z]
This is pretty straightforward. I just check if both numbers that I want to multiply are at least 4 digits long. If not I just use simple multiplication and carry m value. I know that Karatsuba works better for bigger numbers but this is just for testing purposes.
divide [] = []
divide (x:x1:x2:xs) =
let y1 = x `div` 10^x2
y2 = x `mod` 10^x2
y3 = x2 `div` 2
z1 = x1 `div` 10^x2
z2 = x1 `mod` 10^x2
in [[y1,y2,y3],[z1,z2,y3],[y1+y2, z1+z2, y3]]
combine [[x, x1],[y,y1],[z,z1]] = x * 10^(2*x1) + y + (z - x - y) * 10^x1
I was told that combine function should only do the final multiplication. So I guess it should get three numbers as an input (each with their m value) and then also do the necessary subtraction ( z-x-y ) because I couldn't do it in divide.
But this is wrong. I get an error:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]] -> [a]
Actual type: [[[a]]] -> [a]
I think it is a problem with the parameters of combine function but I don't know how to fix it. I also think that there could be a problem with how combine and divide work together because in one of the previous iterations the final result of multiplication was wrong.
Related
Create a divisors :: Int -> [Int] function that returns the divisors
of x.
I've successfully made a divides function that returns True if y is a divisor of x.
divides x y | mod x y == 0 = True
| mod x y /= 0 = False
I've tried to use it to filter numbers from [1..n] , but can't exactly get a grasp on how the filter function works. Can anyone set me in the right direction?
divisors n = filter divides n [1..n]
You are in the right track. Only that your problem is not exactly how filter works, but how Haskell works.
divisors n = filter (divides n) [1..n]
The above will do the trick. See, filter takes two arguments, so does divisors. But you are giving it three arguments at filter divides n [1..n].
Btw,
divides x y | mod x y == 0 = True
| mod x y /= 0 = False
is semantically equivalent to
divides x y = mod x y == 0
and operationally it doesn't repeat the mod calculation and the test mod x y /= 0.
filter takes as its second argument a list to filter - here your [1..n] - and as first argument a function which takes one of those list elements as input and returns a boolean.
So think about what this function would be, in terms of your pre-defined function divides. Since, as you have it, divides x y actually means "y is a divisor of x", you can easily express this with a lambda function:
divisors n = filter (\m -> divides n m) [1..n]
which can be further simplified by "eta-reduction" (or coloquially, "cancelling the m") to
divisors n = filter (divides n) [1..n]
Task is to find all two-valued numbers representable as the sum of the sqrt's of two natural numbers.
I try this:
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod` 1 == 0, sqrt (y) `mod` 1 == 0]
Result:
Unresolved top-level overloading Binding : func
Outstanding context : (Integral b, Floating b)
How can I fix this?
This happens because of a conflict between these two types:
sqrt :: Floating a => a -> a
mod :: Integral a => a -> a -> a
Because you write mod (sqrt x) 1, and sqrt is constrained to return the same type as it takes, the compiler is left trying to find a type for x that simultaneously satisfies the Floating constraint of sqrt and the Integral constraint of mod. There are no types in the base library that satisfy both constraints.
A quick fix is to use mod' :: Real a => a -> a -> a:
import Data.Fixed
func = [sqrt (x) + sqrt (y) | x <- [10..99], y <- [10..99], sqrt (x) `mod'` 1 == 0, sqrt (y) `mod'` 1 == 0]
However, from the error you posted, it looks like you may not be using GHC, and mod' is probably a GHC-ism. In that case you could copy the definition (and the definition of the helper function div') from here.
But I recommend a more involved fix. The key observation is that if x = sqrt y, then x*x = y, so we can avoid calling sqrt at all. Instead of iterating over numbers and checking if they have a clean sqrt, we can iterate over square roots; their squares will definitely have clean square roots. A straightforward application of this refactoring might look like this:
sqrts = takeWhile (\n -> n*n <= 99)
. dropWhile (\n -> n*n < 10)
$ [0..]
func = [x + y | x <- sqrts, y <- sqrts]
Of course, func is a terrible name (it's not even a function!), and sqrts is a constant we could compute ourselves, and is so short we should probably just inline it. So we might then simplify to:
numberSums = [x + y | x <- [4..9], y <- [4..9]]
At this point, I would be wondering whether I really wanted to write this at all, preferring just
numberSums = [8..18]
which, unlike the previous iteration, doesn't have any duplicates. It has lost all of the explanatory power of why this is an interesting constant, though, so you would definitely want a comment.
-- sums of pairs of numbers, each of whose squares lies in the range [10..99]
numberSums = [8..18]
This would be my final version.
Also, although the above definitions were not parameterized by the range to search for perfect squares in, all the proposed refactorings can be applied when that is a parameter; I leave this as a good exercise for the reader to check that they have understood each change.
I'm learning Haskell and I have been practising doing some functions by myself, in this functions are included the calculus of sine using recursion, but I get strange results.
The formula I'm using to calculate the sine is this one:
And my code is this:
--Returns n to power p
pow :: Float->Integer->Float
pow n p =
if p == 0 then
1
else
if p == 1 then
n
else
n * (pow n (p-1))
--Finds a number's factorial
f :: Integer->Integer
f n =
if n == 1 then
n
else
n * (f (n-1))
--TODO: Trigonometric functions ( :v I'll do diz 2)
sinus :: Float->Char->Float
sinus n deg =
if(deg == 'd')then
sinusr 0 (normalize (torad n)) 0
else
sinusr 0 (normalize n) 0
--Get the value equivalent to radians of the presented degrees
torad :: Float->Float
torad v = ( (v * pi) / 180 )
--Recursive to get the value of the entering radians
sinusr :: Integer->Float->Float->Float
sinusr k x result =
if k == 130 then
result + ( ((pow (-1) k ) * ((pow x ((2*k)+1))) / (fromIntegral (f ((2*k)+1)))))
else
result + (sinusr (k+1) x ( ((pow (-1) k ) * ((pow x ((2*k)+1))) / (fromIntegral (f ((2*k)+1))))))
--Subtracts pi/2 the necessary times to get a value minor or equals to pi/2 :v
normalize :: Float->Float
normalize a = a - (fromIntegral (truncate (a / (pi*2)))*(pi*2))
For example, the output it's this:
*Main> sinus 1 'd'
1.7452406e-2
*Main> sinus 1 's'
0.84147096
*Main> sinus 2 's'
NaN
*Main> sinus 2 'd'
3.4899496e-2
Can someone tell me why it is showing me that?
I have worked the same logic with Lisp, and it runs perfectly, I just had to figure out the Haskell syntax, but as you can see, it is not working as it must be.
Beforehand, thank you very much.
Single point arithmetic isn't accurate enough for to calculate a trigonometric function. The exponent doesn't have enough bits for the large, intermediate numbers in sinusr. Or, to be blunt, the following number doesn't fit a Float:
ghci> 2 ^ 130 :: Float
Infinity
As soon as you hit the boundaries of floating point numbers (-Infinity, Infinity) you usually end up with either those or NaN.
Use Double instead. Your implementation of lisp probably uses double point precision floating point numbers too. Even better, don't recalculate the whole fraction in every step, instead update the nominator and denominator, then your values won't get too large for Float.
I am having a hard time trying to figure out how does this function works, and I need an explanation from an expert. Appreciate any help!
puzzle n x = scanr (\y acc -> (acc + y/acc)/2) 1 (replicate n x)
I tried running these:
--puzzle 10 2
--puzzle 10 5
--puzzle 10 36
and it gives me this output, respectively:
[1.414213562373095,1.414213562373095,1.414213562373095,1.414213562373095,1.414213562373095,1.414213562373095,1.4142135623746899,1.4142156862745097,1.4166666666666665,1.5,1.0]
[2.23606797749979,2.23606797749979,2.23606797749979,2.23606797749979,2.23606797749979,2.236067977499978,2.2360688956433634,2.238095238095238,2.3333333333333335,3.0,1.0]
[6.0,6.0,6.0,6.0,6.000000005333189,6.0002529841194185,6.055351744849479,6.872226737643129,10.222972972972974,18.5,1.0]
This function calculates a square root using Newton`s formula and stores all iteration results in list.
Here is a Newton's method on wiki.
Storing process is based on definition of scanr function:
scanr is similar to foldr, but returns a list
of successive reduced values from the right
It makes a list of n x-es like [x,x,x,x,x,..] (n times)
and then what it does is:
x1 = ( 1 + x/1)/2
x2 = (x1 + x/x1)/2
x3 = (x2 + x/x2)/2
x4 = (x3 + x/x3)/2
and the result is [xn,x(n-1),...,x2,x1]
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.