#define ARRAY_TERMINATE 0
#define TRIGGER 'x'
#define REST '.'

// Will accomodate up to 64 long patterns
// If you want to handle larger sets, you probably need to rewrite this code
// to use dynamic arrays instead
int bjorklun_buffer[64][65];

int zarray_count(int arr[]) {
  int counter = 0;
  while (arr[counter] != ARRAY_TERMINATE) {
    counter++;
  }
  return counter;
}

void zarray_concat(int target[], int source[]) {
  int target_size = zarray_count(target);
  int counter = 0;
  while (source[counter] != ARRAY_TERMINATE) {
    target[target_size + counter] = source[counter];
    counter++;
  }
  target[target_size + counter] = ARRAY_TERMINATE;
}

// Usage:
//   int pattern[14];
//   bjorklund_calculate(13, 5, pattern);
//   int length = zarray_count(pattern);
//   for (int i=0; i < length; i++) {
//     print((char)pattern[i]);
//   }
void bjorklund_calculate(int length, int density, int output[]) {
  if (density > length || density < 1) {
    for (int i=0; i < length; i++) {
      output[i] = REST;
    }
    output[length] = ARRAY_TERMINATE;
    return;
  }  
  // Init arrays
  // Ex. l = 8 and d = 5
  // [1] [1] [1] [1] [1] [0] [0] [0]
  int width = length - 1;
  for (int i=0; i < length; i++) {
    bjorklun_buffer[i][0] = i < density ? TRIGGER : REST;
    bjorklun_buffer[i][1] = ARRAY_TERMINATE;    
  }
  int target, remainder_size;
  while (true) {
    if (width == 0) {
      break;
    }
    if (bjorklun_buffer[width][0] == REST) {
      // zero remainder
      target = 0;
      while (bjorklun_buffer[width][0] == REST && bjorklun_buffer[target][0] != REST) {
        zarray_concat(bjorklun_buffer[target], bjorklun_buffer[width]);
        target++;
        width--;
      }
    } else {
      // pattern-remainder?
      remainder_size = zarray_count(bjorklun_buffer[width]);
      if (remainder_size == zarray_count(bjorklun_buffer[0])) {
        // no remainder present
        break;
      }
      if (remainder_size != zarray_count(bjorklun_buffer[width-1])) {
        // we have reached a core
        break;
      }
      target = 0;
      while (zarray_count(bjorklun_buffer[width]) == remainder_size && zarray_count(bjorklun_buffer[target]) != remainder_size) {
        zarray_concat(bjorklun_buffer[target], bjorklun_buffer[width]);
        target++;
        width--;
      }
    }
  }

  // collapse rows into output
  for (int i=0; i <= width; i++) {
    zarray_concat(output, bjorklun_buffer[i]);
  }
}