Beta

Arithmetic Sequence - find hidden

34 of 43Zymurge
Description
Loading description...
Algorithms
  • Please sign in or sign up to leave a comment.
  • saudiGuy Avatar
    • python new test frameworks to be used
    • missing useful imports
  • Blind4Basics Avatar

    edge cases needed:

    test.assert_equals(find_arithmetic_sequence([2,3,1,4]),[1,2,3])
    test.assert_equals(find_arithmetic_sequence([816, 428, 446, 459, 471, 486, 496, 511, 527, 537, 551, 564, 819, 594, 607, 616, 631, 646, 662, 674, 687, 698, 716, 724, 740, 755, 813, 778, 794, 808, 821, 837]),[446, 631, 816])
    
    test.assert_equals(find_arithmetic_sequence([265, 279, 295, 811, 321, 330, 346, 808, 371, 388, 398, 414, 425, 443, 814]), [808, 811, 814])
    test.assert_equals(find_arithmetic_sequence([893, 368, 382, 890, 408, 896, 434, 449], [890, 893, 896])
    

    note: I didn't "explore" the solution suggested by Johan, so you'll have to dig on this side too

  • JohanWiltink Avatar

    This solution has a bug. But the fixed test cases don't catch it, and the randoms only catch it occasionally.

    A fixed test should be added that catches it. Use a failing random test for that. That's another think random tests are good for: finding edge cases, not necessarily in your own solution(s) but in everybody's. ( It would have been nice to get this heads up from that author, but maybe he totally missed the bug. )

  • Blind4Basics Avatar

    This comment has been hidden.

    • Zymurge Avatar

      Well played sir!

      I didn't mean to imply that sorted couldn't work, since it takes extra effort to find all possible solutions and then reevaluate those against their original indexes.

      The question for me is if this then leads to higher performance, as gained from the ability to walk a sorted list.

      Question marked resolved by Zymurge 6 years ago
    • JohanWiltink Avatar

      Specifically that solution may fail a test with [1,4,7,2,3]. That should return [1,4,7], no?

    • JohanWiltink Avatar

      That solution is still O(n^3), is it not? Not an improvement over non-sorting then.

  • JohanWiltink Avatar

    ( JS )

    • Learn to use the testing framework. Use assertDeepEquals instead of assertSimilar, don't reinvent the wheel that is randomize, and use correct headers: tests inside it inside describe. You might also use Chai, which is the current State of the Art ( but doesn't have randomize ).
    • Declare your variables ( correctly ). for ( i=0; i<10; i++ ) implicitly declares i as GLOBAL, which means solutions, as well as your own code somewhere else, can change it. Also, for constants, use const instead of let. Do not use var at all.

    I have mostly fixed this for you but I can't promise I didn't miss something somewhere.

    • Blind4Basics Avatar

      Do not use var at all.

      reason, plz? (trying to gather knowledge, here x) )

    • user8436785 Avatar

      @B4B: It's not a "bad practice" in ES5, but in ES6, var is not that good a practice, you should use let or const instead. ES6 is used on Codewars => var is not a that good practice.

    • Blind4Basics Avatar

      errrr, ok, thx. But why? x) (aside from just the node version)

    • JohanWiltink Avatar

      let's scope is smaller than var's. let declares a variable in a block; var declares it in a function ( for the WHOLE body! ). So in

      function _() {
        for ( var i=0; .. )
          for ( var i=0; .. )
            {}
      }
      

      the inner loop will not behave as you might expect. ( It might actually be the outer one that doesn't. It's such a mess I don't want to figure it out. Just use let. ) ( Actually, I think both misbehave. The inner loop runs 10 times, the outer one once, but the inner loop silently ignores var. Silently ignoring things is ++UnGood. )

      There are subtleties, of course ( this is JS, after all! ), but the simple version is "don't use var".

    • Zymurge Avatar

      Great feedback, thanks! I got away from JS for a year or so while having fun with Go and now Python. let vs var is indeed good form!

      I'll also look into your fork and learn the superior test methods and provided features (didn't know randomize was a thing!)

    • Zymurge Avatar

      Thanks much for all the help. Went with most of what you changed and cleaned up more.

      Suggestion marked resolved by Zymurge 6 years ago
  • Blind4Basics Avatar

    Hi,

    • python: make the solution setup runnable, plz

    • a lot of missing edge cases in the fixed tests. I've rewriten my algo 4 times, each one passing all the current fixed tests. Meaning that, as said before, there aren't enough fixed tests, but that means the description either doesn't give enough info (not the case) too, or doesn't give them in a clear enough way (the info is too far diluted, here ).

      for example:   [360, 825, 391, 405, 414, 428, 442, 454, 828, 486, 822]
                     [414, 428, 442] should equal [822, 825, 828]
      
    • reading it closer, either the description or the reference solution is actually wrong: such that the first member of the sequence will have the lowest indexed first member from the array, according to the case above (...or I just don't get that sentence... :/ )

    • Zymurge Avatar

      I think you are correct on my wording being misleading or plain wrong. What I meant to say was that moving from left to right through the array, priorty is on elements of the solution array found first -- not specific of the order in the final array. So in the referenced case above, 825 is part of the answer and is the leftmost element of any in a valid solution.

      Would changing the wording to below help clarify?

      such that the first located member of the sequence will have the lowest indexed first member from the array

    • Blind4Basics Avatar

      maybe something more like:

      find the triplet whose one element is at the lowest possible index in the original array

      ?

    • Zymurge Avatar

      This would be inaccurate. It's any element must be lower indexed than any element from other triplets. Or the second lowest indexed element in the case of a tie for the first. Words are hard! That's why I put these two specific examples in the text:

      • [99,11,4,7,9,1] returns [7,9,11]
        • the first valid sequence
          • member 11 at index 1 for set[7,9,11]
          • member 4 at index 2 for set[1,4,7]
      • [13,20,17,9,27] returns [13,20,27]
        • the first valid sequence
          • member 13 at index 0 for both valid sets [9,13,17] and [13,20,27]
          • second member 20 at index 1 for set [13,20,27]
          • second member 17 at index 2 for set [9,13,17]

      Are those not clarifying enough?

    • JohanWiltink Avatar

      The problem with specifying by example is it might allow for a wrong interpretation - because we can't read your mind.

      The 99 in the first example is not helping, so it should go. To me, those examples clarify that indices do not have to be in order, but not everyone may get that. I agree specifying it correctly, completely and concisely is hard. But relying on examples is not the way to go IMO. Examples should not be used to specify, only to clarify. I'll try to think of words.

    • Zymurge Avatar

      99 is Wayne Gretzky's retired number. It's ALWAYS appropriate to include :)

      But really, I added it just to give a case where the first index isn't 0. Good feedback that it muddies more than helps though.

    • JohanWiltink Avatar

      Except in an ice hockey team then?

      It might help someone see that the first index need not be 0. I wasn't worried about that, but someone else might be. See the problem with examples?

    • Blind4Basics Avatar

      mmmmh... I didn't even read that part... x) (formatting is somewhat horrible. Nobody will reach that part of the description, I guess, if you don't make it clear there is something important to grasp here).

      Sooo, that would be somehting like

          Return the first triplet (sorted by values) satisfying the conditions.
          If there are several possbilities choose the triplet so that its indexes
          in the original array would be minimal (like for a key function comparison):
      
              [99,11,4,7,1,200,9] returns [7,9,11] because:
          
                [11,7,9] is a possible triplet, but [4,7,1] too
                indexes: (1,3,6) < (2,3,4) because of the 1
                returns [7,9,11] (sorted)
              
              
              [17,20,13,9,27] returns [13,20,27] because:
          
                [17,13,9] is a possible triplet, but [17,20,13] too
                indexes: (0,2,3) > (0,1,2) because of the 1
                returns [13,20,27] (sorted)
      

      edit: I don't like that part: (like for a key function comparison). But didn't find something better...

    • JohanWiltink Avatar

      except it isn't (0,2,3). and mixing < and > is confusing.

      Personally, I would rather focus on a correct spec than on improved examples.

    • Blind4Basics Avatar

      woops, that's because I changed the arrays allong the way. The </> thing is coming from python. Might not be general enough, yes. Any help about the first §? (because the spec is there, actually x) )

      edit: wait... How that it's not (0,2,3)???

    • JohanWiltink Avatar

      [13,20,27] from [17,20,13,9,27] would give (1,2,4), not (0,2,3) ?

    • JohanWiltink Avatar

      Your code should find the first valid Arithmetic Sequence that can be constructed from any 3 integers in the group

      This is confusing, because that would imply sorting by the lowest highest index first. ( That's the first sequence you find completely. )

      "Your code should find the sequence whose indices are lexicographically lowest" ?

      It's jargony, but correct ( I think ), and the examples can clarify ( which is what they are for ).

    • Blind4Basics Avatar

      oh damn... let's make the "alignments" clearer (maybe...):

          (put some good worded specs here x) )
      
      
              For [99,11,4,7,1,200,9]:
          
                possible triplets:          [11,7,9] and [4,7,1]
                indexes:                    (1, 3,6)     (2,3,4)  
                returns the sorted triplet: [7,9,11], because lexicographically (1,3,6) < (2,3,4)
              
              
              For [17,20,21,9,13]:
          
                possible triplets:          [17,9,13] and [17,21,13]
                indexes:                    ( 0,3, 4)     ( 0, 2, 4)
                returns the sorted triplet: [13,17,21], because lexicographically (0,3,4) > (0,2,4)
      

      ?

    • JohanWiltink Avatar

      Where does that 27 come from ?!?

    • Blind4Basics Avatar

      what the hell did I do... x/

      Wait a sec

    • Zymurge Avatar

      Those examples are much clearer, thanks! I was about to say if it's so hard to explain, then maybe lose the requirement :-) But then that would make it somewhat easier to solve.

  • Voile Avatar

    Needs random tests.

    • Zymurge Avatar

      Added. First time doing so, and it's more code than my solution :-)

    • Voile Avatar

      You should put random tests in a loop and not write multiple copies of test_random ;-)

      Also there should be more random tests. Typically 100 random tests is done.

    • Zymurge Avatar

      From my point of view, the role of the random test is to prevent hardcoding answers to the tests that can be discovered through failures. So in theory just one should do the trick. What's the point of having 100? I'd rather preserve cycles on the servers if it's not adding real value.

      I chose the few that I added to cover a couple different sized lists with and without an expected sequence to be found. I would think that's sufficient coverage unless I'm missing something.

    • Voile Avatar

      What's the point of having a 100?

      Ensure correctness? You only have like a few fixed tests and it's very far from comprehensive.

      I'd rather preserve cycles on the servers if it's not adding real value

      How many cycles do you think you'd save by that anyway? ;-) That sounds just like those premature optimizations, not to mention it's not really our business. It's the CW owners who should worry about that.

      Also, don't take my words for it, but it's established kata practices that everyone is following. Why'd you try to do it differently when everyone's doing the same?

    • Zymurge Avatar

      You make a lot of good points. It would be trivial to add the loop and bang out 100 or so random.

      As for why I care, by profession I'm usually heading engineering orgs and like to think big picture. Part of that is to challenge the status quo and ask questions if an existing practice still makes sense, especially when multiplied by some large number due to scale. I get that optimizing CW is not my concern, but old habits die hard :-)

      FYI -- the above it part of why I'm here. After too many years managing I'm trying to get back some of my coding chops and also learning the languages that all the cool kids are coding in these days.

    • Zymurge Avatar

      Fixed

      Issue marked resolved by Zymurge 6 years ago
  • Voile Avatar

    Function argument should not be named set, that's a built-in type.

    • Zymurge Avatar

      Fixed. Thanks. I'm pretty new to Python.

    • Voile Avatar

      Shouldn't it be something like lst? The input isn't even a set, it's a list of unique integers.

      The description needs update too, it also says "set of unique integers" everywhere.

    • Zymurge Avatar

      Clearly I really like sets :-) I mean, it is a set in mathemtical terms, but not necessarily in Python terms. I don't want to use the term list, since I plan to port this to several more languages, and lists aren't always a native feature. Would array be a better generic term?

    • Voile Avatar

      Arrays and lists means roughly the same thing in almost all languages. Sets and lists are definitely different no matter which language you're talking about though, because in computer science they mean completely different data structures with very different characteristics. You can choose to either use array or list, but set is definitely wrong there ;-)

    • Zymurge Avatar

      Agreed on that. I replaced the word set with either group or array depending on the context. That should be less misleading for the Python version specifically. I haven't tried porting to another language yet but assume that you only get one description to rule them all, so will need to keep it language agnostic.

      FYI - I plan to add JS and Go next. I'm pretty rusty in most of the other language options here.

    • Zymurge Avatar

      Fixed

      Issue marked resolved by Zymurge 6 years ago