Explanation of specific list comprehension in Haskell - haskell

I've a question regarding list comprehension
[(x,y)| x<-[1..2], y<-[x..3], let z = x+y, odd z]
Why does this evaluate to:
[(1,2),(2,3)]
?
Where is the z going?
Thanks

Your predicate is "z = x + y for all z odd". If you "unroll" the flow:
z = predicate, and y(x) so for:
x = 1,2
y (1) = 1,2,3
y (2) = 2,3
Based on the combination of the values filtered by the predicate:
x+y <= filter(z)
1+1 = 2 NO
1+2 = 3 OK
1+3 = 4 NO
2+2 = 4 NO
2+3 = 5 OK
so the ok answers are for x = 1 and y = 2 and x = 2 and y =3 => [(1,2), (2,3)]

Related

Show result in Haskell

I'm very new to haskell.
How can I return (x1,x2) and print it out from my code?
qqq x
| x < 0 x1 = mod (-x) 10
| 1 < x && x < 99 x1 = mod x 10
| x2 = mod x 10
You are using guards the wrong way. You seem to see these as if statements, that you then can use for assignements. In Haskell, you do not assign values to a variable, you declare these. You can work with:
qqq :: Integral a => a -> (a, a)
qqq x
| x < 0 = (mod (-x) 10, x2)
| 1 < x && x < 99 = (mod x 10, x2)
where x2 = mod x 10
Here each guard thus has a condition before the equation sign (=), and at the right side returns a 2-tuple with as first item an expression for x1, and as second item x2.
You should also implement extra case(s) for x == 1 and x >= 99, these are not covered by the two guards.

Write a function that lists numbers from n to m by k number of steps. If the step size is negative list them in descending order

Implement the interval2 :: Int -> Int -> Int -> [Int] function,that lists numbers from the first parameter to the third parameter, the stepping's size is the second parameter. Using [n..m], [n,k..m] or [n..] is prohibited.
For example:
interval2 1 1 10 == [1,2..10]
interval2 10 1 0 == [10,11..0]
interval2 10 (-1) 0 == [10,9..0]
interval2 1 2 10 == [1,3..10]
interval2 10 2 0 == [10,12..0]
interval2 0 (-2) (-10) == [0,(-2)..(-10)]
interval2 1 (-1) 10 == [1,0..10]
interval2 0 (-10) (-1000) == [0,(-10)..(-1000)]
So far, I've managed to write some cases, but they didn't do the job very well.
interval2 x y z | x < z && y > 0 = [x] ++ interval2 (x+y) y z
| x < z && y < 0 = [x] ++ interval2 (x-y) y z
| x > z && y > 0 = [x] ++ interval2 (x-y) y z
| x > z && y < 0 = [x] ++ interval2 (x+y) y z
| x == z || x > z = [z]
There are basically two cases when you should emit a new value:
if x <= z and y > 0; and
if x >= z and y < 0.
In both cases that means the list contains x as first element and should recurse on the interval with x+y. In case none of these conditions are not met, then we have reached the end of the list.
This thus means that the function looks like:
interval2 x y z
| (x <= z && y > 0) || (x >= z && y < 0) = …
| otherwise = …
where I leave implementing … as an exercise.
Naming is important. When learning, naming is very important.
What is x? What is y? What is z? Are all of them the same, conceptually?
No, as the exercise describes it, it is
interval2 :: Int -> Int -> Int -> [Int]
interval2 from stepSize to =
this already gets you half way there towards the solution. Yes it does.
Or actually, you have a contradiction. According to the title of your post, it is
interval2b :: Int -> Int -> Int -> [Int]
interval2b from numSteps to =
But in any case, solving the first one first, you seem to get lost in the multitude of tests. Instead of doing all of them in one function, why not do a test to decide which of several functions to use to do the job; then write each of those functions being already able to assume certain things, namely those which we've tested for:
interval2 from stepSize to
| stepSize > 0 = increasing from
| stepSize < 0 = decreasing from
| otherwise = []
where
increasing from
| from
and now it is easy to see which test to perform here, isn't it?
> to = []
| otherwise = from : increasing ....
decreasing from
| from
and similarly here.
.........
..................
I hope this helps you manage this complexity so you'll be able to complete this code yourself.

What's the code to swap variable values using AND, OR, NOT

I need a code to swap the value of two variables without using third variable but only with AND, OR & NOT operators
I have tried it but i always lost one value
Exact code
a = 1
b = 2
# swap
a, b = b, a
For integers, you can use xor:
x = x ^ y
y = x ^ y
x = x ^ y
But otherwise you should just stick to standard swapping practice:
x, y = y, x
The code above creates the tuple (y, x) and unpacks it to x and y
>>> a = 5
>>> b = 6
>>> a+=b
>>> b = a - b
>>> a = a - b
>>> a
6
>>> b
5
>>>
As the pythonic approach and the arithmetic approach have already been submitted as answers, I will present the bitwise xor approach, as outlined on wikipedia:
a = a ^ b
b = b ^ a
a = a ^ b
Of course, you can simplify that if you want:
a ^= b
b ^= a
a ^= b
It's really important to note that this only works on things that can be represented bitwise, like integers. Python will raise an error if you try it on floats or strings or most other datatypes.

Avoiding repeats while printing 'n' int

I'm trying to print only products of 3 and 5 if x < 1000. I'm getting a lot of repeats. How do I make sure that I don't have any repeats?
for x in range(1000):
y = 3
z = 5
a = x % y
b = x % z
if a == 0:
print (x)
if b == 0:
print (y)
You need to combine the two conditions with disjunction (or):
for x in range(1000):
y = 3
z = 5
a = x % y
b = x % z
if a == 0 or b == 0:
print (x)

Where is the mistake in this tail recursive Haskell function?

I have to implement a sum function in Haskell in two ways. One function with tail recursion and the other without tail recursion.
Here is the one without tail recursion and it works perfectly
sum1 x = if x==0 then 0 else x + sum1(x-1)
Here is my attempt with tail recursion and it doesn't work:
sum2 x = help 0 y
help x y = if y==0 then x else help(x+y,y-1)
Can someone point out the mistake?
Your line:
help x y = if y==0 then x else help(x+y,y-1)
is not the correct syntax for calling a function. Because here the Haskell compiler will interpret it as:
help x y = if y==0 then x else help (x+y,y-1)
-- ^ a tuple
Instead you should write:
help x y = if y==0 then x else help (x+y) (y-1)
-- ^ two arguments
Furthermore you can also use guards, like:
helper x y | y == 0 = x
| otherwise = help (x+y) (y-1)
Finally there is also an error in the first line of sum2. It should be x instead of y:
sum2 x = help 0 x
So in full, we get:
sum2 x = help 0 x
helper s x | x == 0 = s
| otherwise = help (s+x) (x-1)
I also renamed y in the helper to x and x to s (as in sum) to make it less confusing (kudos to #Bergi for commenting on this).
Or use an eta reduction:
sum2 = help 0
Finally note that you do not need recursion for this. An implementation that would work faster is the following:
sum3 x = div (x*(x+1)) 2
Since:
n
---
\ (n+1) n
/ i = -------
--- 2
i=1

Resources