From 758c174cae899c37bcdc716f779ff6264e75612c Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Tue, 30 Aug 2022 18:39:36 -0400 Subject: [PATCH] =?UTF-8?q?Optimistic=20special=20case=20to=20quickly=20in?= =?UTF-8?q?vert=20permutations=20with=20=E2=8D=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/grade.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/builtins/grade.h b/src/builtins/grade.h index 95aaca74..afca9910 100644 --- a/src/builtins/grade.h +++ b/src/builtins/grade.h @@ -220,13 +220,22 @@ B GRADE_CAT(c1)(B t, B x) { if (xe==el_i32 || xe==el_c32) { // safe to use the same comparison for i32 & c32 as c32 is 0≤x≤1114111 i32* xp = tyany_ptr(x); i32 min=I32_MAX, max=I32_MIN; + i32 sum=0; for (usz i = 0; i < ia; i++) { i32 c = xp[i]; + sum += c; if (cmax) max=c; } i64 range = max - (i64)min + 1; if (range/2 < ia) { + // First try to invert it as a permutation + if (range==ia && sum==(i32)((i64)ia*(min+max)/2)) { + for (usz i = 0; i < ia; i++) rp[i]=ia; + for (usz i = 0; i < ia; i++) { i32 v=xp[i]; GRADE_UD(rp[v-min],rp[max-v])=i; } + bool done=1; for (usz i = 0; i < ia; i++) done &= rp[i]!=ia; + if (done) { decG(x); return r; } + } TALLOC(usz, tmp, range+1); for (i64 i = 0; i < range+1; i++) tmp[i] = 0; GRADE_UD( // i32 range-based