//
// fat_arr.c
//
// Fat pointer array
//

#include <stdio.h>
#include <stdlib.h>

#define ARR_INIT_CAP 2
#define ARR_GROW_RAT 2

#define TYPE int

typedef TYPE *ARR;

ARR  arrnew(void);
ARR  arrnewcap(int);
void arrdelete(ARR);
ARR  arrappend(ARR, TYPE);
ARR  arrresize(ARR, int);
TYPE arrremove(ARR);
int  arrlen(ARR);
int  arrcap(ARR);

inline ARR
arrnew(void)
{
    return arrnewcap(ARR_INIT_CAP);
}

inline ARR
arrnewcap(int cap)
{
    int *buf;

    if ((buf = malloc(cap * sizeof(TYPE) + 2 * sizeof(int))) == NULL) {
        return NULL;
    }

    buf[0] = 0;
    buf[1] = cap;

    return (ARR)(buf + 2);
}

inline void
arrdelete(ARR arr)
{
    free((int *)arr - 2);
}

inline ARR
arrappend(ARR arr, TYPE val)
{
    int *buf, len, cap;

    buf = (int *)arr - 2;
    len = buf[0];
    cap = buf[1];

    if (cap <= len && (arr = arrresize(arr, cap * ARR_GROW_RAT)) == NULL) {
        return NULL;
    }

    buf = (int *)arr - 2;
    arr[buf[0]++] = val;

    return arr;
}

inline ARR
arrresize(ARR arr, int ncap)
{
    int *buf, len;

    buf = (int *)arr - 2;
    len = buf[0];

    if ((buf = realloc(buf, ncap * sizeof(TYPE) + 2 * sizeof(int))) == NULL) {
        return NULL;
    }

    buf[0] = len;
    buf[1] = ncap;

    return (ARR)(buf + 2);
}

inline TYPE
arrremove(ARR arr)
{
    return arr[--((int *)arr - 2)[0]];
}

inline int
arrlen(ARR arr)
{
    return ((int *)arr - 2)[0];
}

inline int
arrcap(ARR arr)
{
    return ((int *)arr - 2)[1];
}

////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>

#define LIMIT 100

int a = 0;
int b = 1;

int get(void)
{
    int tmp = a;
    a = b;
    b = tmp + b;
    return tmp;
}

void process(int i)
{
    printf("%d\n", i);
}

int main(int argc, char *argv[])
{
    int i, num;

    int limit = argc < 2 ? LIMIT : atoi(argv[1]);

    int *arr = arrnew();

    while ((num = get()) < limit) {
        arr = arrappend(arr, num);
    }

    for (i = 0; i < arrlen(arr); ++i) {
        process(arr[i]);
    }

    for (i = arrlen(arr)-1; i > 0; --i) {
        arr[i] -= arr[i-1];
    }

    for (i = arrlen(arr)-1; i >= 0; --i) {
        process(arrremove(arr));
    }

    arrdelete(arr);

    return 0;
}