/* $begin 340-recurse-proto-c */ long rfun(unsigned long x) { if ( ____ ) return _____; unsigned long nx = _____; long rv = rfun(nx); return _____; }
/* $begin 340-recurse-c */ long rfun(unsigned long x) { if (x == 0) return 0; unsigned long nx = x>>2; long rv = rfun(nx); return x + rv; }
static int rfun(int* c, int* f, int n, int target, MyNode** head, int count) { int cv = *c; if (cv > target) { return 0; } int sum = 0; int tdiv = target / cv; int tmod = target % cv; if (!n || !tmod) { breakme(); if (tmod) return 0; MyNode* node = (MyNode*)malloc(sizeof(MyNode)); if (node) { int total = count + tdiv; int* match = (int*)malloc(sizeof(int) * total); if (match) { int* pf; int* pc; node->next = *head; node->cmb = match; node->cmbSize = total; *f = tdiv; int* p = match + total; for (pf = f, pc = c; total > 0; pf--, pc--) { int i = *pf; total -= i; for (; i > 0; i--) { *(--p) = *pc; } } *head = node; #ifdef MY_UNIT_TEST static int ID = 0; printf("CMB %d count %d:", ID++, (total = count + tdiv)); for (int i = 0; i < total; i++) { printf(",%d", node->cmb[i]); } printf("\n"); #endif sum = 1; } else { free(node); } } if (!n || !sum) return sum; tdiv--; } int nt, nc = c[1]; for (int i = tdiv; i >= 0; i--) { *f = i; nt = (target - (i * cv)); if (nc <= nt) { sum += rfun(c + 1, f + 1, n - 1, nt, head, count + i); } } return sum; }
void m_fn2(R p1) { R a = p1; rfun(p1); fun(this); fun(a); }
//4ms version static int rfun(int* c, int* f, int n, int target, MyNode** head, int count) { int cv = *c; if ((cv > target) || (n < 0)) { breakme(); return 0; } int sum = 0; if (!n || (target == cv)) { breakme(); if (target != cv) return 0; MyNode* node = (MyNode*)malloc(sizeof(MyNode)); if (node) { int total = count + 1; int* match = (int*)malloc(sizeof(int) * total); if (match) { int* pf; int* pc; node->next = *head; node->cmb = match; node->cmbSize = total; *f = 1; int* p = match + total; for (pf = f, pc = c; total > 0; pf--, pc--) { int i = *pf; total -= i; for (; i > 0; i--) { *(--p) = *pc; } } total = node->cmbSize; #ifdef MY_UNIT_TEST static int ID = 0; printf("CMB %d count %d:", ID++, total); for (int i = 0; i < total; i++) { printf(",%d", node->cmb[i]); } printf("\n"); #endif MyNode* prev = *head; DBG("Curr %p cmbSize %d\n", node, total); DBG("Prev %p cmbSize %d\n", prev, prev ? prev->cmbSize : 0); while (prev != NULL) { if ((prev->cmbSize == total) && !memcmp(prev->cmb, match, total * sizeof(int))) { DBG("Duplicate result detected, discarding...\n"); free(match); free(node); return 0; } prev = prev->next; } *head = node; sum = 1; DBG("Good result detected, collecting...\n"); } else { free(node); } } return sum; } { int nt = target - cv; if (cv <= target) { if (c[1] <= nt) { *f = 1; sum = rfun(c + 1, f + 1, n - 1, nt, head, count + 1); } *f = 0; sum += rfun(c + 1, f + 1, n - 1, target, head, count); }/* *f = 1; sum = rfun(c + 1, f + 1, n - 1, nt, head, count + 1); *f = 0; sum += rfun(c + 1, f + 1, n - 1, target, head, count);*/ } return sum; }