Excluding Numbers for Sieve of Sundaram - haskell

I'm working on implementing the Sieve of Sundaram.
The first step is to get a list of Integer's such that:
i, j are Natural Numbers, 1 <= i <= j
i + j + 2*i*j <= n
Here's my function. It's supposed to generate a list of tuples of all (i, j)'s that match the above
restrictions.
numsToRemove :: Integer -> [(Integer, Integer)]
numsToRemove n = [ (i, j) | i <- [1..n], j <- [1..n], i <= j, i >= 1, j >= 1,
i * j + 2*i*j <= n]
But I'm getting non-primes in my answer. Excluding my other work, I think that I'm making a mistake in generating this list of Integers.
Please let me know what I'm doing wrong.

Your function checks for i * j + 2*i*j <= n but your definition asks for i + j + 2*i*j <= n. There is a * that should have been a +.

Related

Binary Search in Fortran 95

I try to implement a binary search in Fortran 95 with a recursive function.
My error message is: /usr/bin/timeout: the monitored command dumped core
Does anyone have an idea how I could solve this problem?
The return value should be 2 for this little programm.
In addition: How can I expand my code to return the position number of the array "ar" to know where I can add my new element (i.e "2.9")? In case of 2.9 it should return 2. Another example, if I take 7.3 instead of 2.9 it should return 6 (between 7.0 and 8.0 of array "ar").
program h
real, dimension(7) :: ar
integer :: s
real :: outp
ar = (/2.0, 3.0, 4.0, 5.0, 7.0, 8.0, 9.0/)
s = sizeof(ar)
outp = findAr(ar, 1, s, 3.0)
print*, outp
end program h
recursive function findAr(ar, l, r, x) result(a)
real, dimension(size(ar)), intent(in) :: ar
integer, intent(in) :: l, r
real, intent(in) :: x
integer :: midd
real :: a
if (r >= 1) then
midd = l + (r - 1) / 2
if (ar(midd) == x) then
a = midd
else if (ar(midd) > x) then
a = findAr(ar, l, midd - 1, x)
else
a = findAr(ar, midd + 1, r, x)
end if
end if
end function findAr
The compiler error can be resolved as specified by the comments to your questions.
Concerning your 2nd question: How to extend your code for search values in between the array elements. One could ask in the same manner for values outside of your array (e.g. smaller than its minimum).
The following code is not using recursive functions nor is it an extension of your code.
You should keep in mind that unnecessary function calls create some overhead and could result in performance loss.
module bin_search_m
implicit none
contains
function bin_search(x, x1) result(i)
!! find index of nearest value in sorted array
real, intent(in) :: x(:)
!! sorted array
real, intent(in) :: x1
!! value to find
integer :: i
!! return array index
integer :: i0, i1
! starting interval is the whole array
i0 = 1
i1 = size(x)
! test if x1 is outside of interval [x(1), x(end)]
if (x1 <= x(i0)) then
i = i0
return
end if
if (x1 >= x(i1)) then
i = i1
return
end if
! binary search
do while (i1 > (i0 + 1))
i = (i1 + i0) / 2
if (x(i) < x1) then
i0 = i
else if (x(i) > x1) then
i1 = i
else
return
end if
end do
! pick index of value that is closer
i = merge(i0, i1, ((2 * x1) < (x(i0) + x(i1))))
end function
end module

Accumulator version of recursion

I have a example of accu version of recursion.
Normal recursion:
fib n = if n== 0 then 1 else if n==1 then 1 else fib(n-1) + fib (n-2)
Accu recursion:
fib n fibPOM n 1 1
fibPOM n f1 f2 = if n ==1 then f1 else fibPOM (n-1) (f1+f2) f1
And i must do the same with this(a^n recursion):
ff a n = if n==0 then 1 else if n==1 then a else a * ff a (n-1)
But i have no idea what i must do to get a^n accu recursion.
Here's a hint: add an accumulator argument acc
ff a n = ffACC a n (some initial accumulator value)
ffACC a n acc =
if n==0 then ...
else if n==1 then ...
else ...
Make sure that in each ... all the recursive calls are tail calls. That is, return ffACC (new a) (new n) (new acc), not something like value * ffACC ....
You start with an initial value 1: ff a n = ffAccu a n 1, then call the recursion as
ffAccu a n m = if n == 0 then m else (ffAccu a (n-1) (a*m))
(Note: The if then else construct might be written more cleanly by using pattern matching, as in
ffAccu a 0 m = m
ffAccu a n m = ffAccu a (n-1) (a*m)
)

Haskell function that return the next prime number after given n

Learning Haskell. Trying to write a function called nextPrime n that will return the next prime number after n.
I have the following:
-- Generate a list of all factors of n
factors :: Integral a => a -> [a]
factors n = [x | x <- [1..n], n `mod` x == 0]
-- True iff n is prime
isPrime :: Integral a => a -> Bool
isPrime n = factors n == [1, n]
So far the function is set up like so:
nextPrime :: Integral a => a -> a
nextPrime n =
I presume I have to do a sort of while loop maybe but not sure how. I am totally new to functional programming. Any help is appreciated
I assumed that nextPrime n means "get me the first prime number that's greater than n".
Here's an idea:
nextPrime :: Integral a => a -> a
nextPrime n = nextPrime' (n + 1)
where nextPrime' m = ...
You want to fill in the blanks for nextPrime'. Here's a hint:
fun n = if n <= 0
then 0
else n + fun (n - 1)
This is a recursive function that calculates the sum 1 + 2 + 3 + ... + n, though it does it starting with n and going down from there. nextPrime' will have to go up.

To prove equality of two function definitions inductively

How do I do the induction to establish the statement moll n = doll n, with
moll 0 = 1 --(m.1)
moll n = moll ( n-1) + n --(m.2)
doll n = sol 0 n --(d.1)
where
sol acc 0 = acc +1 --(d.2)
sol acc n = sol ( acc + n) (n-1) -- ? (d.2)
I tried to prove the base case for n = 0
doll 0 = (d.2) = 1 = (m.1) = moll 0 , which is correct.
Now for n+1, show that
moll 2n = doll (n + 1)
=> doll (n + 1) = (d.2) = soll (acc + n + 1) n
But what now? How can I simplify it any further?
You've got a mistake in your n+1 step. I suspect this is because you're new to Haskell and its precedence rules.
moll (n+1) is not, as you write moll 2n - I'm assuming that by that you mean moll (2*n), since moll 2n is a haskell syntax error.
In any case, moll (n+1) is in fact moll n + n + 1, or, with extra parentheses added just to be explicit:
(moll n) + (n + 1)
That is, you apply moll to n and then you add n + 1 to the result of that.
From here you should be able to apply the induction hypothesis and go forward.
More explicitly, since you seem to still be having trouble:
moll (n+1) == (moll n) + (n + 1) (by m.2)
== (doll n) + (n + 1) (by induction hypot.)
== (sol 0 n) + (n + 1) (by d.1)
Now, as a lemma:
sol x n == (sol 0 n) + x
This can be proved by induction on n. It's obviously true for n equal to 0.
For the lemma's induction step:
sol x (n+1) == (sol (x + (n+1)) n) (By d.2, for (n+1) > 0)
== (sol 0 n) + (x + (n+1)) (By the induction hypot.)
== (sol 0 n) + (n+1) + x (This is just math; re-arranging)
== ((sol 0 n) + (n+1)) + x
== (sol (n+1) n) + x (By the induction hypot. again)
== (sol 0 (n+1)) + x (By d.2 again)
That second time I used the induction hypothesis may seem a bit odd, but remember that the induction hypothesis says:
sol x n == (sol 0 n) + x
For all x. Therefore, I can apply it to anything added to (sol 0 n), including n+1.
Now, back to the main proof, using our lemma:
moll (n+1) == (sol 0 n) + (n + 1) (we had this before)
== sol (n+1) n (by our lemma)
== sol 0 (n+1) (by d.2)
== doll (n+1) (by d.1)

How can I calculate Σ_{i=m}^n (m+i)^n?

I'm currently trying to calculate the following sum:
sum2015 :: Integer->Integer->Integer
sum2015 m n
| m>n = 0
| otherwise = (m+m)^n + sum2015 (m+1) n
As an example, sum2015 0 1 should return 1. However, it returns 2. What did I do wrong?
You're not calculating that sum. Note that m in (m + i)^n must stay fixed, but you use a new m here:
| otherwise = … + sum2015 (m+1) n
-- ^^^^^
-- oh oh
Therefore you get:
sum2015 0 1
= (0 + 0)^1 + sum2015 (0 + 1) 1
= (0 + 0)^1 + (1 + 1)^1 + sum2015 (1 + 1) 1
= (0 + 0)^1 + (1 + 1)^1 + 0
= 0 + 2
= 2
Instead, calculate all (m + i)^n and sum them afterwards:
sum2015 :: Integer -> Integer -> Integer
sum2015 m n = sum . map (\i -> (m + i) ^ n) $ [m..n]
Or, if you're not allowed to use that, use a worker:
sum2015 :: Integer -> Integer -> Integer
sum2015 m n = go m
where go i = ...
I can offer this option:
sum2015 m n = sum [(m + i) ** n | i <- [m..n]]
Firstly, I created list of numbers from m to n "[m..n]".
After for each i in this list, I computing terms of the sum.
Finally, just use "sum" function for obtained result list.
'**' - Pow function

Resources