Problem 742

Minimum Area of a Convex Grid Polygon. Pure Flow port of the native C solver.

Answer18397727
Output18397727
StatusPASS
Native helperno
Runtime70 ms
Peak memory1424 KB
Time complexityO(n^2) (estimated)
Space complexityO(1) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n log n)
Space complexityO(1)O(n)
ApproachFlow solutionSearch with pruning or sieve
VerdictSuboptimal

Flow source

# Project Euler 742
# Minimum Area of a Convex Grid Polygon.
# Pure Flow port of the native C solver.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function malloc(n: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
}

let mut g_pa: ptr<i32> = null
let mut g_pb: ptr<i32> = null
let mut g_npairs: i32 = 0
let mut g_pair_cap: i32 = 0

function gcd(a0: i32, b0: i32) -> i32 {
    let mut a: i32 = a0
    let mut b: i32 = b0
    while b != 0 {
        let t: i32 = a % b
        a = b
        b = t
    }
    return a
}

function primitive_pairs(limit: i32) -> void {
    if g_pair_cap < limit * limit {
        free(g_pa as ptr<void>)
        free(g_pb as ptr<void>)
        g_pair_cap = limit * limit
        g_pa = malloc((g_pair_cap as i64) * 4) as ptr<i32>
        g_pb = malloc((g_pair_cap as i64) * 4) as ptr<i32>
    }
    g_npairs = 0
    let mut a: i32 = 1
    while a <= limit {
        let mut b: i32 = 1
        while b <= limit {
            if gcd(a, b) == 1 {
                g_pa[g_npairs] = a
                g_pb[g_npairs] = b
                g_npairs = g_npairs + 1
            }
            b = b + 1
        }
        a = a + 1
    }
}

# Max-heap comparison: true if (w,tie1,a,b) > (w2,t2,a2,b2)
function heap_gt(w: f64, tie1: i32, a: i32, b: i32, w2: f64, t2: i32, a2: i32, b2: i32) -> bool {
    if w > w2 { return true }
    if w < w2 { return false }
    if tie1 > t2 { return true }
    if tie1 < t2 { return false }
    if a > a2 { return true }
    if a < a2 { return false }
    if b > b2 { return true }
    return false
}

# Select k pairs minimizing a^2 + t*b^2 with tie-break on a+b then a then b.
# Uses a max-heap of size k. Writes results to out_a, out_b.
function n_smallest(out_a: ptr<i32>, out_b: ptr<i32>, k: i32, t: f64) -> void {
    let hw: ptr<f64> = malloc((k as i64) * 8) as ptr<f64>
    let htie1: ptr<i32> = malloc((k as i64) * 4) as ptr<i32>
    let ha: ptr<i32> = malloc((k as i64) * 4) as ptr<i32>
    let hb: ptr<i32> = malloc((k as i64) * 4) as ptr<i32>
    let mut hs: i32 = 0

    let mut idx: i32 = 0
    while idx < g_npairs {
        let a: i32 = g_pa[idx]
        let b: i32 = g_pb[idx]
        let w: f64 = (a as f64) * (a as f64) + t * (b as f64) * (b as f64)
        let tie1: i32 = a + b

        if hs < k {
            let mut i: i32 = hs
            hs = hs + 1
            hw[i] = w
            htie1[i] = tie1
            ha[i] = a
            hb[i] = b
            while i > 0 {
                let p: i32 = (i - 1) / 2
                if heap_gt(hw[i], htie1[i], ha[i], hb[i], hw[p], htie1[p], ha[p], hb[p]) {
                    let tmp_w: f64 = hw[p]
                    hw[p] = hw[i]
                    hw[i] = tmp_w
                    let tmp_t: i32 = htie1[p]
                    htie1[p] = htie1[i]
                    htie1[i] = tmp_t
                    let tmp_a: i32 = ha[p]
                    ha[p] = ha[i]
                    ha[i] = tmp_a
                    let tmp_b: i32 = hb[p]
                    hb[p] = hb[i]
                    hb[i] = tmp_b
                    i = p
                } else {
                    break
                }
            }
        } else {
            let better: bool = heap_gt(hw[0], htie1[0], ha[0], hb[0], w, tie1, a, b)
            if better {
                hw[0] = w
                htie1[0] = tie1
                ha[0] = a
                hb[0] = b
                let mut i: i32 = 0
                while true {
                    let l: i32 = 2 * i + 1
                    let r: i32 = 2 * i + 2
                    let mut largest: i32 = i
                    if l < hs {
                        if heap_gt(hw[l], htie1[l], ha[l], hb[l], hw[largest], htie1[largest], ha[largest], hb[largest]) {
                            largest = l
                        }
                    }
                    if r < hs {
                        if heap_gt(hw[r], htie1[r], ha[r], hb[r], hw[largest], htie1[largest], ha[largest], hb[largest]) {
                            largest = r
                        }
                    }
                    if largest != i {
                        let tmp_w: f64 = hw[i]
                        hw[i] = hw[largest]
                        hw[largest] = tmp_w
                        let tmp_t: i32 = htie1[i]
                        htie1[i] = htie1[largest]
                        htie1[largest] = tmp_t
                        let tmp_a: i32 = ha[i]
                        ha[i] = ha[largest]
                        ha[largest] = tmp_a
                        let tmp_b: i32 = hb[i]
                        hb[i] = hb[largest]
                        hb[largest] = tmp_b
                        i = largest
                    } else {
                        break
                    }
                }
            }
        }
        idx = idx + 1
    }

    let mut i: i32 = 0
    while i < k {
        out_a[i] = ha[i]
        out_b[i] = hb[i]
        i = i + 1
    }
    free(hw as ptr<void>)
    free(htie1 as ptr<void>)
    free(ha as ptr<void>)
    free(hb as ptr<void>)
}

# Insertion sort by slope b/a ascending, then a, then b.
function sort_by_slope(ia: ptr<i32>, ib: ptr<i32>, k: i32) -> void {
    let mut i: i32 = 1
    while i < k {
        let mut j: i32 = i
        while j > 0 {
            let sa: f64 = (ib[j - 1] as f64) / (ia[j - 1] as f64)
            let sb: f64 = (ib[j] as f64) / (ia[j] as f64)
            let swap: bool = false
            if sa > sb {
                swap = true
            } else {
                if sa == sb {
                    if ia[j - 1] > ia[j] {
                        swap = true
                    } else {
                        if ia[j - 1] == ia[j] {
                            if ib[j - 1] > ib[j] {
                                swap = true
                            }
                        }
                    }
                }
            }
            if swap {
                let ta: i32 = ia[j - 1]
                ia[j - 1] = ia[j]
                ia[j] = ta
                let tb: i32 = ib[j - 1]
                ib[j - 1] = ib[j]
                ib[j] = tb
            } else {
                break
            }
            j = j - 1
        }
        i = i + 1
    }
}

function area_from_half_edges(ha: ptr<i32>, hb: ptr<i32>, m: i32) -> i64 {
    let mut px: i64 = 0
    let mut py: i64 = 0
    let mut area: i64 = 0
    let mut i: i32 = 0
    while i < m {
        area = area + px * (hb[i] as i64) - py * (ha[i] as i64)
        px = px + (ha[i] as i64)
        py = py + (hb[i] as i64)
        i = i + 1
    }
    return area
}

function polygon_area_from_interior(ia: ptr<i32>, ib: ptr<i32>, k: i32) -> i64 {
    sort_by_slope(ia, ib, k)
    let m: i32 = 1 + k + 1 + k
    let ha: ptr<i32> = malloc((m as i64) * 4) as ptr<i32>
    let hb: ptr<i32> = malloc((m as i64) * 4) as ptr<i32>
    let mut idx: i32 = 0
    ha[idx] = 1
    hb[idx] = 0
    idx = idx + 1
    let mut i: i32 = 0
    while i < k {
        ha[idx] = ia[i]
        hb[idx] = ib[i]
        idx = idx + 1
        i = i + 1
    }
    ha[idx] = 0
    hb[idx] = 1
    idx = idx + 1
    let mut j: i32 = k - 1
    while j >= 0 {
        ha[idx] = -ia[j]
        hb[idx] = ib[j]
        idx = idx + 1
        j = j - 1
    }
    let area: i64 = area_from_half_edges(ha, hb, m)
    free(ha as ptr<void>)
    free(hb as ptr<void>)
    return area
}

function compute_A(N: i32) -> i64 {
    if N < 4 || N % 4 != 0 { return 0 }
    let k: i32 = (N - 4) / 4
    if k == 0 { return 1 }

    let mut limit: i32 = 40
    primitive_pairs(limit)

    let mut best_area: i64 = -1
    let ca: ptr<i32> = malloc((k as i64) * 4) as ptr<i32>
    let cb: ptr<i32> = malloc((k as i64) * 4) as ptr<i32>

    let mut tn: i32 = 1
    while tn <= 1000 {
        let t: f64 = (tn as f64) / 1000.0

        while true {
            n_smallest(ca, cb, k, t)
            let mut max_a: i32 = 0
            let mut max_b: i32 = 0
            let mut i: i32 = 0
            while i < k {
                if ca[i] > max_a { max_a = ca[i] }
                if cb[i] > max_b { max_b = cb[i] }
                i = i + 1
            }
            if max_a < limit && max_b < limit { break }
            limit = limit * 2
            primitive_pairs(limit)
        }

        let area: i64 = polygon_area_from_interior(ca, cb, k)
        if best_area == -1 || area < best_area { best_area = area }
        tn = tn + 1
    }

    free(ca as ptr<void>)
    free(cb as ptr<void>)
    return best_area
}

function main() -> i32 {
    printf("%lld\n", compute_A(1000))
    return 0
}

Generated C

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Flow runtime helpers */
typedef struct flow_temp_node { struct flow_temp_node* next; } flow_temp_node;
static flow_temp_node* flow_temp_head = NULL;
static int flow_temp_atexit_set = 0;
__attribute__((unused)) static void flow_temp_free_all(void) {
    while (flow_temp_head) {
        flow_temp_node* n = flow_temp_head;
        flow_temp_head = n->next;
        free(n);
    }
}
__attribute__((unused)) static void* flow_temp_alloc(size_t nbytes) {
    flow_temp_node* node = (flow_temp_node*)malloc(sizeof(flow_temp_node) + nbytes);
    if (!node) return NULL;
    node->next = flow_temp_head;
    flow_temp_head = node;
    if (!flow_temp_atexit_set) {
        flow_temp_atexit_set = 1;
        atexit(flow_temp_free_all);
    }
    return (void*)(node + 1);
}
#ifndef FLOW_DIAG
#define FLOW_DIAG(msg) fprintf(stderr, "%s", (msg))
#endif
#ifndef FLOW_LOG
#define FLOW_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
#ifndef FLOW_LOG_EMPTY
#define FLOW_LOG_EMPTY(fmt) printf(fmt)
#endif
static char* flow_strcat(const char* a, const char* b) {
    size_t la = strlen(a ? a : ""), lb = strlen(b ? b : "");
    char* r = (char*)flow_temp_alloc(la + lb + 1);
    if (!r) return NULL;
    if (la) memcpy(r, a, la);
    if (lb) memcpy(r + la, b, lb);
    r[la + lb] = '\0';
    return r;
}

#define __flow_in_arr(arr, val) __extension__ ({ \
    int _found = 0; \
    size_t _n = sizeof(arr)/sizeof((arr)[0]); \
    for (size_t _i = 0; _i < _n; _i++) { \
        if ((arr)[_i] == (val)) { _found = 1; break; } \
    } _found; })

/* Unified fault handler (MISRA #279) — override with -DFLOW_FAULT_HANDLER=fn */
#ifndef FLOW_FAULT_HANDLER
__attribute__((unused)) static inline void flow_fault_handler(const char* msg) {
    fprintf(stderr, "flow: %s\n", msg ? msg : "fault");
    abort();
#if defined(__GNUC__) || defined(__clang__)
    __builtin_unreachable();
#endif
}
#else
#define flow_fault_handler FLOW_FAULT_HANDLER
#endif
#define flow_div_by_zero_handler() flow_fault_handler("division by zero")
#define flow_shift_ub_handler() flow_fault_handler("invalid shift (amount out of range or left-shift of negative)")

#ifndef FLOW_CHECKED_DIV
#define FLOW_CHECKED_DIV(L, R) (((R) != 0) ? ((L) / (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_MOD
#define FLOW_CHECKED_MOD(L, R) (((R) != 0) ? ((L) % (R)) : (flow_div_by_zero_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHL
#define FLOW_CHECKED_SHL(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull)) && ((L) >= 0)) ? ((L) << (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif
#ifndef FLOW_CHECKED_SHR
#define FLOW_CHECKED_SHR(L, R) ((((R) >= 0) && ((unsigned long long)(R) < (sizeof(L) * 8ull))) ? ((L) >> (R)) : (flow_shift_ub_handler(), (L) * 0))
#endif

#include <math.h>

void* _ui_state = NULL;

static inline float i32_to_f32(int32_t v) { return (float)v; }

/* Host stub for @gpu kernels (device codegen replaces this). */
static inline int32_t gpu_thread_id(void) { return 0; }

int32_t gcd_i32_i32(int32_t a0, int32_t b0);
void primitive_pairs_i32(int32_t limit);
bool heap_gt_f64_i32_i32_i32_f64_i32_i32_i32(double w, int32_t tie1, int32_t a, int32_t b, double w2, int32_t t2, int32_t a2, int32_t b2);
void n_smallest_ptr_i32_ptr_i32_i32_f64(int32_t* out_a, int32_t* out_b, int32_t k, double t);
void sort_by_slope_ptr_i32_ptr_i32_i32(int32_t* ia, int32_t* ib, int32_t k);
int64_t area_from_half_edges_ptr_i32_ptr_i32_i32(int32_t* ha, int32_t* hb, int32_t m);
int64_t polygon_area_from_interior_ptr_i32_ptr_i32_i32(int32_t* ia, int32_t* ib, int32_t k);
int64_t compute_A_i32(int32_t N);
int32_t main(void);

/* Module statics */
static int32_t* g_pa = NULL;
static int32_t* g_pb = NULL;
static int32_t g_npairs = 0;
static int32_t g_pair_cap = 0;




int32_t gcd_i32_i32(int32_t a0, int32_t b0) {
    int32_t a = a0;
    int32_t b = b0;
    while (b != 0) {
        int32_t t = FLOW_CHECKED_MOD((a), (b));
        a = b;
        b = t;
    }
    return a;
}

void primitive_pairs_i32(int32_t limit) {
    if (g_pair_cap < (limit * limit)) {
        free(((void*)(g_pa)));
        free(((void*)(g_pb)));
        g_pair_cap = (limit * limit);
        g_pa = ((int32_t*)(malloc((((int64_t)(g_pair_cap)) * 4))));
        g_pb = ((int32_t*)(malloc((((int64_t)(g_pair_cap)) * 4))));
    }
    g_npairs = 0;
    int32_t a = 1;
    while (a <= limit) {
        int32_t b = 1;
        while (b <= limit) {
            if (gcd_i32_i32(a, b) == 1) {
                g_pa[g_npairs] = a;
                g_pb[g_npairs] = b;
                g_npairs = (g_npairs + 1);
            }
            b = (b + 1);
        }
        a = (a + 1);
    }
}

bool heap_gt_f64_i32_i32_i32_f64_i32_i32_i32(double w, int32_t tie1, int32_t a, int32_t b, double w2, int32_t t2, int32_t a2, int32_t b2) {
    if (w > w2) {
        return 1;
    }
    if (w < w2) {
        return 0;
    }
    if (tie1 > t2) {
        return 1;
    }
    if (tie1 < t2) {
        return 0;
    }
    if (a > a2) {
        return 1;
    }
    if (a < a2) {
        return 0;
    }
    if (b > b2) {
        return 1;
    }
    return 0;
}

void n_smallest_ptr_i32_ptr_i32_i32_f64(int32_t* out_a, int32_t* out_b, int32_t k, double t) {
    double* hw = (double*)(((double*)(malloc((((int64_t)(k)) * 8)))));
    int32_t* htie1 = (int32_t*)(((int32_t*)(malloc((((int64_t)(k)) * 4)))));
    int32_t* ha = (int32_t*)(((int32_t*)(malloc((((int64_t)(k)) * 4)))));
    int32_t* hb = (int32_t*)(((int32_t*)(malloc((((int64_t)(k)) * 4)))));
    int32_t hs = 0;
    int32_t idx = 0;
    while (idx < g_npairs) {
        int32_t a = g_pa[idx];
        int32_t b = g_pb[idx];
        double w = ((((double)(a)) * ((double)(a))) + ((t * ((double)(b))) * ((double)(b))));
        int32_t tie1 = (a + b);
        if (hs < k) {
            int32_t i = hs;
            hs = (hs + 1);
            hw[i] = w;
            htie1[i] = tie1;
            ha[i] = a;
            hb[i] = b;
            while (i > 0) {
                int32_t p = FLOW_CHECKED_DIV(((i - 1)), (2));
                if (heap_gt_f64_i32_i32_i32_f64_i32_i32_i32(hw[i], htie1[i], ha[i], hb[i], hw[p], htie1[p], ha[p], hb[p])) {
                    double tmp_w = hw[p];
                    hw[p] = hw[i];
                    hw[i] = tmp_w;
                    int32_t tmp_t = htie1[p];
                    htie1[p] = htie1[i];
                    htie1[i] = tmp_t;
                    int32_t tmp_a = ha[p];
                    ha[p] = ha[i];
                    ha[i] = tmp_a;
                    int32_t tmp_b = hb[p];
                    hb[p] = hb[i];
                    hb[i] = tmp_b;
                    i = p;
                } else {
                    break;
                }
            }
        } else {
            bool better = heap_gt_f64_i32_i32_i32_f64_i32_i32_i32(hw[0], htie1[0], ha[0], hb[0], w, tie1, a, b);
            if (better) {
                hw[0] = w;
                htie1[0] = tie1;
                ha[0] = a;
                hb[0] = b;
                int32_t i = 0;
                while (1) {
                    int32_t l = ((2 * i) + 1);
                    int32_t r = ((2 * i) + 2);
                    int32_t largest = i;
                    if (l < hs) {
                        if (heap_gt_f64_i32_i32_i32_f64_i32_i32_i32(hw[l], htie1[l], ha[l], hb[l], hw[largest], htie1[largest], ha[largest], hb[largest])) {
                            largest = l;
                        }
                    }
                    if (r < hs) {
                        if (heap_gt_f64_i32_i32_i32_f64_i32_i32_i32(hw[r], htie1[r], ha[r], hb[r], hw[largest], htie1[largest], ha[largest], hb[largest])) {
                            largest = r;
                        }
                    }
                    if (largest != i) {
                        double tmp_w = hw[i];
                        hw[i] = hw[largest];
                        hw[largest] = tmp_w;
                        int32_t tmp_t = htie1[i];
                        htie1[i] = htie1[largest];
                        htie1[largest] = tmp_t;
                        int32_t tmp_a = ha[i];
                        ha[i] = ha[largest];
                        ha[largest] = tmp_a;
                        int32_t tmp_b = hb[i];
                        hb[i] = hb[largest];
                        hb[largest] = tmp_b;
                        i = largest;
                    } else {
                        break;
                    }
                }
            }
        }
        idx = (idx + 1);
    }
    int32_t i = 0;
    while (i < k) {
        out_a[i] = ha[i];
        out_b[i] = hb[i];
        i = (i + 1);
    }
    free(((void*)(hw)));
    free(((void*)(htie1)));
    free(((void*)(ha)));
    free(((void*)(hb)));
}

void sort_by_slope_ptr_i32_ptr_i32_i32(int32_t* ia, int32_t* ib, int32_t k) {
    int32_t i = 1;
    while (i < k) {
        int32_t j = i;
        while (j > 0) {
            double sa = (((double)(ib[(j - 1)])) / ((double)(ia[(j - 1)])));
            double sb = (((double)(ib[j])) / ((double)(ia[j])));
            bool swap = 0;
            if (sa > sb) {
                swap = 1;
            } else {
                if (sa == sb) {
                    if (ia[(j - 1)] > ia[j]) {
                        swap = 1;
                    } else {
                        if (ia[(j - 1)] == ia[j]) {
                            if (ib[(j - 1)] > ib[j]) {
                                swap = 1;
                            }
                        }
                    }
                }
            }
            if (swap) {
                int32_t ta = ia[(j - 1)];
                ia[(j - 1)] = ia[j];
                ia[j] = ta;
                int32_t tb = ib[(j - 1)];
                ib[(j - 1)] = ib[j];
                ib[j] = tb;
            } else {
                break;
            }
            j = (j - 1);
        }
        i = (i + 1);
    }
}

int64_t area_from_half_edges_ptr_i32_ptr_i32_i32(int32_t* ha, int32_t* hb, int32_t m) {
    int64_t px = 0;
    int64_t py = 0;
    int64_t area = 0;
    int32_t i = 0;
    while (i < m) {
        area = ((area + (px * ((int64_t)(hb[i])))) - (py * ((int64_t)(ha[i]))));
        px = (px + ((int64_t)(ha[i])));
        py = (py + ((int64_t)(hb[i])));
        i = (i + 1);
    }
    return area;
}

int64_t polygon_area_from_interior_ptr_i32_ptr_i32_i32(int32_t* ia, int32_t* ib, int32_t k) {
    sort_by_slope_ptr_i32_ptr_i32_i32(ia, ib, k);
    int32_t m = (((1 + k) + 1) + k);
    int32_t* ha = (int32_t*)(((int32_t*)(malloc((((int64_t)(m)) * 4)))));
    int32_t* hb = (int32_t*)(((int32_t*)(malloc((((int64_t)(m)) * 4)))));
    int32_t idx = 0;
    ha[idx] = 1;
    hb[idx] = 0;
    idx = (idx + 1);
    int32_t i = 0;
    while (i < k) {
        ha[idx] = ia[i];
        hb[idx] = ib[i];
        idx = (idx + 1);
        i = (i + 1);
    }
    ha[idx] = 0;
    hb[idx] = 1;
    idx = (idx + 1);
    int32_t j = (k - 1);
    while (j >= 0) {
        ha[idx] = (-ia[j]);
        hb[idx] = ib[j];
        idx = (idx + 1);
        j = (j - 1);
    }
    int64_t area = area_from_half_edges_ptr_i32_ptr_i32_i32(ha, hb, m);
    free(((void*)(ha)));
    free(((void*)(hb)));
    return area;
}

int64_t compute_A_i32(int32_t N) {
    if ((N < 4 || FLOW_CHECKED_MOD((N), (4)) != 0)) {
        return 0;
    }
    int32_t k = FLOW_CHECKED_DIV(((N - 4)), (4));
    if (k == 0) {
        return 1;
    }
    int32_t limit = 40;
    primitive_pairs_i32(limit);
    int64_t best_area = (-1);
    int32_t* ca = (int32_t*)(((int32_t*)(malloc((((int64_t)(k)) * 4)))));
    int32_t* cb = (int32_t*)(((int32_t*)(malloc((((int64_t)(k)) * 4)))));
    int32_t tn = 1;
    while (tn <= 1000) {
        double t = (((double)(tn)) / 1000.0);
        while (1) {
            n_smallest_ptr_i32_ptr_i32_i32_f64(ca, cb, k, t);
            int32_t max_a = 0;
            int32_t max_b = 0;
            int32_t i = 0;
            while (i < k) {
                if (ca[i] > max_a) {
                    max_a = ca[i];
                }
                if (cb[i] > max_b) {
                    max_b = cb[i];
                }
                i = (i + 1);
            }
            if ((max_a < limit && max_b < limit)) {
                break;
            }
            limit = (limit * 2);
            primitive_pairs_i32(limit);
        }
        int64_t area = polygon_area_from_interior_ptr_i32_ptr_i32_i32(ca, cb, k);
        if ((best_area == (-1) || area < best_area)) {
            best_area = area;
        }
        tn = (tn + 1);
    }
    free(((void*)(ca)));
    free(((void*)(cb)));
    return best_area;
}

int32_t main(void) {
    printf("%lld\n", compute_A_i32(1000));
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @malloc(i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()
  // Module static: g_pa
  llvm.mlir.global internal @g_pa() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: g_pb
  llvm.mlir.global internal @g_pb() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: g_npairs
  llvm.mlir.global internal @g_npairs(0 : i32) : i32
  // Module static: g_pair_cap
  llvm.mlir.global internal @g_pair_cap(0 : i32) : i32
  func.func @gcd(%arg0: i32, %arg1: i32) -> i32 {
    %2 = llvm.mlir.constant(1 : i64) : i64
    %3 = llvm.alloca %2 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg0, %3 : i32, !llvm.ptr
    %4 = llvm.mlir.constant(1 : i64) : i64
    %5 = llvm.alloca %4 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg1, %5 : i32, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %6 = llvm.load %5 : !llvm.ptr -> i32
    %7 = arith.constant 0 : i32
    %8 = arith.cmpi ne, %6, %7 : i32
    cf.cond_br %8, ^bb1, ^bb2
    ^bb1:
      %9 = llvm.load %3 : !llvm.ptr -> i32
      %10 = llvm.load %5 : !llvm.ptr -> i32
      %11 = arith.remsi %9, %10 : i32
      %12 = llvm.load %5 : !llvm.ptr -> i32
      llvm.store %12, %3 : i32, !llvm.ptr
      llvm.store %11, %5 : i32, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %13 = llvm.load %3 : !llvm.ptr -> i32
    func.return %13 : i32
  }
  func.func @primitive_pairs(%arg0: i32) -> () {
    %14 = llvm.mlir.addressof @g_pair_cap : !llvm.ptr
    %15 = llvm.load %14 : !llvm.ptr -> i32
    %16 = arith.muli %arg0, %arg0 : i32
    %17 = arith.cmpi slt, %15, %16 : i32
    cf.cond_br %17, ^bb3, ^bb4
    ^bb3:
      %19 = llvm.mlir.addressof @g_pa : !llvm.ptr
      %20 = llvm.load %19 : !llvm.ptr -> !llvm.ptr
      func.call @free(%20) : (!llvm.ptr) -> ()
      %22 = llvm.mlir.addressof @g_pb : !llvm.ptr
      %23 = llvm.load %22 : !llvm.ptr -> !llvm.ptr
      func.call @free(%23) : (!llvm.ptr) -> ()
      %24 = arith.muli %arg0, %arg0 : i32
      %25 = llvm.mlir.addressof @g_pair_cap : !llvm.ptr
      llvm.store %24, %25 : i32, !llvm.ptr
      %27 = llvm.mlir.addressof @g_pair_cap : !llvm.ptr
      %28 = llvm.load %27 : !llvm.ptr -> i32
      %29 = arith.extsi %28 : i32 to i64
      %30 = arith.constant 4 : i32
      %32 = arith.extsi %30 : i32 to i64
      %31 = arith.muli %29, %32 : i64
      %26 = func.call @malloc(%31) : (i64) -> !llvm.ptr
      %33 = llvm.mlir.addressof @g_pa : !llvm.ptr
      llvm.store %26, %33 : !llvm.ptr, !llvm.ptr
      %35 = llvm.mlir.addressof @g_pair_cap : !llvm.ptr
      %36 = llvm.load %35 : !llvm.ptr -> i32
      %37 = arith.extsi %36 : i32 to i64
      %38 = arith.constant 4 : i32
      %40 = arith.extsi %38 : i32 to i64
      %39 = arith.muli %37, %40 : i64
      %34 = func.call @malloc(%39) : (i64) -> !llvm.ptr
      %41 = llvm.mlir.addressof @g_pb : !llvm.ptr
      llvm.store %34, %41 : !llvm.ptr, !llvm.ptr
      cf.br ^bb5
    ^bb4:
      cf.br ^bb5
    ^bb5:
    %42 = arith.constant 0 : i32
    %43 = llvm.mlir.addressof @g_npairs : !llvm.ptr
    llvm.store %42, %43 : i32, !llvm.ptr
    %44 = arith.constant 1 : i32
    %45 = llvm.mlir.constant(1 : i64) : i64
    %46 = llvm.alloca %45 x i32 : (i64) -> !llvm.ptr
    llvm.store %44, %46 : i32, !llvm.ptr
    cf.br ^bb6
    ^bb6:
    %47 = llvm.load %46 : !llvm.ptr -> i32
    %48 = arith.cmpi sle, %47, %arg0 : i32
    cf.cond_br %48, ^bb7, ^bb8
    ^bb7:
      %49 = arith.constant 1 : i32
      %50 = llvm.mlir.constant(1 : i64) : i64
      %51 = llvm.alloca %50 x i32 : (i64) -> !llvm.ptr
      llvm.store %49, %51 : i32, !llvm.ptr
      cf.br ^bb9
      ^bb9:
      %52 = llvm.load %51 : !llvm.ptr -> i32
      %53 = arith.cmpi sle, %52, %arg0 : i32
      cf.cond_br %53, ^bb10, ^bb11
      ^bb10:
        %55 = llvm.load %46 : !llvm.ptr -> i32
        %56 = llvm.load %51 : !llvm.ptr -> i32
        %54 = func.call @gcd(%55, %56) : (i32, i32) -> i32
        %57 = arith.constant 1 : i32
        %58 = arith.cmpi eq, %54, %57 : i32
        cf.cond_br %58, ^bb12, ^bb13
        ^bb12:
          %59 = llvm.load %46 : !llvm.ptr -> i32
          %60 = llvm.mlir.addressof @g_pa : !llvm.ptr
          %61 = llvm.load %60 : !llvm.ptr -> !llvm.ptr
          %62 = llvm.mlir.addressof @g_npairs : !llvm.ptr
          %63 = llvm.load %62 : !llvm.ptr -> i32
          %64 = arith.extsi %63 : i32 to i64
          %65 = llvm.getelementptr %61[%64] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %59, %65 : i32, !llvm.ptr
          %66 = llvm.load %51 : !llvm.ptr -> i32
          %67 = llvm.mlir.addressof @g_pb : !llvm.ptr
          %68 = llvm.load %67 : !llvm.ptr -> !llvm.ptr
          %69 = llvm.mlir.addressof @g_npairs : !llvm.ptr
          %70 = llvm.load %69 : !llvm.ptr -> i32
          %71 = arith.extsi %70 : i32 to i64
          %72 = llvm.getelementptr %68[%71] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %66, %72 : i32, !llvm.ptr
          %73 = llvm.mlir.addressof @g_npairs : !llvm.ptr
          %74 = llvm.load %73 : !llvm.ptr -> i32
          %75 = arith.constant 1 : i32
          %76 = arith.addi %74, %75 : i32
          %77 = llvm.mlir.addressof @g_npairs : !llvm.ptr
          llvm.store %76, %77 : i32, !llvm.ptr
          cf.br ^bb14
        ^bb13:
          cf.br ^bb14
        ^bb14:
        %78 = llvm.load %51 : !llvm.ptr -> i32
        %79 = arith.constant 1 : i32
        %80 = arith.addi %78, %79 : i32
        llvm.store %80, %51 : i32, !llvm.ptr
        cf.br ^bb9
      ^bb11:
      %81 = llvm.load %46 : !llvm.ptr -> i32
      %82 = arith.constant 1 : i32
      %83 = arith.addi %81, %82 : i32
      llvm.store %83, %46 : i32, !llvm.ptr
      cf.br ^bb6
    ^bb8:
    func.return
  }
  func.func @heap_gt(%arg0: f64, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: f64, %arg5: i32, %arg6: i32, %arg7: i32) -> i1 {
    %84 = arith.cmpf ogt, %arg0, %arg4 : f64
    cf.cond_br %84, ^bb15, ^bb16
    ^bb15:
      %85 = arith.constant 1 : i1
      func.return %85 : i1
    ^bb16:
      cf.br ^bb17
    ^bb17:
    %86 = arith.cmpf olt, %arg0, %arg4 : f64
    cf.cond_br %86, ^bb18, ^bb19
    ^bb18:
      %87 = arith.constant 0 : i1
      func.return %87 : i1
    ^bb19:
      cf.br ^bb20
    ^bb20:
    %88 = arith.cmpi sgt, %arg1, %arg5 : i32
    cf.cond_br %88, ^bb21, ^bb22
    ^bb21:
      %89 = arith.constant 1 : i1
      func.return %89 : i1
    ^bb22:
      cf.br ^bb23
    ^bb23:
    %90 = arith.cmpi slt, %arg1, %arg5 : i32
    cf.cond_br %90, ^bb24, ^bb25
    ^bb24:
      %91 = arith.constant 0 : i1
      func.return %91 : i1
    ^bb25:
      cf.br ^bb26
    ^bb26:
    %92 = arith.cmpi sgt, %arg2, %arg6 : i32
    cf.cond_br %92, ^bb27, ^bb28
    ^bb27:
      %93 = arith.constant 1 : i1
      func.return %93 : i1
    ^bb28:
      cf.br ^bb29
    ^bb29:
    %94 = arith.cmpi slt, %arg2, %arg6 : i32
    cf.cond_br %94, ^bb30, ^bb31
    ^bb30:
      %95 = arith.constant 0 : i1
      func.return %95 : i1
    ^bb31:
      cf.br ^bb32
    ^bb32:
    %96 = arith.cmpi sgt, %arg3, %arg7 : i32
    cf.cond_br %96, ^bb33, ^bb34
    ^bb33:
      %97 = arith.constant 1 : i1
      func.return %97 : i1
    ^bb34:
      cf.br ^bb35
    ^bb35:
    %98 = arith.constant 0 : i1
    func.return %98 : i1
  }
  func.func @n_smallest(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32, %arg3: f64) -> () {
    %100 = arith.extsi %arg2 : i32 to i64
    %101 = arith.constant 8 : i32
    %103 = arith.extsi %101 : i32 to i64
    %102 = arith.muli %100, %103 : i64
    %99 = func.call @malloc(%102) : (i64) -> !llvm.ptr
    %105 = arith.extsi %arg2 : i32 to i64
    %106 = arith.constant 4 : i32
    %108 = arith.extsi %106 : i32 to i64
    %107 = arith.muli %105, %108 : i64
    %104 = func.call @malloc(%107) : (i64) -> !llvm.ptr
    %110 = arith.extsi %arg2 : i32 to i64
    %111 = arith.constant 4 : i32
    %113 = arith.extsi %111 : i32 to i64
    %112 = arith.muli %110, %113 : i64
    %109 = func.call @malloc(%112) : (i64) -> !llvm.ptr
    %115 = arith.extsi %arg2 : i32 to i64
    %116 = arith.constant 4 : i32
    %118 = arith.extsi %116 : i32 to i64
    %117 = arith.muli %115, %118 : i64
    %114 = func.call @malloc(%117) : (i64) -> !llvm.ptr
    %119 = arith.constant 0 : i32
    %120 = llvm.mlir.constant(1 : i64) : i64
    %121 = llvm.alloca %120 x i32 : (i64) -> !llvm.ptr
    llvm.store %119, %121 : i32, !llvm.ptr
    %122 = arith.constant 0 : i32
    %123 = llvm.mlir.constant(1 : i64) : i64
    %124 = llvm.alloca %123 x i32 : (i64) -> !llvm.ptr
    llvm.store %122, %124 : i32, !llvm.ptr
    cf.br ^bb36
    ^bb36:
    %125 = llvm.load %124 : !llvm.ptr -> i32
    %126 = llvm.mlir.addressof @g_npairs : !llvm.ptr
    %127 = llvm.load %126 : !llvm.ptr -> i32
    %128 = arith.cmpi slt, %125, %127 : i32
    cf.cond_br %128, ^bb37, ^bb38
    ^bb37:
      %130 = llvm.mlir.addressof @g_pa : !llvm.ptr
      %131 = llvm.load %130 : !llvm.ptr -> !llvm.ptr
      %132 = llvm.load %124 : !llvm.ptr -> i32
      %133 = arith.extsi %132 : i32 to i64
      %134 = llvm.getelementptr %131[%133] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %129 = llvm.load %134 : !llvm.ptr -> i32
      %136 = llvm.mlir.addressof @g_pb : !llvm.ptr
      %137 = llvm.load %136 : !llvm.ptr -> !llvm.ptr
      %138 = llvm.load %124 : !llvm.ptr -> i32
      %139 = arith.extsi %138 : i32 to i64
      %140 = llvm.getelementptr %137[%139] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %135 = llvm.load %140 : !llvm.ptr -> i32
      %141 = arith.sitofp %129 : i32 to f64
      %142 = arith.sitofp %129 : i32 to f64
      %143 = arith.mulf %141, %142 : f64
      %144 = arith.sitofp %135 : i32 to f64
      %145 = arith.mulf %arg3, %144 : f64
      %146 = arith.sitofp %135 : i32 to f64
      %147 = arith.mulf %145, %146 : f64
      %148 = arith.addf %143, %147 : f64
      %149 = arith.addi %129, %135 : i32
      %150 = llvm.load %121 : !llvm.ptr -> i32
      %151 = arith.cmpi slt, %150, %arg2 : i32
      cf.cond_br %151, ^bb39, ^bb40
      ^bb39:
        %152 = llvm.load %121 : !llvm.ptr -> i32
        %153 = llvm.mlir.constant(1 : i64) : i64
        %154 = llvm.alloca %153 x i32 : (i64) -> !llvm.ptr
        llvm.store %152, %154 : i32, !llvm.ptr
        %155 = llvm.load %121 : !llvm.ptr -> i32
        %156 = arith.constant 1 : i32
        %157 = arith.addi %155, %156 : i32
        llvm.store %157, %121 : i32, !llvm.ptr
        %158 = llvm.load %154 : !llvm.ptr -> i32
        %159 = arith.extsi %158 : i32 to i64
        %160 = llvm.getelementptr %99[%159] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        llvm.store %148, %160 : f64, !llvm.ptr
        %161 = llvm.load %154 : !llvm.ptr -> i32
        %162 = arith.extsi %161 : i32 to i64
        %163 = llvm.getelementptr %104[%162] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %149, %163 : i32, !llvm.ptr
        %164 = llvm.load %154 : !llvm.ptr -> i32
        %165 = arith.extsi %164 : i32 to i64
        %166 = llvm.getelementptr %109[%165] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %129, %166 : i32, !llvm.ptr
        %167 = llvm.load %154 : !llvm.ptr -> i32
        %168 = arith.extsi %167 : i32 to i64
        %169 = llvm.getelementptr %114[%168] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %135, %169 : i32, !llvm.ptr
        cf.br ^bb42
        ^bb42:
        %170 = llvm.load %154 : !llvm.ptr -> i32
        %171 = arith.constant 0 : i32
        %172 = arith.cmpi sgt, %170, %171 : i32
        cf.cond_br %172, ^bb43, ^bb44
        ^bb43:
          %173 = llvm.load %154 : !llvm.ptr -> i32
          %174 = arith.constant 1 : i32
          %175 = arith.subi %173, %174 : i32
          %176 = arith.constant 2 : i32
          %177 = arith.divsi %175, %176 : i32
          %180 = llvm.load %154 : !llvm.ptr -> i32
          %181 = arith.extsi %180 : i32 to i64
          %182 = llvm.getelementptr %99[%181] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %179 = llvm.load %182 : !llvm.ptr -> f64
          %184 = llvm.load %154 : !llvm.ptr -> i32
          %185 = arith.extsi %184 : i32 to i64
          %186 = llvm.getelementptr %104[%185] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %183 = llvm.load %186 : !llvm.ptr -> i32
          %188 = llvm.load %154 : !llvm.ptr -> i32
          %189 = arith.extsi %188 : i32 to i64
          %190 = llvm.getelementptr %109[%189] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %187 = llvm.load %190 : !llvm.ptr -> i32
          %192 = llvm.load %154 : !llvm.ptr -> i32
          %193 = arith.extsi %192 : i32 to i64
          %194 = llvm.getelementptr %114[%193] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %191 = llvm.load %194 : !llvm.ptr -> i32
          %196 = arith.extsi %177 : i32 to i64
          %197 = llvm.getelementptr %99[%196] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          %195 = llvm.load %197 : !llvm.ptr -> f64
          %199 = arith.extsi %177 : i32 to i64
          %200 = llvm.getelementptr %104[%199] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %198 = llvm.load %200 : !llvm.ptr -> i32
          %202 = arith.extsi %177 : i32 to i64
          %203 = llvm.getelementptr %109[%202] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %201 = llvm.load %203 : !llvm.ptr -> i32
          %205 = arith.extsi %177 : i32 to i64
          %206 = llvm.getelementptr %114[%205] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %204 = llvm.load %206 : !llvm.ptr -> i32
          %178 = func.call @heap_gt(%179, %183, %187, %191, %195, %198, %201, %204) : (f64, i32, i32, i32, f64, i32, i32, i32) -> i1
          cf.cond_br %178, ^bb45, ^bb46
          ^bb45:
            %208 = arith.extsi %177 : i32 to i64
            %209 = llvm.getelementptr %99[%208] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            %207 = llvm.load %209 : !llvm.ptr -> f64
            %211 = llvm.load %154 : !llvm.ptr -> i32
            %212 = arith.extsi %211 : i32 to i64
            %213 = llvm.getelementptr %99[%212] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            %210 = llvm.load %213 : !llvm.ptr -> f64
            %214 = arith.extsi %177 : i32 to i64
            %215 = llvm.getelementptr %99[%214] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            llvm.store %210, %215 : f64, !llvm.ptr
            %216 = llvm.load %154 : !llvm.ptr -> i32
            %217 = arith.extsi %216 : i32 to i64
            %218 = llvm.getelementptr %99[%217] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            llvm.store %207, %218 : f64, !llvm.ptr
            %220 = arith.extsi %177 : i32 to i64
            %221 = llvm.getelementptr %104[%220] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %219 = llvm.load %221 : !llvm.ptr -> i32
            %223 = llvm.load %154 : !llvm.ptr -> i32
            %224 = arith.extsi %223 : i32 to i64
            %225 = llvm.getelementptr %104[%224] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %222 = llvm.load %225 : !llvm.ptr -> i32
            %226 = arith.extsi %177 : i32 to i64
            %227 = llvm.getelementptr %104[%226] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %222, %227 : i32, !llvm.ptr
            %228 = llvm.load %154 : !llvm.ptr -> i32
            %229 = arith.extsi %228 : i32 to i64
            %230 = llvm.getelementptr %104[%229] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %219, %230 : i32, !llvm.ptr
            %232 = arith.extsi %177 : i32 to i64
            %233 = llvm.getelementptr %109[%232] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %231 = llvm.load %233 : !llvm.ptr -> i32
            %235 = llvm.load %154 : !llvm.ptr -> i32
            %236 = arith.extsi %235 : i32 to i64
            %237 = llvm.getelementptr %109[%236] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %234 = llvm.load %237 : !llvm.ptr -> i32
            %238 = arith.extsi %177 : i32 to i64
            %239 = llvm.getelementptr %109[%238] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %234, %239 : i32, !llvm.ptr
            %240 = llvm.load %154 : !llvm.ptr -> i32
            %241 = arith.extsi %240 : i32 to i64
            %242 = llvm.getelementptr %109[%241] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %231, %242 : i32, !llvm.ptr
            %244 = arith.extsi %177 : i32 to i64
            %245 = llvm.getelementptr %114[%244] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %243 = llvm.load %245 : !llvm.ptr -> i32
            %247 = llvm.load %154 : !llvm.ptr -> i32
            %248 = arith.extsi %247 : i32 to i64
            %249 = llvm.getelementptr %114[%248] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %246 = llvm.load %249 : !llvm.ptr -> i32
            %250 = arith.extsi %177 : i32 to i64
            %251 = llvm.getelementptr %114[%250] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %246, %251 : i32, !llvm.ptr
            %252 = llvm.load %154 : !llvm.ptr -> i32
            %253 = arith.extsi %252 : i32 to i64
            %254 = llvm.getelementptr %114[%253] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %243, %254 : i32, !llvm.ptr
            llvm.store %177, %154 : i32, !llvm.ptr
            cf.br ^bb47
          ^bb46:
            cf.br ^bb44
          ^bb47:
          cf.br ^bb42
        ^bb44:
        cf.br ^bb41
      ^bb40:
        %257 = arith.constant 0 : i32
        %258 = arith.extsi %257 : i32 to i64
        %259 = llvm.getelementptr %99[%258] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %256 = llvm.load %259 : !llvm.ptr -> f64
        %261 = arith.constant 0 : i32
        %262 = arith.extsi %261 : i32 to i64
        %263 = llvm.getelementptr %104[%262] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %260 = llvm.load %263 : !llvm.ptr -> i32
        %265 = arith.constant 0 : i32
        %266 = arith.extsi %265 : i32 to i64
        %267 = llvm.getelementptr %109[%266] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %264 = llvm.load %267 : !llvm.ptr -> i32
        %269 = arith.constant 0 : i32
        %270 = arith.extsi %269 : i32 to i64
        %271 = llvm.getelementptr %114[%270] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %268 = llvm.load %271 : !llvm.ptr -> i32
        %255 = func.call @heap_gt(%256, %260, %264, %268, %148, %149, %129, %135) : (f64, i32, i32, i32, f64, i32, i32, i32) -> i1
        cf.cond_br %255, ^bb48, ^bb49
        ^bb48:
          %272 = arith.constant 0 : i32
          %273 = arith.extsi %272 : i32 to i64
          %274 = llvm.getelementptr %99[%273] : (!llvm.ptr, i64) -> !llvm.ptr, f64
          llvm.store %148, %274 : f64, !llvm.ptr
          %275 = arith.constant 0 : i32
          %276 = arith.extsi %275 : i32 to i64
          %277 = llvm.getelementptr %104[%276] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %149, %277 : i32, !llvm.ptr
          %278 = arith.constant 0 : i32
          %279 = arith.extsi %278 : i32 to i64
          %280 = llvm.getelementptr %109[%279] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %129, %280 : i32, !llvm.ptr
          %281 = arith.constant 0 : i32
          %282 = arith.extsi %281 : i32 to i64
          %283 = llvm.getelementptr %114[%282] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %135, %283 : i32, !llvm.ptr
          %284 = arith.constant 0 : i32
          %285 = llvm.mlir.constant(1 : i64) : i64
          %286 = llvm.alloca %285 x i32 : (i64) -> !llvm.ptr
          llvm.store %284, %286 : i32, !llvm.ptr
          cf.br ^bb51
          ^bb51:
          %287 = arith.constant 1 : i1
          cf.cond_br %287, ^bb52, ^bb53
          ^bb52:
            %288 = arith.constant 2 : i32
            %289 = llvm.load %286 : !llvm.ptr -> i32
            %290 = arith.muli %288, %289 : i32
            %291 = arith.constant 1 : i32
            %292 = arith.addi %290, %291 : i32
            %293 = arith.constant 2 : i32
            %294 = llvm.load %286 : !llvm.ptr -> i32
            %295 = arith.muli %293, %294 : i32
            %296 = arith.constant 2 : i32
            %297 = arith.addi %295, %296 : i32
            %298 = llvm.load %286 : !llvm.ptr -> i32
            %299 = llvm.mlir.constant(1 : i64) : i64
            %300 = llvm.alloca %299 x i32 : (i64) -> !llvm.ptr
            llvm.store %298, %300 : i32, !llvm.ptr
            %301 = llvm.load %121 : !llvm.ptr -> i32
            %302 = arith.cmpi slt, %292, %301 : i32
            cf.cond_br %302, ^bb54, ^bb55
            ^bb54:
              %305 = arith.extsi %292 : i32 to i64
              %306 = llvm.getelementptr %99[%305] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              %304 = llvm.load %306 : !llvm.ptr -> f64
              %308 = arith.extsi %292 : i32 to i64
              %309 = llvm.getelementptr %104[%308] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %307 = llvm.load %309 : !llvm.ptr -> i32
              %311 = arith.extsi %292 : i32 to i64
              %312 = llvm.getelementptr %109[%311] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %310 = llvm.load %312 : !llvm.ptr -> i32
              %314 = arith.extsi %292 : i32 to i64
              %315 = llvm.getelementptr %114[%314] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %313 = llvm.load %315 : !llvm.ptr -> i32
              %317 = llvm.load %300 : !llvm.ptr -> i32
              %318 = arith.extsi %317 : i32 to i64
              %319 = llvm.getelementptr %99[%318] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              %316 = llvm.load %319 : !llvm.ptr -> f64
              %321 = llvm.load %300 : !llvm.ptr -> i32
              %322 = arith.extsi %321 : i32 to i64
              %323 = llvm.getelementptr %104[%322] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %320 = llvm.load %323 : !llvm.ptr -> i32
              %325 = llvm.load %300 : !llvm.ptr -> i32
              %326 = arith.extsi %325 : i32 to i64
              %327 = llvm.getelementptr %109[%326] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %324 = llvm.load %327 : !llvm.ptr -> i32
              %329 = llvm.load %300 : !llvm.ptr -> i32
              %330 = arith.extsi %329 : i32 to i64
              %331 = llvm.getelementptr %114[%330] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %328 = llvm.load %331 : !llvm.ptr -> i32
              %303 = func.call @heap_gt(%304, %307, %310, %313, %316, %320, %324, %328) : (f64, i32, i32, i32, f64, i32, i32, i32) -> i1
              cf.cond_br %303, ^bb57, ^bb58
              ^bb57:
                llvm.store %292, %300 : i32, !llvm.ptr
                cf.br ^bb59
              ^bb58:
                cf.br ^bb59
              ^bb59:
              cf.br ^bb56
            ^bb55:
              cf.br ^bb56
            ^bb56:
            %332 = llvm.load %121 : !llvm.ptr -> i32
            %333 = arith.cmpi slt, %297, %332 : i32
            cf.cond_br %333, ^bb60, ^bb61
            ^bb60:
              %336 = arith.extsi %297 : i32 to i64
              %337 = llvm.getelementptr %99[%336] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              %335 = llvm.load %337 : !llvm.ptr -> f64
              %339 = arith.extsi %297 : i32 to i64
              %340 = llvm.getelementptr %104[%339] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %338 = llvm.load %340 : !llvm.ptr -> i32
              %342 = arith.extsi %297 : i32 to i64
              %343 = llvm.getelementptr %109[%342] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %341 = llvm.load %343 : !llvm.ptr -> i32
              %345 = arith.extsi %297 : i32 to i64
              %346 = llvm.getelementptr %114[%345] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %344 = llvm.load %346 : !llvm.ptr -> i32
              %348 = llvm.load %300 : !llvm.ptr -> i32
              %349 = arith.extsi %348 : i32 to i64
              %350 = llvm.getelementptr %99[%349] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              %347 = llvm.load %350 : !llvm.ptr -> f64
              %352 = llvm.load %300 : !llvm.ptr -> i32
              %353 = arith.extsi %352 : i32 to i64
              %354 = llvm.getelementptr %104[%353] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %351 = llvm.load %354 : !llvm.ptr -> i32
              %356 = llvm.load %300 : !llvm.ptr -> i32
              %357 = arith.extsi %356 : i32 to i64
              %358 = llvm.getelementptr %109[%357] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %355 = llvm.load %358 : !llvm.ptr -> i32
              %360 = llvm.load %300 : !llvm.ptr -> i32
              %361 = arith.extsi %360 : i32 to i64
              %362 = llvm.getelementptr %114[%361] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %359 = llvm.load %362 : !llvm.ptr -> i32
              %334 = func.call @heap_gt(%335, %338, %341, %344, %347, %351, %355, %359) : (f64, i32, i32, i32, f64, i32, i32, i32) -> i1
              cf.cond_br %334, ^bb63, ^bb64
              ^bb63:
                llvm.store %297, %300 : i32, !llvm.ptr
                cf.br ^bb65
              ^bb64:
                cf.br ^bb65
              ^bb65:
              cf.br ^bb62
            ^bb61:
              cf.br ^bb62
            ^bb62:
            %363 = llvm.load %300 : !llvm.ptr -> i32
            %364 = llvm.load %286 : !llvm.ptr -> i32
            %365 = arith.cmpi ne, %363, %364 : i32
            cf.cond_br %365, ^bb66, ^bb67
            ^bb66:
              %367 = llvm.load %286 : !llvm.ptr -> i32
              %368 = arith.extsi %367 : i32 to i64
              %369 = llvm.getelementptr %99[%368] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              %366 = llvm.load %369 : !llvm.ptr -> f64
              %371 = llvm.load %300 : !llvm.ptr -> i32
              %372 = arith.extsi %371 : i32 to i64
              %373 = llvm.getelementptr %99[%372] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              %370 = llvm.load %373 : !llvm.ptr -> f64
              %374 = llvm.load %286 : !llvm.ptr -> i32
              %375 = arith.extsi %374 : i32 to i64
              %376 = llvm.getelementptr %99[%375] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              llvm.store %370, %376 : f64, !llvm.ptr
              %377 = llvm.load %300 : !llvm.ptr -> i32
              %378 = arith.extsi %377 : i32 to i64
              %379 = llvm.getelementptr %99[%378] : (!llvm.ptr, i64) -> !llvm.ptr, f64
              llvm.store %366, %379 : f64, !llvm.ptr
              %381 = llvm.load %286 : !llvm.ptr -> i32
              %382 = arith.extsi %381 : i32 to i64
              %383 = llvm.getelementptr %104[%382] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %380 = llvm.load %383 : !llvm.ptr -> i32
              %385 = llvm.load %300 : !llvm.ptr -> i32
              %386 = arith.extsi %385 : i32 to i64
              %387 = llvm.getelementptr %104[%386] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %384 = llvm.load %387 : !llvm.ptr -> i32
              %388 = llvm.load %286 : !llvm.ptr -> i32
              %389 = arith.extsi %388 : i32 to i64
              %390 = llvm.getelementptr %104[%389] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %384, %390 : i32, !llvm.ptr
              %391 = llvm.load %300 : !llvm.ptr -> i32
              %392 = arith.extsi %391 : i32 to i64
              %393 = llvm.getelementptr %104[%392] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %380, %393 : i32, !llvm.ptr
              %395 = llvm.load %286 : !llvm.ptr -> i32
              %396 = arith.extsi %395 : i32 to i64
              %397 = llvm.getelementptr %109[%396] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %394 = llvm.load %397 : !llvm.ptr -> i32
              %399 = llvm.load %300 : !llvm.ptr -> i32
              %400 = arith.extsi %399 : i32 to i64
              %401 = llvm.getelementptr %109[%400] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %398 = llvm.load %401 : !llvm.ptr -> i32
              %402 = llvm.load %286 : !llvm.ptr -> i32
              %403 = arith.extsi %402 : i32 to i64
              %404 = llvm.getelementptr %109[%403] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %398, %404 : i32, !llvm.ptr
              %405 = llvm.load %300 : !llvm.ptr -> i32
              %406 = arith.extsi %405 : i32 to i64
              %407 = llvm.getelementptr %109[%406] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %394, %407 : i32, !llvm.ptr
              %409 = llvm.load %286 : !llvm.ptr -> i32
              %410 = arith.extsi %409 : i32 to i64
              %411 = llvm.getelementptr %114[%410] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %408 = llvm.load %411 : !llvm.ptr -> i32
              %413 = llvm.load %300 : !llvm.ptr -> i32
              %414 = arith.extsi %413 : i32 to i64
              %415 = llvm.getelementptr %114[%414] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %412 = llvm.load %415 : !llvm.ptr -> i32
              %416 = llvm.load %286 : !llvm.ptr -> i32
              %417 = arith.extsi %416 : i32 to i64
              %418 = llvm.getelementptr %114[%417] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %412, %418 : i32, !llvm.ptr
              %419 = llvm.load %300 : !llvm.ptr -> i32
              %420 = arith.extsi %419 : i32 to i64
              %421 = llvm.getelementptr %114[%420] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %408, %421 : i32, !llvm.ptr
              %422 = llvm.load %300 : !llvm.ptr -> i32
              llvm.store %422, %286 : i32, !llvm.ptr
              cf.br ^bb68
            ^bb67:
              cf.br ^bb53
            ^bb68:
            cf.br ^bb51
          ^bb53:
          cf.br ^bb50
        ^bb49:
          cf.br ^bb50
        ^bb50:
        cf.br ^bb41
      ^bb41:
      %423 = llvm.load %124 : !llvm.ptr -> i32
      %424 = arith.constant 1 : i32
      %425 = arith.addi %423, %424 : i32
      llvm.store %425, %124 : i32, !llvm.ptr
      cf.br ^bb36
    ^bb38:
    %426 = arith.constant 0 : i32
    %427 = llvm.mlir.constant(1 : i64) : i64
    %428 = llvm.alloca %427 x i32 : (i64) -> !llvm.ptr
    llvm.store %426, %428 : i32, !llvm.ptr
    cf.br ^bb69
    ^bb69:
    %429 = llvm.load %428 : !llvm.ptr -> i32
    %430 = arith.cmpi slt, %429, %arg2 : i32
    cf.cond_br %430, ^bb70, ^bb71
    ^bb70:
      %432 = llvm.load %428 : !llvm.ptr -> i32
      %433 = arith.extsi %432 : i32 to i64
      %434 = llvm.getelementptr %109[%433] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %431 = llvm.load %434 : !llvm.ptr -> i32
      %435 = llvm.load %428 : !llvm.ptr -> i32
      %436 = arith.extsi %435 : i32 to i64
      %437 = llvm.getelementptr %arg0[%436] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %431, %437 : i32, !llvm.ptr
      %439 = llvm.load %428 : !llvm.ptr -> i32
      %440 = arith.extsi %439 : i32 to i64
      %441 = llvm.getelementptr %114[%440] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %438 = llvm.load %441 : !llvm.ptr -> i32
      %442 = llvm.load %428 : !llvm.ptr -> i32
      %443 = arith.extsi %442 : i32 to i64
      %444 = llvm.getelementptr %arg1[%443] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %438, %444 : i32, !llvm.ptr
      %445 = llvm.load %428 : !llvm.ptr -> i32
      %446 = arith.constant 1 : i32
      %447 = arith.addi %445, %446 : i32
      llvm.store %447, %428 : i32, !llvm.ptr
      cf.br ^bb69
    ^bb71:
    func.call @free(%99) : (!llvm.ptr) -> ()
    func.call @free(%104) : (!llvm.ptr) -> ()
    func.call @free(%109) : (!llvm.ptr) -> ()
    func.call @free(%114) : (!llvm.ptr) -> ()
    func.return
  }
  func.func @sort_by_slope(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32) -> () {
    %452 = arith.constant 1 : i32
    %453 = llvm.mlir.constant(1 : i64) : i64
    %454 = llvm.alloca %453 x i32 : (i64) -> !llvm.ptr
    llvm.store %452, %454 : i32, !llvm.ptr
    cf.br ^bb72
    ^bb72:
    %455 = llvm.load %454 : !llvm.ptr -> i32
    %456 = arith.cmpi slt, %455, %arg2 : i32
    cf.cond_br %456, ^bb73, ^bb74
    ^bb73:
      %457 = llvm.load %454 : !llvm.ptr -> i32
      %458 = llvm.mlir.constant(1 : i64) : i64
      %459 = llvm.alloca %458 x i32 : (i64) -> !llvm.ptr
      llvm.store %457, %459 : i32, !llvm.ptr
      cf.br ^bb75
      ^bb75:
      %460 = llvm.load %459 : !llvm.ptr -> i32
      %461 = arith.constant 0 : i32
      %462 = arith.cmpi sgt, %460, %461 : i32
      cf.cond_br %462, ^bb76, ^bb77
      ^bb76:
        %464 = llvm.load %459 : !llvm.ptr -> i32
        %465 = arith.constant 1 : i32
        %466 = arith.subi %464, %465 : i32
        %467 = arith.extsi %466 : i32 to i64
        %468 = llvm.getelementptr %arg1[%467] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %463 = llvm.load %468 : !llvm.ptr -> i32
        %469 = arith.sitofp %463 : i32 to f64
        %471 = llvm.load %459 : !llvm.ptr -> i32
        %472 = arith.constant 1 : i32
        %473 = arith.subi %471, %472 : i32
        %474 = arith.extsi %473 : i32 to i64
        %475 = llvm.getelementptr %arg0[%474] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %470 = llvm.load %475 : !llvm.ptr -> i32
        %476 = arith.sitofp %470 : i32 to f64
        %477 = arith.divf %469, %476 : f64
        %479 = llvm.load %459 : !llvm.ptr -> i32
        %480 = arith.extsi %479 : i32 to i64
        %481 = llvm.getelementptr %arg1[%480] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %478 = llvm.load %481 : !llvm.ptr -> i32
        %482 = arith.sitofp %478 : i32 to f64
        %484 = llvm.load %459 : !llvm.ptr -> i32
        %485 = arith.extsi %484 : i32 to i64
        %486 = llvm.getelementptr %arg0[%485] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %483 = llvm.load %486 : !llvm.ptr -> i32
        %487 = arith.sitofp %483 : i32 to f64
        %488 = arith.divf %482, %487 : f64
        %489 = arith.constant 0 : i1
        %490 = arith.cmpf ogt, %477, %488 : f64
        cf.cond_br %490, ^bb78, ^bb79
        ^bb78:
          %491 = arith.constant 1 : i1
          cf.br ^bb80(%491 : i1)
        ^bb79:
          %492 = arith.cmpf oeq, %477, %488 : f64
          cf.cond_br %492, ^bb81, ^bb82
          ^bb81:
            %494 = llvm.load %459 : !llvm.ptr -> i32
            %495 = arith.constant 1 : i32
            %496 = arith.subi %494, %495 : i32
            %497 = arith.extsi %496 : i32 to i64
            %498 = llvm.getelementptr %arg0[%497] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %493 = llvm.load %498 : !llvm.ptr -> i32
            %500 = llvm.load %459 : !llvm.ptr -> i32
            %501 = arith.extsi %500 : i32 to i64
            %502 = llvm.getelementptr %arg0[%501] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %499 = llvm.load %502 : !llvm.ptr -> i32
            %503 = arith.cmpi sgt, %493, %499 : i32
            cf.cond_br %503, ^bb84, ^bb85
            ^bb84:
              %504 = arith.constant 1 : i1
              cf.br ^bb86(%504 : i1)
            ^bb85:
              %506 = llvm.load %459 : !llvm.ptr -> i32
              %507 = arith.constant 1 : i32
              %508 = arith.subi %506, %507 : i32
              %509 = arith.extsi %508 : i32 to i64
              %510 = llvm.getelementptr %arg0[%509] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %505 = llvm.load %510 : !llvm.ptr -> i32
              %512 = llvm.load %459 : !llvm.ptr -> i32
              %513 = arith.extsi %512 : i32 to i64
              %514 = llvm.getelementptr %arg0[%513] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %511 = llvm.load %514 : !llvm.ptr -> i32
              %515 = arith.cmpi eq, %505, %511 : i32
              cf.cond_br %515, ^bb87, ^bb88
              ^bb87:
                %517 = llvm.load %459 : !llvm.ptr -> i32
                %518 = arith.constant 1 : i32
                %519 = arith.subi %517, %518 : i32
                %520 = arith.extsi %519 : i32 to i64
                %521 = llvm.getelementptr %arg1[%520] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %516 = llvm.load %521 : !llvm.ptr -> i32
                %523 = llvm.load %459 : !llvm.ptr -> i32
                %524 = arith.extsi %523 : i32 to i64
                %525 = llvm.getelementptr %arg1[%524] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %522 = llvm.load %525 : !llvm.ptr -> i32
                %526 = arith.cmpi sgt, %516, %522 : i32
                %527 = scf.if %526 -> (i1) {
                  %528 = arith.constant 1 : i1
                  scf.yield %528 : i1
                } else {
                  scf.yield %489 : i1
                }
                cf.br ^bb89(%527 : i1)
              ^bb88:
                cf.br ^bb89(%489 : i1)
              ^bb89(%529: i1):
              cf.br ^bb86(%529 : i1)
            ^bb86(%530: i1):
            cf.br ^bb83(%530 : i1)
          ^bb82:
            cf.br ^bb83(%489 : i1)
          ^bb83(%531: i1):
          cf.br ^bb80(%531 : i1)
        ^bb80(%532: i1):
        cf.cond_br %532, ^bb90, ^bb91
        ^bb90:
          %534 = llvm.load %459 : !llvm.ptr -> i32
          %535 = arith.constant 1 : i32
          %536 = arith.subi %534, %535 : i32
          %537 = arith.extsi %536 : i32 to i64
          %538 = llvm.getelementptr %arg0[%537] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %533 = llvm.load %538 : !llvm.ptr -> i32
          %540 = llvm.load %459 : !llvm.ptr -> i32
          %541 = arith.extsi %540 : i32 to i64
          %542 = llvm.getelementptr %arg0[%541] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %539 = llvm.load %542 : !llvm.ptr -> i32
          %543 = llvm.load %459 : !llvm.ptr -> i32
          %544 = arith.constant 1 : i32
          %545 = arith.subi %543, %544 : i32
          %546 = arith.extsi %545 : i32 to i64
          %547 = llvm.getelementptr %arg0[%546] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %539, %547 : i32, !llvm.ptr
          %548 = llvm.load %459 : !llvm.ptr -> i32
          %549 = arith.extsi %548 : i32 to i64
          %550 = llvm.getelementptr %arg0[%549] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %533, %550 : i32, !llvm.ptr
          %552 = llvm.load %459 : !llvm.ptr -> i32
          %553 = arith.constant 1 : i32
          %554 = arith.subi %552, %553 : i32
          %555 = arith.extsi %554 : i32 to i64
          %556 = llvm.getelementptr %arg1[%555] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %551 = llvm.load %556 : !llvm.ptr -> i32
          %558 = llvm.load %459 : !llvm.ptr -> i32
          %559 = arith.extsi %558 : i32 to i64
          %560 = llvm.getelementptr %arg1[%559] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %557 = llvm.load %560 : !llvm.ptr -> i32
          %561 = llvm.load %459 : !llvm.ptr -> i32
          %562 = arith.constant 1 : i32
          %563 = arith.subi %561, %562 : i32
          %564 = arith.extsi %563 : i32 to i64
          %565 = llvm.getelementptr %arg1[%564] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %557, %565 : i32, !llvm.ptr
          %566 = llvm.load %459 : !llvm.ptr -> i32
          %567 = arith.extsi %566 : i32 to i64
          %568 = llvm.getelementptr %arg1[%567] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %551, %568 : i32, !llvm.ptr
          cf.br ^bb92
        ^bb91:
          cf.br ^bb77
        ^bb92:
        %569 = llvm.load %459 : !llvm.ptr -> i32
        %570 = arith.constant 1 : i32
        %571 = arith.subi %569, %570 : i32
        llvm.store %571, %459 : i32, !llvm.ptr
        cf.br ^bb75
      ^bb77:
      %572 = llvm.load %454 : !llvm.ptr -> i32
      %573 = arith.constant 1 : i32
      %574 = arith.addi %572, %573 : i32
      llvm.store %574, %454 : i32, !llvm.ptr
      cf.br ^bb72
    ^bb74:
    func.return
  }
  func.func @area_from_half_edges(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32) -> i64 {
    %575 = arith.constant 0 : i32
    %576 = arith.extsi %575 : i32 to i64
    %577 = llvm.mlir.constant(1 : i64) : i64
    %578 = llvm.alloca %577 x i64 : (i64) -> !llvm.ptr
    llvm.store %576, %578 : i64, !llvm.ptr
    %579 = arith.constant 0 : i32
    %580 = arith.extsi %579 : i32 to i64
    %581 = llvm.mlir.constant(1 : i64) : i64
    %582 = llvm.alloca %581 x i64 : (i64) -> !llvm.ptr
    llvm.store %580, %582 : i64, !llvm.ptr
    %583 = arith.constant 0 : i32
    %584 = arith.extsi %583 : i32 to i64
    %585 = llvm.mlir.constant(1 : i64) : i64
    %586 = llvm.alloca %585 x i64 : (i64) -> !llvm.ptr
    llvm.store %584, %586 : i64, !llvm.ptr
    %587 = arith.constant 0 : i32
    %588 = llvm.mlir.constant(1 : i64) : i64
    %589 = llvm.alloca %588 x i32 : (i64) -> !llvm.ptr
    llvm.store %587, %589 : i32, !llvm.ptr
    cf.br ^bb93
    ^bb93:
    %590 = llvm.load %589 : !llvm.ptr -> i32
    %591 = arith.cmpi slt, %590, %arg2 : i32
    cf.cond_br %591, ^bb94, ^bb95
    ^bb94:
      %592 = llvm.load %586 : !llvm.ptr -> i64
      %593 = llvm.load %578 : !llvm.ptr -> i64
      %595 = llvm.load %589 : !llvm.ptr -> i32
      %596 = arith.extsi %595 : i32 to i64
      %597 = llvm.getelementptr %arg1[%596] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %594 = llvm.load %597 : !llvm.ptr -> i32
      %598 = arith.extsi %594 : i32 to i64
      %599 = arith.muli %593, %598 : i64
      %600 = arith.addi %592, %599 : i64
      %601 = llvm.load %582 : !llvm.ptr -> i64
      %603 = llvm.load %589 : !llvm.ptr -> i32
      %604 = arith.extsi %603 : i32 to i64
      %605 = llvm.getelementptr %arg0[%604] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %602 = llvm.load %605 : !llvm.ptr -> i32
      %606 = arith.extsi %602 : i32 to i64
      %607 = arith.muli %601, %606 : i64
      %608 = arith.subi %600, %607 : i64
      llvm.store %608, %586 : i64, !llvm.ptr
      %609 = llvm.load %578 : !llvm.ptr -> i64
      %611 = llvm.load %589 : !llvm.ptr -> i32
      %612 = arith.extsi %611 : i32 to i64
      %613 = llvm.getelementptr %arg0[%612] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %610 = llvm.load %613 : !llvm.ptr -> i32
      %614 = arith.extsi %610 : i32 to i64
      %615 = arith.addi %609, %614 : i64
      llvm.store %615, %578 : i64, !llvm.ptr
      %616 = llvm.load %582 : !llvm.ptr -> i64
      %618 = llvm.load %589 : !llvm.ptr -> i32
      %619 = arith.extsi %618 : i32 to i64
      %620 = llvm.getelementptr %arg1[%619] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %617 = llvm.load %620 : !llvm.ptr -> i32
      %621 = arith.extsi %617 : i32 to i64
      %622 = arith.addi %616, %621 : i64
      llvm.store %622, %582 : i64, !llvm.ptr
      %623 = llvm.load %589 : !llvm.ptr -> i32
      %624 = arith.constant 1 : i32
      %625 = arith.addi %623, %624 : i32
      llvm.store %625, %589 : i32, !llvm.ptr
      cf.br ^bb93
    ^bb95:
    %626 = llvm.load %586 : !llvm.ptr -> i64
    func.return %626 : i64
  }
  func.func @polygon_area_from_interior(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i32) -> i64 {
    func.call @sort_by_slope(%arg0, %arg1, %arg2) : (!llvm.ptr, !llvm.ptr, i32) -> ()
    %628 = arith.constant 1 : i32
    %629 = arith.addi %628, %arg2 : i32
    %630 = arith.constant 1 : i32
    %631 = arith.addi %629, %630 : i32
    %632 = arith.addi %631, %arg2 : i32
    %634 = arith.extsi %632 : i32 to i64
    %635 = arith.constant 4 : i32
    %637 = arith.extsi %635 : i32 to i64
    %636 = arith.muli %634, %637 : i64
    %633 = func.call @malloc(%636) : (i64) -> !llvm.ptr
    %639 = arith.extsi %632 : i32 to i64
    %640 = arith.constant 4 : i32
    %642 = arith.extsi %640 : i32 to i64
    %641 = arith.muli %639, %642 : i64
    %638 = func.call @malloc(%641) : (i64) -> !llvm.ptr
    %643 = arith.constant 0 : i32
    %644 = llvm.mlir.constant(1 : i64) : i64
    %645 = llvm.alloca %644 x i32 : (i64) -> !llvm.ptr
    llvm.store %643, %645 : i32, !llvm.ptr
    %646 = arith.constant 1 : i32
    %647 = llvm.load %645 : !llvm.ptr -> i32
    %648 = arith.extsi %647 : i32 to i64
    %649 = llvm.getelementptr %633[%648] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %646, %649 : i32, !llvm.ptr
    %650 = arith.constant 0 : i32
    %651 = llvm.load %645 : !llvm.ptr -> i32
    %652 = arith.extsi %651 : i32 to i64
    %653 = llvm.getelementptr %638[%652] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %650, %653 : i32, !llvm.ptr
    %654 = llvm.load %645 : !llvm.ptr -> i32
    %655 = arith.constant 1 : i32
    %656 = arith.addi %654, %655 : i32
    llvm.store %656, %645 : i32, !llvm.ptr
    %657 = arith.constant 0 : i32
    %658 = llvm.mlir.constant(1 : i64) : i64
    %659 = llvm.alloca %658 x i32 : (i64) -> !llvm.ptr
    llvm.store %657, %659 : i32, !llvm.ptr
    cf.br ^bb96
    ^bb96:
    %660 = llvm.load %659 : !llvm.ptr -> i32
    %661 = arith.cmpi slt, %660, %arg2 : i32
    cf.cond_br %661, ^bb97, ^bb98
    ^bb97:
      %663 = llvm.load %659 : !llvm.ptr -> i32
      %664 = arith.extsi %663 : i32 to i64
      %665 = llvm.getelementptr %arg0[%664] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %662 = llvm.load %665 : !llvm.ptr -> i32
      %666 = llvm.load %645 : !llvm.ptr -> i32
      %667 = arith.extsi %666 : i32 to i64
      %668 = llvm.getelementptr %633[%667] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %662, %668 : i32, !llvm.ptr
      %670 = llvm.load %659 : !llvm.ptr -> i32
      %671 = arith.extsi %670 : i32 to i64
      %672 = llvm.getelementptr %arg1[%671] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %669 = llvm.load %672 : !llvm.ptr -> i32
      %673 = llvm.load %645 : !llvm.ptr -> i32
      %674 = arith.extsi %673 : i32 to i64
      %675 = llvm.getelementptr %638[%674] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %669, %675 : i32, !llvm.ptr
      %676 = llvm.load %645 : !llvm.ptr -> i32
      %677 = arith.constant 1 : i32
      %678 = arith.addi %676, %677 : i32
      llvm.store %678, %645 : i32, !llvm.ptr
      %679 = llvm.load %659 : !llvm.ptr -> i32
      %680 = arith.constant 1 : i32
      %681 = arith.addi %679, %680 : i32
      llvm.store %681, %659 : i32, !llvm.ptr
      cf.br ^bb96
    ^bb98:
    %682 = arith.constant 0 : i32
    %683 = llvm.load %645 : !llvm.ptr -> i32
    %684 = arith.extsi %683 : i32 to i64
    %685 = llvm.getelementptr %633[%684] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %682, %685 : i32, !llvm.ptr
    %686 = arith.constant 1 : i32
    %687 = llvm.load %645 : !llvm.ptr -> i32
    %688 = arith.extsi %687 : i32 to i64
    %689 = llvm.getelementptr %638[%688] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %686, %689 : i32, !llvm.ptr
    %690 = llvm.load %645 : !llvm.ptr -> i32
    %691 = arith.constant 1 : i32
    %692 = arith.addi %690, %691 : i32
    llvm.store %692, %645 : i32, !llvm.ptr
    %693 = arith.constant 1 : i32
    %694 = arith.subi %arg2, %693 : i32
    %695 = llvm.mlir.constant(1 : i64) : i64
    %696 = llvm.alloca %695 x i32 : (i64) -> !llvm.ptr
    llvm.store %694, %696 : i32, !llvm.ptr
    cf.br ^bb99
    ^bb99:
    %697 = llvm.load %696 : !llvm.ptr -> i32
    %698 = arith.constant 0 : i32
    %699 = arith.cmpi sge, %697, %698 : i32
    cf.cond_br %699, ^bb100, ^bb101
    ^bb100:
      %701 = llvm.load %696 : !llvm.ptr -> i32
      %702 = arith.extsi %701 : i32 to i64
      %703 = llvm.getelementptr %arg0[%702] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %700 = llvm.load %703 : !llvm.ptr -> i32
      %705 = arith.constant 0 : i32
      %704 = arith.subi %705, %700 : i32
      %706 = llvm.load %645 : !llvm.ptr -> i32
      %707 = arith.extsi %706 : i32 to i64
      %708 = llvm.getelementptr %633[%707] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %704, %708 : i32, !llvm.ptr
      %710 = llvm.load %696 : !llvm.ptr -> i32
      %711 = arith.extsi %710 : i32 to i64
      %712 = llvm.getelementptr %arg1[%711] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %709 = llvm.load %712 : !llvm.ptr -> i32
      %713 = llvm.load %645 : !llvm.ptr -> i32
      %714 = arith.extsi %713 : i32 to i64
      %715 = llvm.getelementptr %638[%714] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %709, %715 : i32, !llvm.ptr
      %716 = llvm.load %645 : !llvm.ptr -> i32
      %717 = arith.constant 1 : i32
      %718 = arith.addi %716, %717 : i32
      llvm.store %718, %645 : i32, !llvm.ptr
      %719 = llvm.load %696 : !llvm.ptr -> i32
      %720 = arith.constant 1 : i32
      %721 = arith.subi %719, %720 : i32
      llvm.store %721, %696 : i32, !llvm.ptr
      cf.br ^bb99
    ^bb101:
    %722 = func.call @area_from_half_edges(%633, %638, %632) : (!llvm.ptr, !llvm.ptr, i32) -> i64
    func.call @free(%633) : (!llvm.ptr) -> ()
    func.call @free(%638) : (!llvm.ptr) -> ()
    func.return %722 : i64
  }
  func.func @compute_A(%arg0: i32) -> i64 {
    %725 = arith.constant 4 : i32
    %726 = arith.cmpi slt, %arg0, %725 : i32
    %727 = scf.if %726 -> (i1) {
      %728 = arith.constant true
      scf.yield %728 : i1
    } else {
      %729 = arith.constant 4 : i32
      %730 = arith.remsi %arg0, %729 : i32
      %731 = arith.constant 0 : i32
      %732 = arith.cmpi ne, %730, %731 : i32
      scf.yield %732 : i1
    }
    cf.cond_br %727, ^bb102, ^bb103
    ^bb102:
      %733 = arith.constant 0 : i32
      %734 = arith.extsi %733 : i32 to i64
      func.return %734 : i64
    ^bb103:
      cf.br ^bb104
    ^bb104:
    %735 = arith.constant 4 : i32
    %736 = arith.subi %arg0, %735 : i32
    %737 = arith.constant 4 : i32
    %738 = arith.divsi %736, %737 : i32
    %739 = arith.constant 0 : i32
    %740 = arith.cmpi eq, %738, %739 : i32
    cf.cond_br %740, ^bb105, ^bb106
    ^bb105:
      %741 = arith.constant 1 : i32
      %742 = arith.extsi %741 : i32 to i64
      func.return %742 : i64
    ^bb106:
      cf.br ^bb107
    ^bb107:
    %743 = arith.constant 40 : i32
    %744 = llvm.mlir.constant(1 : i64) : i64
    %745 = llvm.alloca %744 x i32 : (i64) -> !llvm.ptr
    llvm.store %743, %745 : i32, !llvm.ptr
    %747 = llvm.load %745 : !llvm.ptr -> i32
    func.call @primitive_pairs(%747) : (i32) -> ()
    %748 = arith.constant 1 : i32
    %750 = arith.constant 0 : i32
    %749 = arith.subi %750, %748 : i32
    %751 = arith.extsi %749 : i32 to i64
    %752 = llvm.mlir.constant(1 : i64) : i64
    %753 = llvm.alloca %752 x i64 : (i64) -> !llvm.ptr
    llvm.store %751, %753 : i64, !llvm.ptr
    %755 = arith.extsi %738 : i32 to i64
    %756 = arith.constant 4 : i32
    %758 = arith.extsi %756 : i32 to i64
    %757 = arith.muli %755, %758 : i64
    %754 = func.call @malloc(%757) : (i64) -> !llvm.ptr
    %760 = arith.extsi %738 : i32 to i64
    %761 = arith.constant 4 : i32
    %763 = arith.extsi %761 : i32 to i64
    %762 = arith.muli %760, %763 : i64
    %759 = func.call @malloc(%762) : (i64) -> !llvm.ptr
    %764 = arith.constant 1 : i32
    %765 = llvm.mlir.constant(1 : i64) : i64
    %766 = llvm.alloca %765 x i32 : (i64) -> !llvm.ptr
    llvm.store %764, %766 : i32, !llvm.ptr
    cf.br ^bb108
    ^bb108:
    %767 = llvm.load %766 : !llvm.ptr -> i32
    %768 = arith.constant 1000 : i32
    %769 = arith.cmpi sle, %767, %768 : i32
    cf.cond_br %769, ^bb109, ^bb110
    ^bb109:
      %770 = llvm.load %766 : !llvm.ptr -> i32
      %771 = arith.sitofp %770 : i32 to f64
      %772 = arith.constant 1000.0 : f32
      %774 = arith.extf %772 : f32 to f64
      %773 = arith.divf %771, %774 : f64
      cf.br ^bb111
      ^bb111:
      %775 = arith.constant 1 : i1
      cf.cond_br %775, ^bb112, ^bb113
      ^bb112:
        func.call @n_smallest(%754, %759, %738, %773) : (!llvm.ptr, !llvm.ptr, i32, f64) -> ()
        %777 = arith.constant 0 : i32
        %778 = llvm.mlir.constant(1 : i64) : i64
        %779 = llvm.alloca %778 x i32 : (i64) -> !llvm.ptr
        llvm.store %777, %779 : i32, !llvm.ptr
        %780 = arith.constant 0 : i32
        %781 = llvm.mlir.constant(1 : i64) : i64
        %782 = llvm.alloca %781 x i32 : (i64) -> !llvm.ptr
        llvm.store %780, %782 : i32, !llvm.ptr
        %783 = arith.constant 0 : i32
        %784 = llvm.mlir.constant(1 : i64) : i64
        %785 = llvm.alloca %784 x i32 : (i64) -> !llvm.ptr
        llvm.store %783, %785 : i32, !llvm.ptr
        cf.br ^bb114
        ^bb114:
        %786 = llvm.load %785 : !llvm.ptr -> i32
        %787 = arith.cmpi slt, %786, %738 : i32
        cf.cond_br %787, ^bb115, ^bb116
        ^bb115:
          %789 = llvm.load %785 : !llvm.ptr -> i32
          %790 = arith.extsi %789 : i32 to i64
          %791 = llvm.getelementptr %754[%790] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %788 = llvm.load %791 : !llvm.ptr -> i32
          %792 = llvm.load %779 : !llvm.ptr -> i32
          %793 = arith.cmpi sgt, %788, %792 : i32
          cf.cond_br %793, ^bb117, ^bb118
          ^bb117:
            %795 = llvm.load %785 : !llvm.ptr -> i32
            %796 = arith.extsi %795 : i32 to i64
            %797 = llvm.getelementptr %754[%796] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %794 = llvm.load %797 : !llvm.ptr -> i32
            llvm.store %794, %779 : i32, !llvm.ptr
            cf.br ^bb119
          ^bb118:
            cf.br ^bb119
          ^bb119:
          %799 = llvm.load %785 : !llvm.ptr -> i32
          %800 = arith.extsi %799 : i32 to i64
          %801 = llvm.getelementptr %759[%800] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %798 = llvm.load %801 : !llvm.ptr -> i32
          %802 = llvm.load %782 : !llvm.ptr -> i32
          %803 = arith.cmpi sgt, %798, %802 : i32
          cf.cond_br %803, ^bb120, ^bb121
          ^bb120:
            %805 = llvm.load %785 : !llvm.ptr -> i32
            %806 = arith.extsi %805 : i32 to i64
            %807 = llvm.getelementptr %759[%806] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %804 = llvm.load %807 : !llvm.ptr -> i32
            llvm.store %804, %782 : i32, !llvm.ptr
            cf.br ^bb122
          ^bb121:
            cf.br ^bb122
          ^bb122:
          %808 = llvm.load %785 : !llvm.ptr -> i32
          %809 = arith.constant 1 : i32
          %810 = arith.addi %808, %809 : i32
          llvm.store %810, %785 : i32, !llvm.ptr
          cf.br ^bb114
        ^bb116:
        %811 = llvm.load %779 : !llvm.ptr -> i32
        %812 = llvm.load %745 : !llvm.ptr -> i32
        %813 = arith.cmpi slt, %811, %812 : i32
        %814 = scf.if %813 -> (i1) {
          %815 = llvm.load %782 : !llvm.ptr -> i32
          %816 = llvm.load %745 : !llvm.ptr -> i32
          %817 = arith.cmpi slt, %815, %816 : i32
          scf.yield %817 : i1
        } else {
          %818 = arith.constant false
          scf.yield %818 : i1
        }
        cf.cond_br %814, ^bb123, ^bb124
        ^bb123:
          cf.br ^bb113
        ^bb124:
          cf.br ^bb125
        ^bb125:
        %819 = llvm.load %745 : !llvm.ptr -> i32
        %820 = arith.constant 2 : i32
        %821 = arith.muli %819, %820 : i32
        llvm.store %821, %745 : i32, !llvm.ptr
        %823 = llvm.load %745 : !llvm.ptr -> i32
        func.call @primitive_pairs(%823) : (i32) -> ()
        cf.br ^bb111
      ^bb113:
      %824 = func.call @polygon_area_from_interior(%754, %759, %738) : (!llvm.ptr, !llvm.ptr, i32) -> i64
      %825 = llvm.load %753 : !llvm.ptr -> i64
      %826 = arith.constant 1 : i32
      %828 = arith.constant 0 : i32
      %827 = arith.subi %828, %826 : i32
      %830 = arith.extsi %827 : i32 to i64
      %829 = arith.cmpi eq, %825, %830 : i64
      %831 = scf.if %829 -> (i1) {
        %832 = arith.constant true
        scf.yield %832 : i1
      } else {
        %833 = llvm.load %753 : !llvm.ptr -> i64
        %834 = arith.cmpi slt, %824, %833 : i64
        scf.yield %834 : i1
      }
      cf.cond_br %831, ^bb126, ^bb127
      ^bb126:
        llvm.store %824, %753 : i64, !llvm.ptr
        cf.br ^bb128
      ^bb127:
        cf.br ^bb128
      ^bb128:
      %835 = llvm.load %766 : !llvm.ptr -> i32
      %836 = arith.constant 1 : i32
      %837 = arith.addi %835, %836 : i32
      llvm.store %837, %766 : i32, !llvm.ptr
      cf.br ^bb108
    ^bb110:
    func.call @free(%754) : (!llvm.ptr) -> ()
    func.call @free(%759) : (!llvm.ptr) -> ()
    %840 = llvm.load %753 : !llvm.ptr -> i64
    func.return %840 : i64
  }
  func.func @main() -> i32 {
    %841 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %843 = arith.constant 1000 : i32
    %842 = func.call @compute_A(%843) : (i32) -> i64
    %844 = llvm.call @printf(%841, %842) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %845 = arith.constant 0 : i32
    func.return %845 : i32
  }
}