Problem 367

Expected 3-shuffle bozo-sort steps for n=11, rounded nearest.

Answer48271207
Output48271207
StatusPASS
Native helperno
Runtime0 ms
Peak memory1072 KB
Time complexityO(n^2) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n * s^2)
Space complexityO(n^2)O(s^2)
ApproachFlow solutionMarkov chain or DP over states
VerdictUnknown

Flow source

# Project Euler 367
# Expected 3-shuffle bozo-sort steps for n=11, rounded nearest.

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

function factorial_f(n: i64) -> f64 {
    let mut r: f64 = 1.0
    let mut i: i64 = 2
    while i <= n {
        r = r * (i as f64)
        i = i + 1
    }
    return r
}

function dim_part(parts: ptr<i32>, plen: i64) -> f64 {
    let mut n: i64 = 0
    let mut i: i64 = 0
    while i < plen {
        n = n + (parts[i] as i64)
        i = i + 1
    }
    if n == 0 { return 1.0 }
    let mut maxc: i64 = 0
    i = 0
    while i < plen {
        if (parts[i] as i64) > maxc { maxc = parts[i] as i64 }
        i = i + 1
    }
    let col_lens: ptr<i32> = calloc(maxc, 4)
    let mut c: i64 = 0
    while c < maxc {
        let mut cnt: i64 = 0
        i = 0
        while i < plen {
            if (parts[i] as i64) > c { cnt = cnt + 1 }
            i = i + 1
        }
        col_lens[c] = cnt as i32
        c = c + 1
    }
    let mut prod: f64 = 1.0
    i = 0
    while i < plen {
        let ln: i64 = parts[i] as i64
        c = 0
        while c < ln {
            let hook: f64 = ((ln - c) + (col_lens[c] as i64) - i - 1) as f64
            prod = prod * hook
            c = c + 1
        }
        i = i + 1
    }
    free(col_lens)
    return factorial_f(n) / prod
}

function cell_in(cells: ptr<i32>, ncells: i64, r: i32, c: i32) -> bool {
    let mut i: i64 = 0
    while i < ncells {
        if cells[2 * i] == r && cells[2 * i + 1] == c { return true }
        i = i + 1
    }
    return false
}

function is_connected(cells: ptr<i32>, ncells: i64) -> bool {
    if ncells == 0 { return false }
    let seen: ptr<i8> = calloc(ncells, 1)
    let stack: ptr<i64> = calloc(ncells, 8)
    stack[0] = 0
    seen[0] = 1
    let mut top: i64 = 1
    let mut count: i64 = 1
    while top > 0 {
        top = top - 1
        let idx: i64 = stack[top]
        let r: i32 = cells[2 * idx]
        let c: i32 = cells[2 * idx + 1]
        let mut d: i64 = 0
        while d < 4 {
            let mut nr: i32 = r
            let mut nc: i32 = c
            match d {
                0 => { nr = r + 1 }
                1 => { nr = r - 1 }
                2 => { nc = c + 1 }
                _ => { nc = c - 1 }
            }
            let mut j: i64 = 0
            while j < ncells {
                if cells[2 * j] == nr && cells[2 * j + 1] == nc {
                    if seen[j] == 0 {
                        seen[j] = 1
                        stack[top] = j
                        top = top + 1
                        count = count + 1
                    }
                    break
                }
                j = j + 1
            }
            d = d + 1
        }
    }
    free(stack)
    free(seen)
    return count == ncells
}

function has_2x2(cells: ptr<i32>, ncells: i64) -> bool {
    let mut i: i64 = 0
    while i < ncells {
        let r: i32 = cells[2 * i]
        let c: i32 = cells[2 * i + 1]
        if cell_in(cells, ncells, r + 1, c) && cell_in(cells, ncells, r, c + 1) && cell_in(cells, ncells, r + 1, c + 1) {
            return true
        }
        i = i + 1
    }
    return false
}

function remaining_partition(parts: ptr<i32>, plen: i64, cells: ptr<i32>, ncells: i64,
                             out: ptr<i32>, out_len: ptr<i64>) -> bool {
    let mut new_len: i64 = 0
    let mut r: i64 = 0
    while r < plen {
        let ln: i64 = parts[r] as i64
        let mut max_rem: i64 = 0 - 1
        let mut c: i64 = 0
        while c < ln {
            if !cell_in(cells, ncells, r as i32, c as i32) {
                if c > max_rem { max_rem = c }
            }
            c = c + 1
        }
        let mut nrow: i64 = 0
        if max_rem >= 0 {
            nrow = max_rem + 1
            c = 0
            while c < nrow {
                if cell_in(cells, ncells, r as i32, c as i32) {
                    return false
                }
                c = c + 1
            }
        }
        out[new_len] = nrow as i32
        new_len = new_len + 1
        r = r + 1
    }
    while new_len > 0 && out[new_len - 1] == 0 {
        new_len = new_len - 1
    }
    let mut i: i64 = 0
    while i + 1 < new_len {
        if out[i] < out[i + 1] { return false }
        i = i + 1
    }
    out_len[0] = new_len
    return true
}

function character_cycle_k(parts: ptr<i32>, plen: i64, k: i64) -> f64 {
    let cells_all: ptr<i32> = calloc(2 * 64, 4)
    let mut nall: i64 = 0
    let mut r: i64 = 0
    while r < plen {
        let mut c: i64 = 0
        while c < (parts[r] as i64) {
            cells_all[2 * nall] = r as i32
            cells_all[2 * nall + 1] = c as i32
            nall = nall + 1
            c = c + 1
        }
        r = r + 1
    }
    if k > nall {
        free(cells_all)
        return 0.0
    }
    let mut total: f64 = 0.0
    let limit: i64 = 1 << nall
    let mut mask: i64 = 0
    while mask < limit {
        let mut bits: i64 = 0
        let mut t: i64 = mask
        while t > 0 {
            bits = bits + (t & 1)
            t = t >> 1
        }
        if bits == k {
            let strip: ptr<i32> = calloc(2 * k, 4)
            let mut si: i64 = 0
            let mut i: i64 = 0
            while i < nall {
                if ((mask >> i) & 1) == 1 {
                    strip[2 * si] = cells_all[2 * i]
                    strip[2 * si + 1] = cells_all[2 * i + 1]
                    si = si + 1
                }
                i = i + 1
            }
            let out: ptr<i32> = calloc(16, 4)
            let out_len: ptr<i64> = calloc(1, 8)
            if remaining_partition(parts, plen, strip, k, out, out_len) {
                if is_connected(strip, k) {
                    if !has_2x2(strip, k) {
                        let mut rows_used: i64 = 0
                        let seen_r: ptr<i8> = calloc(16, 1)
                        i = 0
                        while i < k {
                            let rr: i32 = strip[2 * i]
                            if seen_r[rr] == 0 {
                                seen_r[rr] = 1
                                rows_used = rows_used + 1
                            }
                            i = i + 1
                        }
                        free(seen_r)
                        let height: i64 = rows_used - 1
                        let dnu: f64 = dim_part(out, out_len[0])
                        let mut sign: f64 = 1.0
                        if (height % 2) == 1 { sign = 0.0 - 1.0 }
                        total = total + sign * dnu
                    }
                }
            }
            free(out_len)
            free(out)
            free(strip)
        }
        mask = mask + 1
    }
    free(cells_all)
    return total
}

function process_partition(parts: ptr<i32>, plen: i64, n: i64) -> f64 {
    if plen == 1 && (parts[0] as i64) == n { return 0.0 }
    let d: f64 = dim_part(parts, plen)
    let chi2: f64 = character_cycle_k(parts, plen, 2)
    let chi3: f64 = character_cycle_k(parts, plen, 3)
    let r2: f64 = chi2 / d
    let r3: f64 = chi3 / d
    let lam: f64 = 1.0 / 6.0 + 0.5 * r2 + (1.0 / 3.0) * r3
    return (d * d) / (1.0 - lam)
}

function gen_and_sum(parts: ptr<i32>, plen: i64, rem: i64, maxp: i64, n: i64) -> f64 {
    if rem == 0 {
        return process_partition(parts, plen, n)
    }
    let mut total: f64 = 0.0
    let mut first: i64 = maxp
    if first > rem { first = rem }
    while first >= 1 {
        parts[plen] = first as i32
        total = total + gen_and_sum(parts, plen + 1, rem - first, first, n)
        first = first - 1
    }
    return total
}

function main() -> i32 {
    let parts: ptr<i32> = calloc(11, 4)
    let x: f64 = gen_and_sum(parts, 0, 11, 11, 11)
    free(parts)
    let mut ans: i64 = floor(x) as i64
    let frac: f64 = x - (ans as f64)
    if frac >= 0.5 { ans = ans + 1 }
    printf("%lld\n", ans)
    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; }

double factorial_f_i64(int64_t n);
double dim_part_ptr_i32_i64(int32_t* parts, int64_t plen);
bool cell_in_ptr_i32_i64_i32_i32(int32_t* cells, int64_t ncells, int32_t r, int32_t c);
bool is_connected_ptr_i32_i64(int32_t* cells, int64_t ncells);
bool has_2x2_ptr_i32_i64(int32_t* cells, int64_t ncells);
bool remaining_partition_ptr_i32_i64_ptr_i32_i64_ptr_i32_ptr_i64(int32_t* parts, int64_t plen, int32_t* cells, int64_t ncells, int32_t* out, int64_t* out_len);
double character_cycle_k_ptr_i32_i64_i64(int32_t* parts, int64_t plen, int64_t k);
double process_partition_ptr_i32_i64_i64(int32_t* parts, int64_t plen, int64_t n);
double gen_and_sum_ptr_i32_i64_i64_i64_i64(int32_t* parts, int64_t plen, int64_t rem, int64_t maxp, int64_t n);
int32_t main(void);




double factorial_f_i64(int64_t n) {
    double r = 1.0;
    int64_t i = 2;
    while (i <= n) {
        r = (r * ((double)(i)));
        i = (i + 1);
    }
    return r;
}

double dim_part_ptr_i32_i64(int32_t* parts, int64_t plen) {
    int64_t n = 0;
    int64_t i = 0;
    while (i < plen) {
        n = (n + ((int64_t)(parts[i])));
        i = (i + 1);
    }
    if (n == 0) {
        return 1.0;
    }
    int64_t maxc = 0;
    i = 0;
    while (i < plen) {
        if (((int64_t)(parts[i])) > maxc) {
            maxc = ((int64_t)(parts[i]));
        }
        i = (i + 1);
    }
    int32_t* col_lens = (int32_t*)(calloc(maxc, 4));
    int64_t c = 0;
    while (c < maxc) {
        int64_t cnt = 0;
        i = 0;
        while (i < plen) {
            if (((int64_t)(parts[i])) > c) {
                cnt = (cnt + 1);
            }
            i = (i + 1);
        }
        col_lens[c] = ((int32_t)(cnt));
        c = (c + 1);
    }
    double prod = 1.0;
    i = 0;
    while (i < plen) {
        int64_t ln = ((int64_t)(parts[i]));
        c = 0;
        while (c < ln) {
            double hook = ((double)(((((ln - c) + ((int64_t)(col_lens[c]))) - i) - 1)));
            prod = (prod * hook);
            c = (c + 1);
        }
        i = (i + 1);
    }
    free(col_lens);
    return (factorial_f_i64(n) / prod);
}

bool cell_in_ptr_i32_i64_i32_i32(int32_t* cells, int64_t ncells, int32_t r, int32_t c) {
    int64_t i = 0;
    while (i < ncells) {
        if ((cells[(2 * i)] == r && cells[((2 * i) + 1)] == c)) {
            return 1;
        }
        i = (i + 1);
    }
    return 0;
}

bool is_connected_ptr_i32_i64(int32_t* cells, int64_t ncells) {
    if (ncells == 0) {
        return 0;
    }
    int8_t* seen = (int8_t*)(calloc(ncells, 1));
    int64_t* stack = (int64_t*)(calloc(ncells, 8));
    stack[0] = 0;
    seen[0] = 1;
    int64_t top = 1;
    int64_t count = 1;
    while (top > 0) {
        top = (top - 1);
        int64_t idx = stack[top];
        int32_t r = cells[(2 * idx)];
        int32_t c = cells[((2 * idx) + 1)];
        int64_t d = 0;
        while (d < 4) {
            int32_t nr = r;
            int32_t nc = c;
            { // match block
                if ((d) == 0) {
                    nr = (r + 1);
                } else if ((d) == 1) {
                    nr = (r - 1);
                } else if ((d) == 2) {
                    nc = (c + 1);
                } else { // exhaustive
                    nc = (c - 1);
                }
            } // end match
            int64_t j = 0;
            while (j < ncells) {
                if ((cells[(2 * j)] == nr && cells[((2 * j) + 1)] == nc)) {
                    if (seen[j] == 0) {
                        seen[j] = 1;
                        stack[top] = j;
                        top = (top + 1);
                        count = (count + 1);
                    }
                    break;
                }
                j = (j + 1);
            }
            d = (d + 1);
        }
    }
    free(stack);
    free(seen);
    return count == ncells;
}

bool has_2x2_ptr_i32_i64(int32_t* cells, int64_t ncells) {
    int64_t i = 0;
    while (i < ncells) {
        int32_t r = cells[(2 * i)];
        int32_t c = cells[((2 * i) + 1)];
        if (((cell_in_ptr_i32_i64_i32_i32(cells, ncells, (r + 1), c) && cell_in_ptr_i32_i64_i32_i32(cells, ncells, r, (c + 1))) && cell_in_ptr_i32_i64_i32_i32(cells, ncells, (r + 1), (c + 1)))) {
            return 1;
        }
        i = (i + 1);
    }
    return 0;
}

bool remaining_partition_ptr_i32_i64_ptr_i32_i64_ptr_i32_ptr_i64(int32_t* parts, int64_t plen, int32_t* cells, int64_t ncells, int32_t* out, int64_t* out_len) {
    int64_t new_len = 0;
    int64_t r = 0;
    while (r < plen) {
        int64_t ln = ((int64_t)(parts[r]));
        int64_t max_rem = (0 - 1);
        int64_t c = 0;
        while (c < ln) {
            if ((!(cell_in_ptr_i32_i64_i32_i32(cells, ncells, ((int32_t)(r)), ((int32_t)(c)))))) {
                if (c > max_rem) {
                    max_rem = c;
                }
            }
            c = (c + 1);
        }
        int64_t nrow = 0;
        if (max_rem >= 0) {
            nrow = (max_rem + 1);
            c = 0;
            while (c < nrow) {
                if (cell_in_ptr_i32_i64_i32_i32(cells, ncells, ((int32_t)(r)), ((int32_t)(c)))) {
                    return 0;
                }
                c = (c + 1);
            }
        }
        out[new_len] = ((int32_t)(nrow));
        new_len = (new_len + 1);
        r = (r + 1);
    }
    while ((new_len > 0 && out[(new_len - 1)] == 0)) {
        new_len = (new_len - 1);
    }
    int64_t i = 0;
    while ((i + 1) < new_len) {
        if (out[i] < out[(i + 1)]) {
            return 0;
        }
        i = (i + 1);
    }
    out_len[0] = new_len;
    return 1;
}

double character_cycle_k_ptr_i32_i64_i64(int32_t* parts, int64_t plen, int64_t k) {
    int32_t* cells_all = (int32_t*)(calloc((2 * 64), 4));
    int64_t nall = 0;
    int64_t r = 0;
    while (r < plen) {
        int64_t c = 0;
        while (c < ((int64_t)(parts[r]))) {
            cells_all[(2 * nall)] = ((int32_t)(r));
            cells_all[((2 * nall) + 1)] = ((int32_t)(c));
            nall = (nall + 1);
            c = (c + 1);
        }
        r = (r + 1);
    }
    if (k > nall) {
        free(cells_all);
        return 0.0;
    }
    double total = 0.0;
    int64_t limit = FLOW_CHECKED_SHL((1), (nall));
    int64_t mask = 0;
    while (mask < limit) {
        int64_t bits = 0;
        int64_t t = mask;
        while (t > 0) {
            bits = (bits + (t & 1));
            t = FLOW_CHECKED_SHR((t), (1));
        }
        if (bits == k) {
            int32_t* strip = (int32_t*)(calloc((2 * k), 4));
            int64_t si = 0;
            int64_t i = 0;
            while (i < nall) {
                if ((FLOW_CHECKED_SHR((mask), (i)) & 1) == 1) {
                    strip[(2 * si)] = cells_all[(2 * i)];
                    strip[((2 * si) + 1)] = cells_all[((2 * i) + 1)];
                    si = (si + 1);
                }
                i = (i + 1);
            }
            int32_t* out = (int32_t*)(calloc(16, 4));
            int64_t* out_len = (int64_t*)(calloc(1, 8));
            if (remaining_partition_ptr_i32_i64_ptr_i32_i64_ptr_i32_ptr_i64(parts, plen, strip, k, out, out_len)) {
                if (is_connected_ptr_i32_i64(strip, k)) {
                    if ((!(has_2x2_ptr_i32_i64(strip, k)))) {
                        int64_t rows_used = 0;
                        int8_t* seen_r = (int8_t*)(calloc(16, 1));
                        i = 0;
                        while (i < k) {
                            int32_t rr = strip[(2 * i)];
                            if (seen_r[rr] == 0) {
                                seen_r[rr] = 1;
                                rows_used = (rows_used + 1);
                            }
                            i = (i + 1);
                        }
                        free(seen_r);
                        int64_t height = (rows_used - 1);
                        double dnu = dim_part_ptr_i32_i64(out, out_len[0]);
                        double sign = 1.0;
                        if (FLOW_CHECKED_MOD((height), (2)) == 1) {
                            sign = (0.0 - 1.0);
                        }
                        total = (total + (sign * dnu));
                    }
                }
            }
            free(out_len);
            free(out);
            free(strip);
        }
        mask = (mask + 1);
    }
    free(cells_all);
    return total;
}

double process_partition_ptr_i32_i64_i64(int32_t* parts, int64_t plen, int64_t n) {
    if ((plen == 1 && ((int64_t)(parts[0])) == n)) {
        return 0.0;
    }
    double d = dim_part_ptr_i32_i64(parts, plen);
    double chi2 = character_cycle_k_ptr_i32_i64_i64(parts, plen, 2);
    double chi3 = character_cycle_k_ptr_i32_i64_i64(parts, plen, 3);
    double r2 = (chi2 / d);
    double r3 = (chi3 / d);
    double lam = (((1.0 / 6.0) + (0.5 * r2)) + ((1.0 / 3.0) * r3));
    return ((d * d) / (1.0 - lam));
}

double gen_and_sum_ptr_i32_i64_i64_i64_i64(int32_t* parts, int64_t plen, int64_t rem, int64_t maxp, int64_t n) {
    if (rem == 0) {
        return process_partition_ptr_i32_i64_i64(parts, plen, n);
    }
    double total = 0.0;
    int64_t first = maxp;
    if (first > rem) {
        first = rem;
    }
    while (first >= 1) {
        parts[plen] = ((int32_t)(first));
        total = (total + gen_and_sum_ptr_i32_i64_i64_i64_i64(parts, (plen + 1), (rem - first), first, n));
        first = (first - 1);
    }
    return total;
}

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