Ad
  • Custom User Avatar

    Ah okay. Thanks.

  • Custom User Avatar

    That means solvers need to give more ratings and rankings.

  • Custom User Avatar

    I just noticed that the Beta Status for this kata still says 'Testing and feedback needed'. I thought I had taken care of the testing on this, but please do let me know if there is something else required. Thanks.

  • Custom User Avatar

    Got it. Thanks again for all your help.

  • Custom User Avatar

    Yes, minding that .slice() only copies on the first level of its argument, so if you are passing an Array of Arrays, you should be passing in arg.map( sub => sub.slice() ) ( .map() returns a new Array on the first level, .slice() on the second ). As Unnamed said, there are alternatives for true deep cloning, but this'll work for the job at hand.

  • Custom User Avatar

    Wow, thank you for taking the time to write all that. So let me make sure I get this: because arrays are passed by reference in JavaScript, modifications to the array from within the function will of course also change the array from outside of the function. So I should pass in deep copies of the array using the slice function. Is that correct?

  • Custom User Avatar

    Hi again. My background is with Java so I'm pretty familiar with OOP. I was speaking from the point of view of encapsulation. Having said that, the properties in my JavaScript version are public so I suppose I've no cause to question the public variables in your translation!
    Thanks for the link on C# naming guidelines. I didn't know they differed from Java in that way.

  • Custom User Avatar

    Hi, the methods being used are on a class because, like Java, C# is a strictly OOP language and everything is done inside a class. Variables being public also allow them to be accessed outside the class itself.

    As for the capitalization of properties/methods, they follow C# member naming guidelines which specify that public properties/methods should be PascalCased, which you can see here.

  • Custom User Avatar

    Hiya. I hope this doesn't come across as pedantic, and I'm not that familiar with C#, but should the variable names be public and starting with a capital letter? Or are getters & setters considered to be overkill for this kind of challenge? Thought I'd better check what I was approving first!

  • Custom User Avatar

    Array.prototype.slice and Object.assign make shallow copies; for deep copying there are cloneDeep in lodash or JSON.parse(JSON.stringify()) as a quick hack.

  • Custom User Avatar

    Hi AtomicTanuki, make sure you press the "Approve" button on that page.

  • Custom User Avatar

    Basically, yes.

    The expected value being an unchanged array was not actually unchanged. All odd subarrays were being reversed twice, so it looked unchanged. It was an artifact of reusing the argument from the user solution to the reference solution. So that'll go away if you fix the modification vulnerability. ( I had forgotten that .reverse() changes its argument in place, and I was not taking into account subarrays could be reused as well as the outer array. I thought I was safe because I returned a new copy of the outer array. )

    The way to fix that has been explained on countless other first ( and later ) kata, but here goes again ( sigh .. ) :

    Give user a copy of any Object random input argument, and/or calculate the expected value first. Make damn sure the reference solution is not modifying its argument, or give the reference solution its own copy of the original.

    Short story long(er): when passing arguments, JavaScript passes non-primitive arguments ( i.e., all Objects, including Arrays ) by reference. If you change properties of that argument in your function, the caller sees his variable change as well. Primitive values are safe from this ( either because they are passed by value, or because they are immutable. I'm not sure any more which one is the actual reason, but passing primitive Strings, Numbers and Booleans is safe ).

    Creating deep copies of Arrays can be accomplished with a.slice(), of Objects with Object.assign({},o), other objects, custom ones and such, you may need to go through the appropriate constructor again.

    Whenever you are passing arguments other than primitive values, you should be on your toes to make damn sure your reference solution does not modify its argument(s) and your tests are immune to it being done by the user solution. Your reference solution for this kata does not modify its arguments ( kudos! ); your testing is vulnerable. Implement either of the fixes mentioned above, and you're good to go.

  • Custom User Avatar

    I'm not sure what to do about that. Is it always necessary to have random tests when writing a kata?

  • Custom User Avatar

    See my solution. If I change the input parameter in my solution, the modified argument is used to calculate the expected output.

    I had already looked at your testing code. I said it was unclear to me why the random tests were expecting an unmodified array, and it still is.

  • Custom User Avatar

    Hmmm. I'm not quite sure what you mean by 'vulnerable to input modification'.
    I have basically randomized the number of 'matches' that are passed into the function.
    It's probably considered hacky, but this is the test that I wrote:

    for (let i = 0; i < 200; i++) {
    let matches = [];
    let limit = Math.floor(Math.random() * 20)
    for (let j = 0; j < limit; j++) {
    matches.push(['C1','C2']);
    }
    Test.assertDeepEquals(contestantSwapper(matches), contestantSwapperCheck(matches));
    }

  • Loading more items...