#include "common.h"

static unsigned int m;

#define ELEMENT(i, j) (1 + (i)*(1 << m) + (j))

static void z_curve(uint start_i, uint start_j, uint n)
{
    if (n==0) {
#ifdef DEBUG        
        printf("%u %u ", start_i, start_j);
#else
        printf("%u  ", ELEMENT(start_i, start_j));
#endif
    }
    else if (n==1) {
        /* This is not really necessary, but we also directly solve for m=1,
         * as a possible aid to understanding */
#ifdef DEBUG
        printf("(%u %u)  (%u %u)  (%u %u)  (%u %u)  ", start_i, start_j,
               start_i, start_j+1,
               start_i+1,   start_j,
               start_i+1, start_j+1);
#else
        printf("%u  %u  %u  %u  ",
               ELEMENT(start_i, start_j),
               ELEMENT(start_i, (start_j+1)),
               ELEMENT((start_i+1),   start_j),
               ELEMENT((start_i+1), (start_j+1)));
#endif
    }
    else {
        n = n-1;
        z_curve(start_i,        start_j,        n);
        z_curve(start_i,        start_j+(1<<n), n);
        z_curve(start_i+(1<<n), start_j,        n);
        z_curve(start_i+(1<<n), start_j+(1<<n), n);
    }

    return;
}


int main(int ac, char *av[])
{
    if (ac < 2)
        ERR_MESG("Usage: z_curve <m>");

    m = atoi(av[1]);
    z_curve(0, 0, m);
    putchar('\n');

    return 0;
}
