]> pd.if.org Git - scripts/commitdiff
added program to find consecutive partitions
authorNathan Wagner <nw@hydaspes.if.org>
Sat, 11 Mar 2017 09:49:31 +0000 (03:49 -0600)
committerNathan Wagner <nw@hydaspes.if.org>
Sat, 11 Mar 2017 09:49:31 +0000 (03:49 -0600)
conseqpart.c [new file with mode: 0644]

diff --git a/conseqpart.c b/conseqpart.c
new file mode 100644 (file)
index 0000000..8d5904c
--- /dev/null
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/*
+ * observations:
+ *
+ * solutions of any length L starting at b have the sum
+ * S = L * (L-1 + 2b ) / 2 
+ *
+ * This sum must equal the target t, so the base for a given length is
+ * t = L * (L-1+2b) / 2
+ * b = (2t/L-L+1)/2
+ *
+ * Since b must be an integer, t % ( (L+1)*L / 2 ) must equal 0
+ * 2t % L must be zero and
+ * 2t/L - L + 1 must be even
+ *
+ * With a minimum base of 1, the sum is (L+1)*L / 2, 
+ * which must not exceed the target
+ * t >= (L+1)*L/2
+ * L <= (sqrt(8t+1)-1) / 2
+ *
+ * Even targets must have solution lengths >= 3
+ * even length solutions can start on any number
+ * odd length solutions must be centered on an even number
+ *
+ * Odd targets must have an odd number of odd numbers
+ * in the solution
+ * they always have an even length solution of t/2 + t/2 + 1
+ *
+ */
+int main(int ac, char *av[]) {
+       unsigned target; /* number to decompose */
+       unsigned sbase; /* lowest number in solution */
+       unsigned slen; /*  N quantity of numbers in solution */
+       int oddtarget;
+       unsigned maxlen;
+
+       target = atoi(av[1]);
+
+       maxlen = (sqrt(8.0*target+1.0)-1) / 2;
+       oddtarget = target % 2;
+
+       if (oddtarget) {
+               printf("2 %d .. %d\n", target/2, target/2+1);
+       }
+
+       for (slen=3; slen <= maxlen; slen++) {
+               if (oddtarget && (slen % 2 == 0 && (slen/2 % 2 == 0))) {
+                       continue;
+               }
+
+               if (2 * target % slen != 0) {
+                       continue;
+               }
+               if ( (2 * target / slen - slen + 1) % 2 != 0) {
+                       continue;
+               }
+               sbase = (2 * target / slen - slen + 1) / 2;
+       
+               printf("%d %d .. %d\n", slen, sbase, sbase+slen-1);
+       }
+
+       return 0;
+}