WeixiangYan/CodeTransOcean huggingface dataset:
Task: Ormiston triples

C: #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <locale.h>

bool *sieve(uint64_t limit) {
    uint64_t i, p;
    limit++;
    
    bool *c = calloc(limit, sizeof(bool)); 
    c[0] = true;
    c[1] = true;
    for (i = 4; i < limit; i += 2) c[i] = true;
    p = 3; 
    while (true) {
        uint64_t p2 = p * p;
        if (p2 >= limit) break;
        for (i = p2; i < limit; i += 2 * p) c[i] = true;
        while (true) {
            p += 2;
            if (!c[p]) break;
        }
    }
    return c;
}

typedef struct {
    char digs[20];
    int count;
} digits;

digits getDigits(uint64_t n) {
    if (n == 0) return (digits){ {0}, 1 };
    digits d;
    d.count = 0;
    while (n > 0) {
        d.digs[d.count++] = n % 10;
        n = n / 10;
    }
    return d; 
}

int main() {
    const uint64_t limit = 10000000000;
    uint64_t i, j, pc = 0, p1, p2, p3, key1, key2, key3;
    int k, count, count2;
    digits d;
    bool *c = sieve(limit);
    for (i = 0; i < limit; ++i) {
        if (!c[i]) ++pc;
    }
    uint64_t *primes = (uint64_t *)malloc(pc * sizeof(uint64_t));
    for (i = 0, j = 0; i < limit; ++i) {
        if (!c[i]) primes[j++] = i;
    }
    free(c);
    uint64_t orm25[25];
    int counts[2];
    j = limit/10;
    for (i = 0; i < pc-2; ++i) {
        p1 = primes[i];
        p2 = primes[i+1];
        p3 = primes[i+2];
        if ((p2 - p1) % 18 || (p3 - p2) % 18) continue;
        key1 = 1;
        d = getDigits(p1);
        for (k = 0; k < d.count; ++k) key1 *= primes[d.digs[k]];
        key2 = 1;
        d = getDigits(p2);
        for (k = 0; k < d.count; ++k) key2 *= primes[d.digs[k]];
        if (key1 != key2) continue;
        key3 = 1;
        d = getDigits(p3);
        for (k = 0; k < d.count; ++k) key3 *= primes[d.digs[k]];
        if (key2 == key3) {
            if (count < 25) orm25[count] = p1;
            if (p1 >= j) {
                counts[count2++] = count;
                j *= 10;
            }
            ++count;
        }
    }
    counts[count2] = count;
    printf("Smallest members of first 25 Ormiston triples:\n");
    setlocale(LC_NUMERIC, "");
    for (i = 0; i < 25; ++i) {
        printf("%'10ld  ", orm25[i]);
        if (!((i+1) % 5)) printf("\n");
    }
    printf("\n");
    j = limit/10;
    for (i = 0; i < 2; ++i) {
        printf("%'d Ormiston triples before %'ld\n", counts[i], j);
        j *= 10;
        printf("\n");
    }
    free(primes);
    return 0;
}
Task: Ormiston pairs

C: #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <locale.h>

bool *sieve(int limit) {
    int i, p;
    limit++;
    
    bool *c = calloc(limit, sizeof(bool)); 
    c[0] = true;
    c[1] = true;
    for (i = 4; i < limit; i += 2) c[i] = true;
    p = 3; 
    while (true) {
        int p2 = p * p;
        if (p2 >= limit) break;
        for (i = p2; i < limit; i += 2 * p) c[i] = true;
        while (true) {
            p += 2;
            if (!c[p]) break;
        }
    }
    return c;
}

typedef struct {
    char digs[20];
    int count;
} digits;

digits getDigits(int n) {
    if (n == 0) return (digits){ {0}, 1 };
    digits d;
    d.count = 0;
    while (n > 0) {
        d.digs[d.count++] = n % 10;
        n = n / 10;
    }
    return d; 
}

typedef struct {
    int x;
    int y;
} pair;

int main() {
    const int limit = 1000000000;
    int i, j, k, pc = 0, count = 0, count2 = 0, p1, p2, key1, key2;
    digits d;
    bool *c = sieve(limit);
    for (i = 0; i < limit; ++i) {
        if (!c[i]) ++pc;
    }
    int *primes = (int *)malloc(pc * sizeof(int));
    for (i = 0, j = 0; i < limit; ++i) {
        if (!c[i]) primes[j++] = i;
    }
    pair orm30[30];
    int counts[5];
    j = 100000;
    for (i = 0; i < pc-1; ++i) {
        p1 = primes[i];
        p2 = primes[i+1];
        if ((p2 - p1) % 18) continue;
        key1 = 1;
        d = getDigits(p1);
        for (k = 0; k < d.count; ++k) key1 *= primes[d.digs[k]];
        key2 = 1;
        d = getDigits(p2);
        for (k = 0; k < d.count; ++k) key2 *= primes[d.digs[k]];
        if (key1 == key2) {
            if (count < 30) orm30[count] = (pair){p1, p2};
            if (p1 >= j) {
                counts[count2++] = count;
                j *= 10;
            }
            ++count;
        }
    }
    counts[count2] = count;
    printf("First 30 Ormiston pairs:\n");
    setlocale(LC_NUMERIC, "");
    for (i = 0; i < 30; ++i) {
        printf("[%'6d, %'6d] ", orm30[i].x, orm30[i].y);
        if (!((i+1) % 3)) printf("\n");
    }
    printf("\n");
    j = 100000;
    for (i = 0; i < 5; ++i) {
        printf("%'d Ormiston pairs before %'d\n", counts[i], j);
        j *= 10;
    }
    free(c);
    free(primes);
    return 0;
}
Task: Doomsday rule

C: #include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

typedef struct { 
    uint16_t year;
    uint8_t month;
    uint8_t day;
} Date;

bool leap(uint16_t year) {
    return year%4==0 && (year%100!=0 || year%400==0);
}

const char *weekday(Date date) {
    static const uint8_t leapdoom[] = {4,1,7,2,4,6,4,1,5,3,7,5};
    static const uint8_t normdoom[] = {3,7,7,4,2,6,4,1,5,3,7,5};
    static const char *days[] = {
        "Sunday", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday"
    };
    
    unsigned c = date.year/100, r = date.year%100;
    unsigned s = r/12, t = r%12;
    
    unsigned c_anchor = (5 * (c%4) + 2) % 7;
    unsigned doom = (s + t + (t/4) + c_anchor) % 7;
    unsigned anchor = (leap(date.year) ? leapdoom : normdoom)[date.month-1];
    return days[(doom+date.day-anchor+7)%7];
}

int main(void) {
    const char *past = "was", *future = "will be";
    const char *months[] = { "",
        "January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December"
    };
    
    const Date dates[] = {
        {1800,1,6}, {1875,3,29}, {1915,12,7}, {1970,12,23}, {2043,5,14},
        {2077,2,12}, {2101,4,2}
    };
    
    int i;
    for (i=0; i < sizeof(dates)/sizeof(Date); i++) {
        printf("%s %d, %d %s on a %s.\n",
            months[dates[i].month], dates[i].day, dates[i].year,
            dates[i].year > 2021 ? future : past,
            weekday(dates[i]));
    }
    
    return 0;
}
Task: Gauss-Jordan matrix inversion

C: 
#include <math.h>
int gjinv (double *a, int n, double *b)
{
	int i, j, k, p;
	double f, g, tol;
	if (n < 1) return -1;  
	f = 0.;  
	for (i = 0; i < n; ++i) {
		for (j = 0; j < n; ++j) {
			g = a[j+i*n];
			f += g * g;
		}
	}
	f = sqrt(f);
	tol = f * 2.2204460492503131e-016;
	for (i = 0; i < n; ++i) {  
		for (j = 0; j < n; ++j) {
			b[j+i*n] = (i == j) ? 1. : 0.;
		}
	}
	for (k = 0; k < n; ++k) {  
		f = fabs(a[k+k*n]);  
		p = k;
		for (i = k+1; i < n; ++i) {
			g = fabs(a[k+i*n]);
			if (g > f) {
				f = g;
				p = i;
			}
		}
		if (f < tol) return 1;  
		if (p != k) {  
			for (j = k; j < n; ++j) {
				f = a[j+k*n];
				a[j+k*n] = a[j+p*n];
				a[j+p*n] = f;
			}
			for (j = 0; j < n; ++j) {
				f = b[j+k*n];
				b[j+k*n] = b[j+p*n];
				b[j+p*n] = f;
			}
		}
		f = 1. / a[k+k*n];  
		for (j = k; j < n; ++j) a[j+k*n] *= f;
		for (j = 0; j < n; ++j) b[j+k*n] *= f;
		for (i = 0; i < n; ++i) {  
			if (i == k) continue;
			f = a[k+i*n];
			for (j = k; j < n; ++j) a[j+i*n] -= a[j+k*n] * f;
			for (j = 0; j < n; ++j) b[j+i*n] -= b[j+k*n] * f;
		}
	}
	return 0;
}
Task: Numerical integration_Adaptive Simpson's method

C: #include <stdio.h>
#include <math.h>

typedef struct { double m; double fm; double simp; } triple;


triple _quad_simpsons_mem(double (*f)(double), double a, double fa, double b, double fb) {
    
    double m = (a + b) / 2;
    double fm = f(m);
    double simp = fabs(b - a) / 6 * (fa + 4*fm + fb);
    triple t = {m, fm, simp};
    return t;
}

double _quad_asr(double (*f)(double), double a, double fa, double b, double fb, double eps, double whole, double m, double fm) {
    
    
    triple lt = _quad_simpsons_mem(f, a, fa, m, fm);
    triple rt = _quad_simpsons_mem(f, m, fm, b, fb);
    double delta = lt.simp + rt.simp - whole;
    if (fabs(delta) <= eps * 15) return lt.simp + rt.simp + delta/15;
    return _quad_asr(f, a, fa, m, fm, eps/2, lt.simp, lt.m, lt.fm) +
           _quad_asr(f, m, fm, b, fb, eps/2, rt.simp, rt.m, rt.fm);
}

double quad_asr(double (*f)(double), double a, double b, double eps) {
    
    double fa = f(a);
    double fb = f(b);
    triple t = _quad_simpsons_mem(f, a, fa, b, fb);
    return _quad_asr(f, a, fa, b, fb, eps, t.simp, t.m, t.fm);
}

int main(){
    double a = 0.0, b = 1.0;
    double sinx = quad_asr(sin, a, b, 1e-09);
    printf("Simpson's integration of sine from %g to %g = %f\n", a, b, sinx);
    return 0;
}
Task: Colorful numbers

C: #include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>

bool colorful(int n) {
    
    if (n < 0 || n > 98765432)
        return false;
    int digit_count[10] = {};
    int digits[8] = {};
    int num_digits = 0;
    for (int m = n; m > 0; m /= 10) {
        int d = m % 10;
        if (n > 9 && (d == 0 || d == 1))
            return false;
        if (++digit_count[d] > 1)
            return false;
        digits[num_digits++] = d;
    }
    
    int products[36] = {};
    for (int i = 0, product_count = 0; i < num_digits; ++i) {
        for (int j = i, p = 1; j < num_digits; ++j) {
            p *= digits[j];
            for (int k = 0; k < product_count; ++k) {
                if (products[k] == p)
                    return false;
            }
            products[product_count++] = p;
        }
    }
    return true;
}

static int count[8];
static bool used[10];
static int largest = 0;

void count_colorful(int taken, int n, int digits) {
    if (taken == 0) {
        for (int d = 0; d < 10; ++d) {
            used[d] = true;
            count_colorful(d < 2 ? 9 : 1, d, 1);
            used[d] = false;
        }
    } else {
        if (colorful(n)) {
            ++count[digits - 1];
            if (n > largest)
                largest = n;
        }
        if (taken < 9) {
            for (int d = 2; d < 10; ++d) {
                if (!used[d]) {
                    used[d] = true;
                    count_colorful(taken + 1, n * 10 + d, digits + 1);
                    used[d] = false;
                }
            }
        }
    }
}

int main() {
    setlocale(LC_ALL, "");

    clock_t start = clock();

    printf("Colorful numbers less than 100:\n");
    for (int n = 0, count = 0; n < 100; ++n) {
        if (colorful(n))
            printf("%2d%c", n, ++count % 10 == 0 ? '\n' : ' ');
    }

    count_colorful(0, 0, 0);
    printf("\n\nLargest colorful number: %'d\n", largest);

    printf("\nCount of colorful numbers by number of digits:\n");
    int total = 0;
    for (int d = 0; d < 8; ++d) {
        printf("%d   %'d\n", d + 1, count[d]);
        total += count[d];
    }
    printf("\nTotal: %'d\n", total);

    clock_t end = clock();
    printf("\nElapsed time: %f seconds\n",
           (end - start + 0.0) / CLOCKS_PER_SEC);
    return 0;
}
Task: Generate random chess position

C: #include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define TRUE 1
#define FALSE 0

typedef int bool;

char grid[8][8];

void placeKings() {
    int r1, r2, c1, c2;
    for (;;) {
        r1 = rand() % 8;
        c1 = rand() % 8;
        r2 = rand() % 8;
        c2 = rand() % 8;
        if (r1 != r2 && abs(r1 - r2) > 1 && abs(c1 - c2) > 1) {
            grid[r1][c1] = 'K';
            grid[r2][c2] = 'k';
            return;
        }
    }
}

void placePieces(const char *pieces, bool isPawn) {
    int n, r, c;
    int numToPlace = rand() % strlen(pieces);
    for (n = 0; n < numToPlace; ++n) {
        do {
            r = rand() % 8;
            c = rand() % 8;
        }
        while (grid[r][c] != 0 || (isPawn && (r == 7 || r == 0)));
        grid[r][c] = pieces[n];
    }
}

void toFen() {
    char fen[80], ch;
    int r, c, countEmpty = 0, index = 0;
    for (r = 0; r < 8; ++r) {
        for (c = 0; c < 8; ++c) {
            ch = grid[r][c];
            printf("%2c ", ch == 0 ? '.' : ch);
            if (ch == 0) {
                countEmpty++;
            }
            else {
                if (countEmpty > 0) {
                    fen[index++] = countEmpty + 48;
                    countEmpty = 0;               
                }
                fen[index++] = ch;
            }
        }
        if (countEmpty > 0) {
            fen[index++] = countEmpty + 48;
            countEmpty = 0;
        }
        fen[index++]= '/';
        printf("\n");
    }
    strcpy(fen + index, " w - - 0 1");
    printf("%s\n", fen);
}

char *createFen() {
    placeKings();
    placePieces("PPPPPPPP", TRUE);
    placePieces("pppppppp", TRUE);
    placePieces("RNBQBNR", FALSE);
    placePieces("rnbqbnr", FALSE);
    toFen();
}

int main() {
    srand(time(NULL));
    createFen();
    return 0;
}
Task: Numbers which are the cube roots of the product of their proper divisors

C: #include <stdio.h>
#include <locale.h>

int divisorCount(int n) {
    int i, j, count = 0, k = !(n%2) ? 1 : 2;
    for (i = 1; i*i <= n; i += k) {
        if (!(n%i)) {
            ++count;
            j = n/i;
            if (j != i) ++count;
        }
    }
    return count;
}

int main() {
    int i, numbers50[50], count = 0, n = 1, dc;
    printf("First 50 numbers which are the cube roots of the products of their proper divisors:\n");
    setlocale(LC_NUMERIC, "");
    while (1) {
        dc = divisorCount(n);
        if (n == 1|| dc == 8) {
            ++count;
            if (count <= 50) {
                numbers50[count-1] = n;
                if (count == 50) {
                    for (i = 0; i < 50; ++i) {
                        printf("%3d ", numbers50[i]);
                        if (!((i+1) % 10)) printf("\n");
                    }
                }
            } else if (count == 500) {
                printf("\n500th   : %'d\n", n);
            } else if (count == 5000) {
                printf("5,000th : %'d\n", n);
            } else if (count == 50000) {
                printf("50,000th: %'d\n", n);
                break;
            }
        }
        ++n;
    }
    return 0;
}
Task: Arithmetic derivative

C: #include <stdio.h>
#include <stdint.h>

typedef uint64_t u64;

void primeFactors(u64 n, u64 *factors, int *length) {
    if (n < 2) return;
    int count = 0;
    int inc[8] = {4, 2, 4, 2, 4, 6, 2, 6};
    while (!(n%2)) {
        factors[count++] = 2;
        n /= 2;
    }
    while (!(n%3)) {
        factors[count++] = 3;
        n /= 3;
    }
    while (!(n%5)) {
        factors[count++] = 5;
        n /= 5;
    }
    for (u64 k = 7, i = 0; k*k <= n; ) {
        if (!(n%k)) {
            factors[count++] = k;
            n /= k;
        } else {
            k += inc[i];
            i = (i + 1) % 8;
        }
    }
    if (n > 1) {
        factors[count++] = n;
    }
    *length = count;
}

double D(double n) {
    if (n < 0) return -D(-n);
    if (n < 2) return 0;
    int i, length;
    double d;
    u64 f[80], g;
    if (n < 1e19) {
        primeFactors((u64)n, f, &length);
    } else {
        g = (u64)(n / 100);
        primeFactors(g, f, &length);
        f[length+1] = f[length] = 2;
        f[length+3] = f[length+2] = 5;
        length += 4;
    }
    if (length == 1) return 1;
    if (length == 2) return (double)(f[0] + f[1]);
    d = n / (double)f[0];
    return D(d) * (double)f[0] + d;
}

int main() {
    u64 ad[200];
    int n, m;
    double pow;
    for (n = -99; n < 101; ++n) {
        ad[n+99] = (int)D((double)n);
    }
    for (n = 0; n < 200; ++n) {
        printf("%4ld ", ad[n]);
        if (!((n+1)%10)) printf("\n");
    }
    printf("\n");
    pow = 1;
    for (m = 1; m < 21; ++m) {
        pow *= 10;
        printf("D(10^%-2d) / 7 = %.0f\n", m, D(pow)/7);
    }
    return 0;
}
Task: Product of min and max prime factors

C: #include <stdbool.h>
#include <stdio.h>
#include <string.h>

#define MAX 100

void sieve(bool *prime, int max) {
    memset(prime, true, max+1);
    prime[0] = prime[1] = false;
    
    for (int p=2; p*p<=max; p++)
        for (int c=p*p; c<=max; c+=p)
            prime[c] = false; 
}

int lo_fac(bool *prime, int n) {
    if (n==1) return 1;
    for (int f=2; f<=n; f++) 
        if (prime[f] && n%f == 0) return f;
    return n;
}

int hi_fac(bool *prime, int n) {
    if (n==1) return 1;
    for (int f=n; f>=2; f--)
        if (prime[f] && n%f == 0) return f;
    return n;
}

int main() {
    bool prime[MAX+1];
    sieve(prime, MAX);
    
    for (int i=1; i<=MAX; i++) {
        printf("%6d", lo_fac(prime, i) * hi_fac(prime, i));
        if (i%10 == 0) printf("\n");
    }
    return 0;
}
Task: Compiler_AST interpreter

C: 
count = 1;
n = 1;
limit = 100;
while (n < limit) {
    k=3;
    p=1;
    n=n+2;
    while ((k*k<=n) && (p)) {
        p=n/k*k!=n;
        k=k+2;
    }
    if (p) {
        print(n, " is prime\n");
        count = count + 1;
    }
}
print("Total primes found: ", count, "\n");
Task: Sorting algorithms_Tree sort on a linked list

C: #include <stdio.h>
#include <stdlib.h>
#include <time.h>

void fatal(const char* message) {
    fprintf(stderr, "%s\n", message);
    exit(1);
}

void* xmalloc(size_t n) {
    void* ptr = malloc(n);
    if (ptr == NULL)
        fatal("Out of memory");
    return ptr;
}

typedef struct node_tag {
    int item;
    struct node_tag* prev;
    struct node_tag* next;
} node_t;

void list_initialize(node_t* list) {
    list->prev = list;
    list->next = list;
}

void list_destroy(node_t* list) {
    node_t* n = list->next;
    while (n != list) {
        node_t* tmp = n->next;
        free(n);
        n = tmp;
    }
}

void list_append_node(node_t* list, node_t* node) {
    node_t* prev = list->prev;
    prev->next = node;
    list->prev = node;
    node->prev = prev;
    node->next = list;
}

void list_append_item(node_t* list, int item) {
    node_t* node = xmalloc(sizeof(node_t));
    node->item = item;
    list_append_node(list, node);
}

void list_print(node_t* list) {
    printf("[");
    node_t* n = list->next;
    if (n != list) {
        printf("%d", n->item);
        n = n->next;
    }
    for (; n != list; n = n->next)
        printf(", %d", n->item);
    printf("]\n");
}

void tree_insert(node_t** p, node_t* n) {
    while (*p != NULL) {
        if (n->item < (*p)->item)
            p = &(*p)->prev;
        else
            p = &(*p)->next;
    }
    *p = n;
}

void tree_to_list(node_t* list, node_t* node) {
    if (node == NULL)
        return;
    node_t* prev = node->prev;
    node_t* next = node->next;
    tree_to_list(list, prev);
    list_append_node(list, node);
    tree_to_list(list, next);
}

void tree_sort(node_t* list) {
    node_t* n = list->next;
    if (n == list)
        return;
    node_t* root = NULL;
    while (n != list) {
        node_t* next = n->next;
        n->next = n->prev = NULL;
        tree_insert(&root, n);
        n = next;
    }
    list_initialize(list);
    tree_to_list(list, root);
}

int main() {
    srand(time(0));
    node_t list;
    list_initialize(&list);
    for (int i = 0; i < 16; ++i)
        list_append_item(&list, rand() % 100);
    printf("before sort: ");
    list_print(&list);
    tree_sort(&list);
    printf(" after sort: ");
    list_print(&list);
    list_destroy(&list);
    return 0;
}
Task: Wordle comparison

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

void wordle(const char *answer, const char *guess, int *result) {
    int i, ix, n = strlen(guess);
    char *ptr;
    if (n != strlen(answer)) {
        printf("The words must be of the same length.\n");
        exit(1);
    }
    char answer2[n+1];
    strcpy(answer2, answer);
    for (i = 0; i < n; ++i) {
        if (guess[i] == answer2[i]) {
            answer2[i] = '\v';
            result[i] = 2;
        }
    }
    for (i = 0; i < n; ++i) {
        if ((ptr = strchr(answer2, guess[i])) != NULL) {
            ix = ptr - answer2;
            answer2[ix] = '\v';
            result[i] = 1;
        }
    }
}

int main() {
    int i, j;
    const char *answer, *guess;
    int res[5];
    const char *res2[5];
    const char *colors[3] = {"grey", "yellow", "green"};
    const char *pairs[5][2] = {
        {"ALLOW", "LOLLY"},
        {"BULLY", "LOLLY"},
        {"ROBIN", "ALERT"},
        {"ROBIN", "SONIC"},
        {"ROBIN", "ROBIN"}
    };
    for (i = 0; i < 5; ++i) {
        answer = pairs[i][0];
        guess  = pairs[i][1];
        for (j = 0; j < 5; ++j) res[j] = 0;
        wordle(answer, guess, res);
        for (j = 0; j < 5; ++j) res2[j] = colors[res[j]];
        printf("%s v %s => { ", answer, guess);
        for (j = 0; j < 5; ++j) printf("%d ", res[j]);
        printf("} => { ");
        for (j = 0; j < 5; ++j) printf("%s ", res2[j]);
        printf("}\n");
    }
    return 0;
}
Task: Distance and Bearing

C: 
csv=externstr("curl 'https:



{
    for(i = 1 , #csv, tmp = Vecsmall(csv[i]);
        for(j = 1 , #tmp, if(tmp[j]==92, tmp[j]=78));
        csv[i] = strchr(tmp)
    );
};
 
{  
convert(csv,mat)=
    write1(mat,"[");
    for(i=1, #csv-1,
        write1(mat,csv[i]); write1(mat,";")
    );
    write1(mat,csv[#csv]); write(mat,"]")
};
 
convert(csv,airports);
M = read(airports);

{
distance(lat1, lon1, lat2, lon2, unit = "mi") =
    my(dist = 0, rlat1, rlat2, rtheta);
    if(lat1!=lat2 || lon1!=lon2,
        rlat1 = lat1*Pi/180; rlat2 = lat2*Pi/180;
        rtheta = (lon1-lon2)*Pi/180;
        dist = sin(rlat1)*sin(rlat2) + cos(rlat1)*cos(rlat2)*cos(rtheta);
        dist = acos(min(dist,1))*180/Pi*60*1.1515576;
        if(unit=="Km", dist*= 1.609344, unit=="NM", dist*= 0.868976)
    );dist
};

{
bearing(lat1, lon1, lat2, lon2)=
    my(bear, rlat1, rlat2, rdlon, x, y);
    if (lat1!=lat2 || lon1!=lon2,
        rlat1 = lat1*Pi/180; rlat2 = lat2*Pi/180;
        rdlon = (lon2-lon1)*Pi/180;
        y = sin(rdlon)*cos(rlat2);
        x = cos(rlat1)*sin(rlat2) - sin(rlat1)*cos(rlat2)*cos(rdlon);
        
        if( x>0, bear=atan(y/x), x<0 && y>0, bear=atan(y/x)+Pi,
            x<0 && y==0, bear=Pi, x<0 && y<0, bear=atan(y/x)-Pi,
            x==0 && y>0, bear=Pi/2, x==0 && y<0, bear=-Pi/2);
        bear = (bear*180/Pi+360)%360;
    );bear
};

{
request(lat, lon, r = 20 , unit = "NM")=
    my(D = vector(#M[,1]), R = matrix(r+1, 5));
    R[1,1] = "NAME"; R[1,2] = "COUNTRY"; R[1,3] = "ICAO"; R[1,4] = "DISTANCE"; R[1,5] = "BEARING";
    printf("%-38s\t%-16s\t%-4s\t%s\t%s\n", R[1,1], R[1,2], R[1,3], R[1,4], R[1,5]);  
    for(i = 1, #M[,1],
        D[i] = [distance(lat, lon, M[i,7], M[i,8], unit) , i];
    );
    D=vecsort(D);
    for(i = 1, r,
        R[i+1,1] = M[D[i][2],2]; R[i+1,2] = M[D[i][2],4]; R[i+1,3] = M[D[i][2],6];
        R[i+1,4] = D[i][1]; R[i+1,5] = bearing(lat, lon, M[D[i][2],7], M[D[i][2],8]);
        printf("%-38s\t%-16s\t%-4s\t%8.1f\t%7.0f\n", R[i+1,1], R[i+1,2], R[i+1,3], R[i+1,4], R[i+1,5]);    
    );
} 

request(51.514669, 2.198581)