4 ms·
Interestingly it apparently takes a sorting routine to test sorting routines. It's not the first time I ended up wondering whether testing something rigorously
by contravariant 4y ago
Interestingly it apparently takes a sorting routine to test sorting routines.
It's not the first time I ended up wondering whether testing something rigorously is actually easier than implementing it correctly.
- adrianN 4y agoMany problems have tricky, performant solutions and simple, slow solutions. Comparing to a simple reference implementation is a very good way to test. For some problems it is much easier to check that the result is correct than to find the result (that's what P and NP are about for example). Sorting is one of these problems. You can check that one list is a permutation of another list in linear time. Comparing against a library implementation of sorting is just simpler in many languages.
- nayuki 4y ago> it apparently takes a sorting routine to test sorting routines You don't have to sort to check sortedness. boolean isSorted(int[] original, int[] sorted) { if (original.length != sorted.length) return false; for (int i = 0; i < original.length; i++) { if (i > 0 && sorted[i] < sorted[i - 1]) return false; if (countInstances(original[i], original) != countIntasnces(original[i], sorted)) return false; } return true; } int countInstances(int value, int[] array) { int count = 0; for (int v : array) { if (v == value) count++; } return count; } I know that bubble sort, selection sort, and insertion sort can be implemented in about half the code as this. But this code is read-only and is more obviously correct than trying to prove an algorithm that mutates the array.
- tialaramex 4y agoSo far as I can tell, isSorted([0, 0, 0], [4, 20, 0, 0, 0]) is true (the code doesn't care about values in sorted which never occur in original and doesn't check these arrays are the same length) But isSorted([10, 5, 0], [0, 5, 10]) is false (for some reason the code checks that original is sorted, rather than sorted...) That's OK though, the original exercise exists because most programmers can't get even basic algorithms right, so you're helping to demonstrate that.
- nayuki 4y agoI fixed two silly mistakes thanks to your comment! Added at the beginning of isSorted(): if (original.length != sorted.length) return false; Changed the wrong ordering check: if (i > 0 && original[i] < original[i - 1]) > most programmers can't get even basic algorithms right, so you're helping to demonstrate that Now this puts my entire body of published work into question...
- Schroedingersat 4y agoAdditionally your issorted is n^2 which may not finish if you're testing an nlogn sorting algorithm.
- tialaramex 4y agoIt occurs to me that the "you're helping" might read as snark and it wasn't really intended that way, or at least, not as snark at you, but rather all of us. It's silly to reject help from e.g. peer review, static analysis, smarter / safer languages. If you look at some tool and say "What kind of idiot would make the mistakes this catches?" the answer is almost certainly "idiots like you".
- samatman 4y agoDoes it? I'm seeing two O(n) processes: one to confirm order and the other to confirm permutation of set. In almost-Lua pseudocode: function isOrdered(array, predicate) -- zero and one length arrays are trivially ordered if len(array) < 2 then return true end local ordered = true for i = 0, len(array) - 1 do ordered = ordered and predicate(array[i], array + 1) end return ordered end function popCount(array) local pops = {} for item in iterate(array) do pops = pops[item] and pops[item] + 1 or 1 end return pops end Then you compare the two popcounts, if they're the same and the result is in-order then something made them that way.