Creating list with multiple conditions in haskell - haskell

Define the sequence (bn)n=1,2,… such that bn=3 when n is divisible by 3, and bn=4(n+1)^2 in other cases.
Define a function that for an argument n creates the list of n initial numbers of the sequence (bn)n=1,2,… .
so far I have two lists with condition 1 and condition 2:
divisible3 n = [x | x <- [1..n], x `mod` 3 == 0]
notdivisible3 n = [x*x*4+8*x+4 | x <- [1..n], x `mod` 3 /= 0]
I want it to be one list like:
list n = [x | x <- [1..n], condition1, condition 2]

You should write an if ... then ... else ... in the "yield" part of the list comprehension, not a filter. So something like:
list n = [ if n `mod` 3 == 0 then … else … | x <- [1..n]]
where I leave the … parts as an exercise.

Related

Haskell List comprehensions infinite list problem

I'm trying to learn Haskell and comprehension lists but cannot find solution on this:
mylist = [x*y | x <- [1..], y <- [1..]]
After my trials the result is something like this
mylist = [1,2,3,4,5,...]
because in list comprehensions, x takes the value 1,and then y changes value repeatedly.
But my goal is to achieve a different assignment so as to have the following result:
mylist = [1,2,2,4,3,3,6.....]
I mean i want the combinations being mixed and not each one apart,because I have a serious problem to have the suitable result.
I will give a more specific example.
I want a list that will have all numbers of this form:
num = 2^x * 3^y
x and y must take all values >= 0.
My approach is the following:
powers = [2^x * 3^y | x <- [0..], y <- [0..]]
But in this way I only take powers of 3, because x is constantly 0.
I tried this one
multiples = nub (merge (<=) powers2 powers3)
powers3 = [2^x * 3^y | x <- [0..], y <- [0..]]
powers2 = [2^x * 3^y | y <- [0..], x <- [0..]]
so as to merge the different ones but again,the values 6,12,etc. are missing - the result is this:
mylist = [1,2,3,4,8,9,16,27,32,64,81...]
The code that you show,
multiples = nub (merge (<=) powers2 powers3)
powers3 = [2^x * 3^y | x <- [0..], y <- [0..]]
powers2 = [2^x * 3^y | y <- [0..], x <- [0..]]
is equivalent to
powers3 = [2^x * 3^y | x <- [0], y <- [0..]]
= [2^0 * 3^y | y <- [0..]]
= [3^y | y <- [0..]]
powers2 = [2^x * 3^y | y <- [0], x <- [0..]]
= [2^x * 3^0 | x <- [0..]]
= [2^x | x <- [0..]]
so you only produce the powers of 2 and 3, without any mixed multiples. As such, there are guaranteed to be no duplicates in the stream, and the nub was not necessary. And of course it's incomplete.
But let's look at it at another angle. It was proposed in the comments to create a 2D grid out of these numbers:
mults23_2D = [[2^x * 3^y | y <- [0..]] | x <- [0..]]
{-
1 3 9 27 81 ...
2 6 18 54 ...
4 12 36 108 ...
8 24 72 ...
16 ...
.......
-}
Now we're getting somewhere. At least now none are skipped. We just need to understand how to join them into one sorted, increasing stream of numbers. Simple concat of course won't do. We need to merge them in order. A well-known function merge does that, provided the arguments are already ordered, increasing lists.
Each row produced is already in increasing order, but there are infinitely many of them. Never fear, foldr can do it. We define
mults23 = foldr g [] [[2^x * 3^y | y <- [0..]] | x <- [0..]]
-- foldr g [] [a,b,c,...] == a `g` (b `g` (c `g` (....)))
where
g (x:xs) ys =
Here it is a little bit tricky. If we define g = merge, we'll have a run-away recursion, because each merge will want to know the head element of its "right" (second) argument stream.
To prevent that, we produce the leftmost element right away.
x : merge xs ys
And that's that.
Tool use
I needed an infinite Cartesian product function. An infinite function must take the diagonals of a table.
The pair pattern of a diagonal traversal is
0 0 – 0 1, 1 0 – 0 2, 1 1, 2 0 – 0 3, 1 2, 2 1, 3 0
I love the symmetries but the pattern is counting forward with first digit and backward with second which when expressed in an infinite function is
diag2 xs ys = [ (m,n) | i<- [1..], (m,n) <- zip (take i xs) (reverse.take i $ ys) ]
The infinite generation is just to take any amount however large to work with.
What may be important, also is taking a diagonal or triangular number for a complete set.
revt n makes a triangular number from you input. If you want 25 elements revt 25 will return 7. tri 7 will return 28 the parameter for take. revt and tri are
tri n = foldl (+) 1 [2..n]
revt n = floor (sqrt (n*2))
Making and using taket is good until you learn the first 10 or so triangular numbers.
taket n xs = take (tri $ revt n) xs
Now, with some tools in place we apply them (mostly 1) to a problem.
[ 2^a * 3^b | (a,b) <- sort.taket 25 $ diag2 [0..] [0..]]
[1,3,9,27,81,243,729, 2,6,18,54,162,486, 4,12,36,108,324, 8,24,72,216, 16,48,144, 32,96, 64]
And it’s a diagonal. The first group is 7 long, the second is 6 long, the second-to-the-last is 2 long and the last is 1 long. revt 25 is 7. tri 7 is 28 the length of the output list.

How to use list comprehension in Haskell?

I am trying to teach myself Haskell and I am doing random exercises.
I was supposed to write a code that will do this 6 = [1*1 + 3*3 + 5*5]= 35
So I had to filter out all odd numbers and then calculate the sum if I multiply every single one with itself.
sumquad n = (potenzsum(filter odd (ones n)))
where
potenzsum [x] = x*x
potenzsum [x,y] = x*x + y*y
potenzsum (x:xs) = x + potenzsum xs
ones 0 = []
ones x = [ 1 .. x]
This code works ;)
Now I am supposed to do the same thing but with list comprehension (I am allowed to use this list [1...n]
I could only think of this... Could someone help me?
power1 xs = [x*x | x <- xs]
Actually, you did half the job by [x * x | x <- xs], just replace xs by odd numbers from the previous example:
[x * x | x <- filter odd (ones 6))]
And you'll receive a list of squares: [1, 9, 25], which can be summed by function sum:
f n = sum [x * x | x <- filter odd (ones n))]
it evaluates to 35
One more note regarding list comprehension: the iterated elements can be filtered out by specifying conditions, which are called guards. Thus, the code above can be refactored into:
f n = sum [x * x | x <- [1..n], odd x]

Testing if an inputted Int is a perfect number

I've been looking into perfect numbers, and I found this interesting bit of code on rosettacode:
perfect n = n == sum [i | i <- [1..n-1], n `mod` i == 0]
Now, I understand what a perfect number is, and I know which numbers are considered perfect, however I'm struggling to work out which parts of this code do what.
I understand that it's working out the factors of the inputted number, and combining them together to see if it matches the input itself, but I'm not sure how it's doing this.
If anyone could possibly break down this bit of code in a beginner-friendly manner I'd be very appreciative.
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^^^^^^
For i from 1 to n-1 (that is, [1, 2, 3, 4 ... n-1])
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^^^
And only for those values where i evenly divides n. Discarding values that do not match this requirement.
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^
Include i in the result list.
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^
Add the elements of this list together.
n == sum [i | i <- [1..n-1], n `mod` i == 0]
^^^^
And return True iff the total equals n.
[i | i <- [1..n-1], n `mod` i == 0]
Starting from the middle, you can read it like this: for each element i of the [1..n-1] list, check if n `mod` i equals 0. If it does, include i in the result list (that's the part to the left of the |. Without using the list comprehension syntax, that might be written using the filter function:
filter (\i -> n `mod` i == 0)
The elements of the resulting list are then added with sum, and, finally, the sum is tested for equality with n.

Why does my prime factorization function append 1 to the result?

I am creating a function to factorize any given number in haskell. And so i have created this:
primes :: [Integer]
primes = 2:(sieve [3,5..])
where
sieve (p:xs) = p : sieve [x |x <- xs, x `mod` ((p+1) `div` 2 ) > 0]
factorize 2 = [2]
factorize x
| divisible x = w:(factorize (x `div` w))
| otherwise = [x]
where
divisible :: Integer -> Bool
divisible y = [x |x <- (2:[3,5..y]), y `mod` x == 0] /= []
firstfactor :: Integer -> [Integer] -> Integer
firstfactor a (x:xs)
| a `ifdiv` x = x
| otherwise = firstfactor a xs
firstfactor a _ = a
ifdiv x y = mod x y == 0
w = firstfactor x primes
The function works fine, but appends 1 to the end of the list, for example factorize 80 would give this list: [2,2,2,2,5,1] My question is, why does this happen?
This comes up from two parts of the code. Firstly, factorize 1 is [1]. Secondly, since x is always divisible by itself, your very final call will always have w == x, so the recursion will be w:(factorize (w `div` w)) which is always w:(factorize 1).
To solve this, you can just add an extra base case to throw out the factors of 1:
factorize 1 = []
factorize ...
Also, you can drop the factorize 2 = [2] case because it gets subsumed by the otherwise case you already have.
factorize 1 = [] makes sense mathematically, because 1 has no prime factors (remember that 1 is not a prime number itself!). This follows the same logic behind product [] = 1—1 is the identity for multiplication, which makes it the "default" value when you have nothing to multiply.

Finding primes using Sieve of Eratosthenes not working - Haskell

Here is the code I am trying to use: This should generate all primes up to 100
sieve_primes = [x | x<-[2..100], y<-[2..50], z <-[2..25], (x*z) `mod` y /= 0]
The code
isPrime n = length [x | x<-[2..n], n `mod` x == 0] == 1
computes all the factors just to count them. You don't need to count them: as soon as the second factor is found you can stop your search without checking for further ones.
So, either replace length ... == 1 with a custom predicate, or take 2 elements from the list comprehension before checking its length.
What you had in mind was probably
Prelude> [x| x<-[2..100], not $ elem x [y*z| y<-[2..50], z<-[2..25]]]
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
This is very slow. At least we can rearrange the pieces,
Prelude> [x| let sieve=[y*z| y<-[2..50], z<-[2..25]],
x<-[2..100], not $ elem x sieve]
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
This is still very slow, for any number much above even 1000 (where you'd use 500 and 250). Then again, why the 25 (250) limit? Your code follows the
primes = [x| x<-[2..], not $ elem x
[y*z| y<-[2..x`div`2], z<-[2..min y (x`div`y)]]]
idea, i.e. y*z = 2*y .. min (y*y) x, so with the known top limit (x <= n) it should be
primesTo n = [x| let sieve=[y*z| y<-[2..n`div`2], z<-[2..min y (n`div`y)]],
x<-[2..n], not $ elem x sieve]
(incidentally, max (min y (n/y)) {y=2..n/2} = sqrt n, so we could've used 10 instead of 25, (and 31 instead of 250, for the 1000)).
Now 1000 is not a problem, only above ~ 10,000 we again begin to see that it's slow (still), running at n2.05..2.10 empirical orders of growth (quick testing interpreted code in GHCi at n = 5000, 10000, 15000).
As for your second (now deleted) function, it can be rewritten, step by step improving its speed, as
isPrime n = length [x | x<-[2..n], n `mod` x == 0] == 1
= take 1 [x | x<-[2..n], n `mod` x == 0] == [n]
= [x | x<- takeWhile ((<=n).(^2)) [2..n], n `mod` x == 0] == []
= and [n `mod` x > 0 | x<- takeWhile ((<=n).(^2)) (2:[3,5..n])]
now, compiled, it can get first 10,000 primes in few tenths of a second.

Resources