[Issue 14223] TimSort algorithm is incorrect
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Tue Feb 24 13:48:10 PST 2015
https://issues.dlang.org/show_bug.cgi?id=14223
Ketmar Dark <ketmar at ketmar.no-ip.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |ketmar at ketmar.no-ip.org
--- Comment #1 from Ketmar Dark <ketmar at ketmar.no-ip.org> ---
a possible patch:
fixes TimSort implementation, according to
http://envisage-project.eu/proving-android-java-and-python-sorting-algorithm-is-broken-and-how-to-fix-it/
diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d
index a71eb47..f40e957 100644
--- a/std/algorithm/sorting.d
+++ b/std/algorithm/sorting.d
@@ -1230,21 +1230,21 @@ private template TimSortImpl(alias pred, R)
while (stackLen > 1)
{
immutable run3 = stackLen - 1;
- immutable run2 = stackLen - 2;
+ auto run2 = stackLen - 2;
immutable run1 = stackLen - 3;
- if (stackLen >= 3 && stack[run1].length <= stack[run2].length
+ stack[run3].length)
+ immutable run0 = stackLen - 4;
+ if ((stackLen >= 3 && stack[run1].length <= stack[run2].length
+ stack[run3].length) ||
+ (stackLen >= 4 && stack[run0].length <= stack[run2].length
+ stack[run1].length))
{
- immutable at = stack[run1].length <= stack[run3].length
- ? run1 : run2;
- mergeAt(range, stack[0 .. stackLen], at, minGallop, temp);
- --stackLen;
+ if (stack[run1].length < stack[run3].length)
+ --run2;
}
- else if (stack[run2].length <= stack[run3].length)
+ else if (stackLen < 2 || stack[run2].length >
stack[run3].length)
{
- mergeAt(range, stack[0 .. stackLen], run2, minGallop,
temp);
- --stackLen;
+ break; // invariant is established
}
- else break;
+ mergeAt(range, stack[0 .. stackLen], run2, minGallop, temp);
+ --stackLen;
}
}
i haven't analyzed the code, though, and didn't run any unittests besides the
simplest ones, so i can't guarantee that i did it right.
so hereby i sommon someone more knowledgeable to properly check it.
--
More information about the Digitalmars-d-bugs
mailing list