Home > Back-end >  Write a function that lists numbers from n to m by k number of steps. If the step size is negative l
Write a function that lists numbers from n to m by k number of steps. If the step size is negative l

Time:10-24

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]

CodePudding user response:

There are basically two cases when you should emit a new value:

  1. if x <= z and y > 0; and
  2. 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.

CodePudding user response:

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.

  • Related