From 3df745afcfd51da1a18a18f5960c7e5db65e1730 Mon Sep 17 00:00:00 2001 From: Exxion Date: Tue, 12 Apr 2022 17:17:57 -0400 Subject: [PATCH] Fast macro-based heapsort (#32381) --- __DEFINES/sort.dm | 33 +++++++++++++++++++++++++++++++++ vgstation13.dme | 1 + 2 files changed, 34 insertions(+) create mode 100644 __DEFINES/sort.dm diff --git a/__DEFINES/sort.dm b/__DEFINES/sort.dm new file mode 100644 index 00000000000..792d555fdaa --- /dev/null +++ b/__DEFINES/sort.dm @@ -0,0 +1,33 @@ +#define SIFT_DOWN(L, comparison, n, i) do { \ +var/SIFT_DOWN_largest = i; \ +var/SIFT_DOWN_i; \ +do { \ + SIFT_DOWN_i = SIFT_DOWN_largest; \ + var/SIFT_DOWN_l = 2 * SIFT_DOWN_largest; \ + var/SIFT_DOWN_r = SIFT_DOWN_l + 1; \ + if(SIFT_DOWN_l <= n) { \ + if(comparison(L[SIFT_DOWN_l], L[SIFT_DOWN_largest])) { \ + SIFT_DOWN_largest = SIFT_DOWN_l; \ + } \ + if((SIFT_DOWN_r <= n) && comparison(L[SIFT_DOWN_r], L[SIFT_DOWN_largest])) { \ + SIFT_DOWN_largest = SIFT_DOWN_r; \ + } \ + } \ + L.Swap(SIFT_DOWN_i, SIFT_DOWN_largest); \ +} while(SIFT_DOWN_largest != SIFT_DOWN_i);} while(FALSE) + +#define SORT(L, comparison) do { \ +var/SORT_N = L.len; \ +for(var/SORT_i in round(SORT_N / 2) to 1 step -1) { \ + SIFT_DOWN(L, comparison, SORT_N, SORT_i); \ +} \ +for(var/SORT_i in SORT_N to 2 step -1) { \ + L.Swap(1, SORT_i); \ + SIFT_DOWN(L, comparison, SORT_i - 1, 1); \ +}} while(FALSE) + +#define GREATER(a, b) (a > b) +#define LESS(a, b) (a < b) + +#define SORT_ASC(L) SORT(L, GREATER) +#define SORT_DSC(L) SORT(L, LESS) diff --git a/vgstation13.dme b/vgstation13.dme index 22686290e3d..b8f487bacb6 100644 --- a/vgstation13.dme +++ b/vgstation13.dme @@ -66,6 +66,7 @@ #include "__DEFINES\silicon.dm" #include "__DEFINES\simple_animal_defines.dm" #include "__DEFINES\snow.dm" +#include "__DEFINES\sort.dm" #include "__DEFINES\spell_defines.dm" #include "__DEFINES\striketeam_defines.dm" #include "__DEFINES\stylesheet.dm"