#include #include #include struct term { int32_t value; uint32_t pusher; }; struct change { uint32_t index; struct term contents; }; struct term *generate(uint32_t count) { uint32_t A = count > 10000 ? count : 10000; struct term *terms = calloc(A * 3, sizeof(*terms)); terms[0].value = 2; terms[0].pusher = 0; uint64_t *used = calloc(A >> 6, sizeof(*used)); uint32_t i = 0; while (i < count) { while (terms[++i].pusher); struct change changes[256]; changes[0].index = i; changes[0].contents = terms[i]; uint32_t j = 3; for (;;) { for (int_fast8_t invalid = 1; invalid;) { while ((used[j>>6] >> (j & 0x3F)) & 1) { j++; } for (uint32_t t = i;; t += terms[t+1].value) { if (terms[t-1+j].pusher) { j++; break; } if (terms[t+1].value <= 0) { invalid = 0; break; } } } terms[i].value = j; uint32_t change_index = 1; uint32_t current_index = 0; while (current_index < change_index) { uint32_t p = changes[current_index].index; if (terms[p].value > 0) { uint32_t n = p - 1 + terms[p].value; if (terms[n].pusher && terms[n].pusher != p) { goto undo; } if (!((terms[n].value == terms[p-1].value) && (terms[n].pusher == p))) { if (terms[p-1].value == 0) { changes[change_index].index = p - 1; changes[change_index].contents = terms[p-1]; change_index++; terms[p-1].value = -(p-1); } changes[change_index].index = n; changes[change_index].contents = terms[n]; change_index++; terms[n].value = terms[p-1].value; terms[n].pusher = p; if ((terms[n+1].pusher && (terms[n+1].value == terms[p+1].value)) || (terms[n-1].pusher && (terms[n].value == terms[terms[n-1].pusher+1].value))) { goto undo; } } } if (terms[p+1].value > 0) { uint32_t n = p + terms[p+1].value; if (terms[n].pusher && (terms[n].pusher != p + 1)) { goto undo; } if (!((terms[n].value == terms[p].value) && (terms[n].pusher == p + 1))) { changes[change_index].index = n; changes[change_index].contents = terms[n]; change_index++; terms[n].value = terms[p].value; terms[n].pusher = p + 1; if ((terms[n+1].pusher && (terms[n+1].value == terms[p+2].value)) || (terms[n-1].pusher && (terms[n].value == terms[terms[n-1].pusher+1].value))) { goto undo; } } } current_index++; } break; undo: while (--change_index) { terms[changes[change_index].index] = changes[change_index].contents; } j++; } used[j>>6] |= (1ULL << (j & 0x3F)); } free(used); return terms; } int main(int argc, char **argv) { if (argc == 2) { uint32_t count = atoi(argv[1]); if (count) { struct term *terms = generate(count); printf("%d", terms[0].value); for (uint32_t i = 1; i < count; i++) { printf(", %d", terms[i].value); } free(terms); } } printf("\n"); return 0; }