5 kyu

Haskell List Dot Notation

473 of 474surtich
Description
Loading description...
Functional Programming
Arrays
Algorithms
  • Please sign in or sign up to leave a comment.
  • ejini战神 Avatar

    These edge cases should also be tested since they are present in example tests:

    • [1..9,12..15] -- invalid since one single range is allowed

    • [1,2..20,25] -- invalid since a range has to be the final item

    • [1,2,3..20] -- invalid since at most one inidivual element can be provided before a range

  • trashy_incel Avatar

    assertSimilar is deprecated, use assertDeepEquals

  • Joec05 Avatar

    the empty list test is confusing. coded it if options generator is an empty string to return an empty array and it deemed the empty list undefined in the output? since when is an empty string undefined?

  • B1ts Avatar

    It's very disappointing to see great description, examples, just to find out that you only need to implement a fraction of the given task. And then, no random tests...

  • Voile Avatar

    Needs random tests

  • Azuaron Avatar

    This comment has been hidden.

    • akar-0 Avatar

      I agree. And I would add that I see no point in using a map instead of a single string as argument.

  • EDave Avatar

    The first point in "[1.3..7]" is supposed to be a comma, right?

  • wthit56 Avatar

    Would be nice to add the generator expression to the error messages.

  • wthit56 Avatar

    Is a default negative step used? So that [5..1] == [5,4,3,2,1], or does this result in [1]?

    • wthit56 Avatar

      Looks like it isn't. Might be worth putting that into the description. Really enjoyed this one. Good job.

      Question marked resolved by wthit56 11 years ago
  • user3482173 Avatar

    The logic behind the .. notation is a bit counter-intuitive, you should describe it a bit more. I am used to notation like a:step:b or from a to b by step.

    Here you use (correct me if I am wrong): a,c..b to say from a to b by step with step = c - a.

    • surtich Avatar

      [1..5] // Goesforward step one 1,2,3,4,5 [1.3..7] // Goes forward step two (3 - 1). SO 1,3,5,7 [5..3] // Bad, if the step is not one, Haskell calculates it [index1] - [index 0] [6,5..3] // Goes backward step -1 (5 - 6) 6,5,4,3 [6,4..0] // Goes backward step -2 (4 -6) 6, 4, 2, 0

      Is tt best explained like this?

      Thanks for your commet.

    • nivoliev Avatar

      What about ['1,2..6,8..11,10..0'] ? and ['1,1..10'] ? My current solution infinitely loops on the last one.

    • wthit56 Avatar

      I thought I understood it, until I saw this explanation. Would really be useful if you just explained the whole thing. It's pretty hard to grasp, even with your more detailed code comments.

      If I've figured it out correctly... @nivolviev's examples should go like this: 1,2..6,8..11,10..0 == [1,2,3,4,5,6,8,10,11,10,9,8,7,6,5,4,3,2,1,0] 1,1..10 == (bad form, defaults to 1) [1,1,2,3,4,5,6,7,8,9,10]

      Okay, now I've really confused myself @.@"

    • surtich Avatar

      Both are right, the explanation is not very good but my English either. Sorry.

      I added more tests and improved the explanation with more examples. I hope now you understand it better.

      Sorry, nivoliev, your solution is not valid now.

    • nivoliev Avatar

      No problem. I find it weird now that 1,3..4 gives [1,3] whereas 3,4..0 gives [3]. What is the behaviour of 1,2..2 and 3,2..2 then ?

      I believe you should define formal specifications for the descriptor, something like "a valid descriptor is made of a (possibly empty) list of individual numeric elements, plus a single optional final range with format 'start..end', where start and end are numbers. A range is increasing if end ≥ start, decreasing otherwise. The provided individual elements provide the first elements of the output list. The range elements are appended to these, and are defined using a step. The step is defined as start-a, where a is the last individual element provided. In case no individual element is provided, the step is 1. An increasing (resp. decreasing) range with a negative (resp. positive) step is empty. Otherwise the elements of the range are defined as start + k * step, with k starting at 0 and increasing one by one as long as the result is in between start and end."

    • surtich Avatar

      These are the answers at your questions tested against my Haskell console:

      Test.assertSimilar(ArrayComprehension({generator: '1,3..4'}), [1,3]); Test.assertSimilar(ArrayComprehension({generator: '1,2..2'}), [1,2]); Test.assertSimilar(ArrayComprehension({generator: '3,2..2'}), [3,2]); Test.assertSimilar(ArrayComprehension({generator: '3,4..0'}), []); // I think this is nonsense and I not going to add this test.

      Thanks a lot for your help. I would not know how to explain it so well. I copied it verbatim in the exercise.

    • nivoliev Avatar

      Since the ranges in both 1,2..2 and 3,2..2 contain 2, the specification I described is wrong about increasing and decreasing sequences. It should say that a sequence is constant if start === end, increasing if start < end and decreasing otherwise. It should also be added somewhere that a constant sequence has one single element, which is its start. In the text, I used the word descriptor, while you use generator in the kata description. Finally, given your example, I also realize from your examples that if a range is provided, only one single individual element is allowed. I would therefore reformulate my previous description as

      A valid generator can be either

      • a list of individual elements : the resulting list is the list made of the individual elements as in classical Javascript
      • a range in the form 'start..end' : if end >= start, the list is [start, start+1, start+2, ..., end] otherwise the result is []
      • a single element a followed by a range : let step = start - a
        • if start === end the list is [a,start]
        • if step is positive and end > start then the list is [a, a+step, a+2*step, ...] as long as a+k*step <= end
        • if step is negative and end < start then the list is [a, a+step, a+2*step, ...] as long as a-k*step >= end
        • otherwise the list is []

      I would put the examples after the formal definition, and maybe use

      [2,3,-5,3] // just like in JavaScript : [2,3,-5,3]
      [1..5] // goes forward with step 1 : [1,2,3,4,5]
      [1.3..7] // goes forward with step 2 (3 - 1) : [1,3,5,7]
      [6,5..3] // goes back with step -1 = (5 - 6) : [6,5,4,3]
      [6,4..0] // goes back with step -2 = (4 -6) : [6, 4, 2, 0]
      [5..3] // default step is 1 while the range is decreasing : []
      [10,1..10] // goes back with step -9 for an increasing range : [10]
      [1,1..10] // goes forwaed with step is 0 = ( 1 - 1) : infitite list [1,1,...]. Do not worry about this case in this kata for this, we will deal with it in the third part.
      [1..9,12..15] // invalid since one single range is allowed
      [1,2..20,25] // invalid since a range has to be the final item
      [1,2,3..20] // invalid since at most one inidivual element can be provided before a range
      
    • surtich Avatar

      Wow! That's a lot of work! You are really helping me a lot. I think this is much more clean now. Thank you very much.

    • user3482173 Avatar

      What is the logic behind 8,4..40 => [8] ? Negative step and increasing range should return [], no ?

    • surtich Avatar

      Yes, you are right.By the moment I have commented this test because my solution does not pass this test.