Problem 740

Secret Santa: probability the last person gets at least one of their own slips. State DP: (u1, u2, k) where u1/u2 are unprocessed non-last people with 1/2 slips, k = last person's slips remaining (0..2).

Answer0.0189581208
Output0.0189581208
StatusPASS
Native helperno
Runtime10 ms
Peak memory1616 KB
Time complexityO(1) (estimated)
Space complexityO(n) (estimated)

Performance comparison

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

Flow source

# Project Euler 740
# Secret Santa: probability the last person gets at least one of their own slips.
# State DP: (u1, u2, k) where u1/u2 are unprocessed non-last people with 1/2 slips,
# k = last person's slips remaining (0..2).

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
    function memset(s: ptr<void>, c: i32, n: i64) -> ptr<void>
}

const N: i32 = 100
const MAXU: i32 = 102
const MAXK: i32 = 3
const STATE_SIZE: i32 = 31212

function sidx(u1: i32, u2: i32, k: i32) -> i32 {
    return (u1 * MAXU + u2) * MAXK + k
}

function q(n: i32) -> f64 {
    if n < 2 { return 0.0 }
    if n == 2 { return 1.0 }

    let mut cur: ptr<f64> = calloc((STATE_SIZE as i64), 8) as ptr<f64>
    let mut nxt: ptr<f64> = calloc((STATE_SIZE as i64), 8) as ptr<f64>

    cur[sidx(0, n - 1, 2)] = 1.0

    let mut t: i32 = 0
    while t < n - 1 {
        let m: i32 = (n - 1) - t
        let T_total: i32 = 2 * n - 2 * t

        memset(nxt as ptr<void>, 0, (STATE_SIZE as i64) * 8)

        let mut u1: i32 = 0
        while u1 <= m {
            let mut u2: i32 = 0
            while u2 <= m - u1 {
                let u0: i32 = m - u1 - u2
                let mut k: i32 = 0
                while k <= 2 {
                    let prob: f64 = cur[sidx(u1, u2, k)]
                    if prob == 0.0 {
                        k = k + 1
                        continue
                    }

                    let sp: i32 = T_total - u1 - 2 * u2 - k
                    if sp < 0 {
                        k = k + 1
                        continue
                    }

                    let mut s: i32 = 0
                    while s <= 2 {
                        let mut cnt: i32 = u2
                        if s == 0 { cnt = u0 }
                        else { if s == 1 { cnt = u1 } }
                        if cnt == 0 {
                            s = s + 1
                            continue
                        }
                        let p_actor: f64 = prob * ((cnt as f64) / (m as f64))

                        let mut uu1: i32 = u1
                        let mut uu2: i32 = u2
                        if s == 1 { uu1 = uu1 - 1 }
                        else { if s == 2 { uu2 = uu2 - 1 } }

                        let C1: i32 = T_total - s
                        let invC1: f64 = 1.0 / (C1 as f64)
                        let C2: i32 = (T_total - 1) - s
                        let invC2: f64 = 1.0 / (C2 as f64)

                        # First draw: last-person slip
                        if k > 0 {
                            let p1: f64 = (k as f64) * invC1
                            let a: i32 = uu1
                            let b: i32 = uu2
                            let kk: i32 = k - 1
                            let ss: i32 = sp
                            if kk > 0 {
                                let idx: i32 = sidx(a, b, kk - 1)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((kk as f64) * invC2)
                            }
                            if a > 0 {
                                let idx: i32 = sidx(a - 1, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((a as f64) * invC2)
                            }
                            if b > 0 {
                                let idx: i32 = sidx(a + 1, b - 1, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * (2.0 * (b as f64) * invC2)
                            }
                            if ss > 0 {
                                let idx: i32 = sidx(a, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((ss as f64) * invC2)
                            }
                        }

                        # First draw: unprocessed(1)
                        if uu1 > 0 {
                            let p1: f64 = (uu1 as f64) * invC1
                            let a: i32 = uu1 - 1
                            let b: i32 = uu2
                            let kk: i32 = k
                            let ss: i32 = sp
                            if kk > 0 {
                                let idx: i32 = sidx(a, b, kk - 1)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((kk as f64) * invC2)
                            }
                            if a > 0 {
                                let idx: i32 = sidx(a - 1, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((a as f64) * invC2)
                            }
                            if b > 0 {
                                let idx: i32 = sidx(a + 1, b - 1, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * (2.0 * (b as f64) * invC2)
                            }
                            if ss > 0 {
                                let idx: i32 = sidx(a, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((ss as f64) * invC2)
                            }
                        }

                        # First draw: unprocessed(2)
                        if uu2 > 0 {
                            let p1: f64 = 2.0 * (uu2 as f64) * invC1
                            let a: i32 = uu1 + 1
                            let b: i32 = uu2 - 1
                            let kk: i32 = k
                            let ss: i32 = sp
                            if kk > 0 {
                                let idx: i32 = sidx(a, b, kk - 1)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((kk as f64) * invC2)
                            }
                            if a > 0 {
                                let idx: i32 = sidx(a - 1, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((a as f64) * invC2)
                            }
                            if b > 0 {
                                let idx: i32 = sidx(a + 1, b - 1, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * (2.0 * (b as f64) * invC2)
                            }
                            if ss > 0 {
                                let idx: i32 = sidx(a, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((ss as f64) * invC2)
                            }
                        }

                        # First draw: processed pool
                        if sp > 0 {
                            let p1: f64 = (sp as f64) * invC1
                            let a: i32 = uu1
                            let b: i32 = uu2
                            let kk: i32 = k
                            let ss: i32 = sp - 1
                            if kk > 0 {
                                let idx: i32 = sidx(a, b, kk - 1)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((kk as f64) * invC2)
                            }
                            if a > 0 {
                                let idx: i32 = sidx(a - 1, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((a as f64) * invC2)
                            }
                            if b > 0 {
                                let idx: i32 = sidx(a + 1, b - 1, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * (2.0 * (b as f64) * invC2)
                            }
                            if ss > 0 {
                                let idx: i32 = sidx(a, b, kk)
                                nxt[idx] = nxt[idx] + p_actor * p1 * ((ss as f64) * invC2)
                            }
                        }

                        s = s + 1
                    }
                    k = k + 1
                }
                u2 = u2 + 1
            }
            u1 = u1 + 1
        }

        let tmp: ptr<f64> = cur
        cur = nxt
        nxt = tmp

        t = t + 1
    }

    # After n-1 people, only 2 slips remain. Fail iff k > 0.
    let mut ans: f64 = 0.0
    let mut i: i32 = 0
    while i < STATE_SIZE {
        let k: i32 = i % MAXK
        if k > 0 { ans = ans + cur[i] }
        i = i + 1
    }

    free(cur as ptr<void>)
    free(nxt as ptr<void>)
    return ans
}

function main() -> i32 {
    printf("%.10f\n", q(100))
    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 sidx_i32_i32_i32(int32_t u1, int32_t u2, int32_t k);
double q_i32(int32_t n);
int32_t main(void);

static const int32_t N = 100;
static const int32_t MAXU = 102;
static const int32_t MAXK = 3;
static const int32_t STATE_SIZE = 31212;




int32_t sidx_i32_i32_i32(int32_t u1, int32_t u2, int32_t k) {
    return ((((u1 * MAXU) + u2) * MAXK) + k);
}

double q_i32(int32_t n) {
    if (n < 2) {
        return 0.0;
    }
    if (n == 2) {
        return 1.0;
    }
    double* cur = (double*)(((double*)(calloc(((int64_t)(STATE_SIZE)), 8))));
    double* nxt = (double*)(((double*)(calloc(((int64_t)(STATE_SIZE)), 8))));
    cur[sidx_i32_i32_i32(0, (n - 1), 2)] = 1.0;
    int32_t t = 0;
    while (t < (n - 1)) {
        int32_t m = ((n - 1) - t);
        int32_t T_total = ((2 * n) - (2 * t));
        memset(((void*)(nxt)), 0, (((int64_t)(STATE_SIZE)) * 8));
        int32_t u1 = 0;
        while (u1 <= m) {
            int32_t u2 = 0;
            while (u2 <= (m - u1)) {
                int32_t u0 = ((m - u1) - u2);
                int32_t k = 0;
                while (k <= 2) {
                    double prob = cur[sidx_i32_i32_i32(u1, u2, k)];
                    if (prob == 0.0) {
                        k = (k + 1);
                        continue;
                    }
                    int32_t sp = (((T_total - u1) - (2 * u2)) - k);
                    if (sp < 0) {
                        k = (k + 1);
                        continue;
                    }
                    int32_t s = 0;
                    while (s <= 2) {
                        int32_t cnt = u2;
                        if (s == 0) {
                            cnt = u0;
                        } else {
                            if (s == 1) {
                                cnt = u1;
                            }
                        }
                        if (cnt == 0) {
                            s = (s + 1);
                            continue;
                        }
                        double p_actor = (prob * (((double)(cnt)) / ((double)(m))));
                        int32_t uu1 = u1;
                        int32_t uu2 = u2;
                        if (s == 1) {
                            uu1 = (uu1 - 1);
                        } else {
                            if (s == 2) {
                                uu2 = (uu2 - 1);
                            }
                        }
                        int32_t C1 = (T_total - s);
                        double invC1 = (1.0 / ((double)(C1)));
                        int32_t C2 = ((T_total - 1) - s);
                        double invC2 = (1.0 / ((double)(C2)));
                        if (k > 0) {
                            double p1 = (((double)(k)) * invC1);
                            int32_t a = uu1;
                            int32_t b = uu2;
                            int32_t kk = (k - 1);
                            int32_t ss = sp;
                            if (kk > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, (kk - 1));
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(kk)) * invC2)));
                            }
                            if (a > 0) {
                                int32_t idx = sidx_i32_i32_i32((a - 1), b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(a)) * invC2)));
                            }
                            if (b > 0) {
                                int32_t idx = sidx_i32_i32_i32((a + 1), (b - 1), kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * ((2.0 * ((double)(b))) * invC2)));
                            }
                            if (ss > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(ss)) * invC2)));
                            }
                        }
                        if (uu1 > 0) {
                            double p1 = (((double)(uu1)) * invC1);
                            int32_t a = (uu1 - 1);
                            int32_t b = uu2;
                            int32_t kk = k;
                            int32_t ss = sp;
                            if (kk > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, (kk - 1));
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(kk)) * invC2)));
                            }
                            if (a > 0) {
                                int32_t idx = sidx_i32_i32_i32((a - 1), b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(a)) * invC2)));
                            }
                            if (b > 0) {
                                int32_t idx = sidx_i32_i32_i32((a + 1), (b - 1), kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * ((2.0 * ((double)(b))) * invC2)));
                            }
                            if (ss > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(ss)) * invC2)));
                            }
                        }
                        if (uu2 > 0) {
                            double p1 = ((2.0 * ((double)(uu2))) * invC1);
                            int32_t a = (uu1 + 1);
                            int32_t b = (uu2 - 1);
                            int32_t kk = k;
                            int32_t ss = sp;
                            if (kk > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, (kk - 1));
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(kk)) * invC2)));
                            }
                            if (a > 0) {
                                int32_t idx = sidx_i32_i32_i32((a - 1), b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(a)) * invC2)));
                            }
                            if (b > 0) {
                                int32_t idx = sidx_i32_i32_i32((a + 1), (b - 1), kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * ((2.0 * ((double)(b))) * invC2)));
                            }
                            if (ss > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(ss)) * invC2)));
                            }
                        }
                        if (sp > 0) {
                            double p1 = (((double)(sp)) * invC1);
                            int32_t a = uu1;
                            int32_t b = uu2;
                            int32_t kk = k;
                            int32_t ss = (sp - 1);
                            if (kk > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, (kk - 1));
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(kk)) * invC2)));
                            }
                            if (a > 0) {
                                int32_t idx = sidx_i32_i32_i32((a - 1), b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(a)) * invC2)));
                            }
                            if (b > 0) {
                                int32_t idx = sidx_i32_i32_i32((a + 1), (b - 1), kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * ((2.0 * ((double)(b))) * invC2)));
                            }
                            if (ss > 0) {
                                int32_t idx = sidx_i32_i32_i32(a, b, kk);
                                nxt[idx] = (nxt[idx] + ((p_actor * p1) * (((double)(ss)) * invC2)));
                            }
                        }
                        s = (s + 1);
                    }
                    k = (k + 1);
                }
                u2 = (u2 + 1);
            }
            u1 = (u1 + 1);
        }
        double* tmp = (double*)(cur);
        cur = nxt;
        nxt = tmp;
        t = (t + 1);
    }
    double ans = 0.0;
    int32_t i = 0;
    while (i < STATE_SIZE) {
        int32_t k = FLOW_CHECKED_MOD((i), (MAXK));
        if (k > 0) {
            ans = (ans + cur[i]);
        }
        i = (i + 1);
    }
    free(((void*)(cur)));
    free(((void*)(nxt)));
    return ans;
}

int32_t main(void) {
    printf("%.10f\n", q_i32(100));
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("%.10f\n\00") {addr_space = 0 : i32} : !llvm.array<7 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()
  func.func private @memset(!llvm.ptr, i32, i64) -> !llvm.ptr
  // Constant: N
  llvm.mlir.global internal constant @N(100 : i32) : i32
  // Constant: MAXU
  llvm.mlir.global internal constant @MAXU(102 : i32) : i32
  // Constant: MAXK
  llvm.mlir.global internal constant @MAXK(3 : i32) : i32
  // Constant: STATE_SIZE
  llvm.mlir.global internal constant @STATE_SIZE(31212 : i32) : i32
  func.func @sidx(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
    %0 = llvm.mlir.addressof @MAXU : !llvm.ptr
    %1 = llvm.load %0 : !llvm.ptr -> i32
    %2 = arith.muli %arg0, %1 : i32
    %3 = arith.addi %2, %arg1 : i32
    %4 = llvm.mlir.addressof @MAXK : !llvm.ptr
    %5 = llvm.load %4 : !llvm.ptr -> i32
    %6 = arith.muli %3, %5 : i32
    %7 = arith.addi %6, %arg2 : i32
    func.return %7 : i32
  }
  func.func @q(%arg0: i32) -> f64 {
    %8 = arith.constant 2 : i32
    %9 = arith.cmpi slt, %arg0, %8 : i32
    cf.cond_br %9, ^bb0, ^bb1
    ^bb0:
      %10 = arith.constant 0.0 : f32
      %11 = arith.extf %10 : f32 to f64
      func.return %11 : f64
    ^bb1:
      cf.br ^bb2
    ^bb2:
    %12 = arith.constant 2 : i32
    %13 = arith.cmpi eq, %arg0, %12 : i32
    cf.cond_br %13, ^bb3, ^bb4
    ^bb3:
      %14 = arith.constant 1.0 : f32
      %15 = arith.extf %14 : f32 to f64
      func.return %15 : f64
    ^bb4:
      cf.br ^bb5
    ^bb5:
    %17 = llvm.mlir.addressof @STATE_SIZE : !llvm.ptr
    %18 = llvm.load %17 : !llvm.ptr -> i32
    %19 = arith.extsi %18 : i32 to i64
    %20 = arith.constant 8 : i32
    %21 = arith.extsi %20 : i32 to i64
    %16 = func.call @calloc(%19, %21) : (i64, i64) -> !llvm.ptr
    %22 = llvm.mlir.constant(1 : i64) : i64
    %23 = llvm.alloca %22 x !llvm.ptr : (i64) -> !llvm.ptr
    llvm.store %16, %23 : !llvm.ptr, !llvm.ptr
    %25 = llvm.mlir.addressof @STATE_SIZE : !llvm.ptr
    %26 = llvm.load %25 : !llvm.ptr -> i32
    %27 = arith.extsi %26 : i32 to i64
    %28 = arith.constant 8 : i32
    %29 = arith.extsi %28 : i32 to i64
    %24 = func.call @calloc(%27, %29) : (i64, i64) -> !llvm.ptr
    %30 = llvm.mlir.constant(1 : i64) : i64
    %31 = llvm.alloca %30 x !llvm.ptr : (i64) -> !llvm.ptr
    llvm.store %24, %31 : !llvm.ptr, !llvm.ptr
    %32 = arith.constant 1.0 : f32
    %33 = llvm.load %23 : !llvm.ptr -> !llvm.ptr
    %35 = arith.constant 0 : i32
    %36 = arith.constant 1 : i32
    %37 = arith.subi %arg0, %36 : i32
    %38 = arith.constant 2 : i32
    %34 = func.call @sidx(%35, %37, %38) : (i32, i32, i32) -> i32
    %39 = arith.extf %32 : f32 to f64
    %40 = arith.extsi %34 : i32 to i64
    %41 = llvm.getelementptr %33[%40] : (!llvm.ptr, i64) -> !llvm.ptr, f64
    llvm.store %39, %41 : f64, !llvm.ptr
    %42 = arith.constant 0 : i32
    %43 = llvm.mlir.constant(1 : i64) : i64
    %44 = llvm.alloca %43 x i32 : (i64) -> !llvm.ptr
    llvm.store %42, %44 : i32, !llvm.ptr
    cf.br ^bb6
    ^bb6:
    %45 = llvm.load %44 : !llvm.ptr -> i32
    %46 = arith.constant 1 : i32
    %47 = arith.subi %arg0, %46 : i32
    %48 = arith.cmpi slt, %45, %47 : i32
    cf.cond_br %48, ^bb7, ^bb8
    ^bb7:
      %49 = arith.constant 1 : i32
      %50 = arith.subi %arg0, %49 : i32
      %51 = llvm.load %44 : !llvm.ptr -> i32
      %52 = arith.subi %50, %51 : i32
      %53 = arith.constant 2 : i32
      %54 = arith.muli %53, %arg0 : i32
      %55 = arith.constant 2 : i32
      %56 = llvm.load %44 : !llvm.ptr -> i32
      %57 = arith.muli %55, %56 : i32
      %58 = arith.subi %54, %57 : i32
      %60 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
      %61 = arith.constant 0 : i32
      %62 = llvm.mlir.addressof @STATE_SIZE : !llvm.ptr
      %63 = llvm.load %62 : !llvm.ptr -> i32
      %64 = arith.extsi %63 : i32 to i64
      %65 = arith.constant 8 : i32
      %67 = arith.extsi %65 : i32 to i64
      %66 = arith.muli %64, %67 : i64
      %59 = func.call @memset(%60, %61, %66) : (!llvm.ptr, i32, i64) -> !llvm.ptr
      %68 = arith.constant 0 : i32
      %69 = llvm.mlir.constant(1 : i64) : i64
      %70 = llvm.alloca %69 x i32 : (i64) -> !llvm.ptr
      llvm.store %68, %70 : i32, !llvm.ptr
      cf.br ^bb9
      ^bb9:
      %71 = llvm.load %70 : !llvm.ptr -> i32
      %72 = arith.cmpi sle, %71, %52 : i32
      cf.cond_br %72, ^bb10, ^bb11
      ^bb10:
        %73 = arith.constant 0 : i32
        %74 = llvm.mlir.constant(1 : i64) : i64
        %75 = llvm.alloca %74 x i32 : (i64) -> !llvm.ptr
        llvm.store %73, %75 : i32, !llvm.ptr
        cf.br ^bb12
        ^bb12:
        %76 = llvm.load %75 : !llvm.ptr -> i32
        %77 = llvm.load %70 : !llvm.ptr -> i32
        %78 = arith.subi %52, %77 : i32
        %79 = arith.cmpi sle, %76, %78 : i32
        cf.cond_br %79, ^bb13, ^bb14
        ^bb13:
          %80 = llvm.load %70 : !llvm.ptr -> i32
          %81 = arith.subi %52, %80 : i32
          %82 = llvm.load %75 : !llvm.ptr -> i32
          %83 = arith.subi %81, %82 : i32
          %84 = arith.constant 0 : i32
          %85 = llvm.mlir.constant(1 : i64) : i64
          %86 = llvm.alloca %85 x i32 : (i64) -> !llvm.ptr
          llvm.store %84, %86 : i32, !llvm.ptr
          cf.br ^bb15
          ^bb15:
          %87 = llvm.load %86 : !llvm.ptr -> i32
          %88 = arith.constant 2 : i32
          %89 = arith.cmpi sle, %87, %88 : i32
          cf.cond_br %89, ^bb16, ^bb17
          ^bb16:
            %91 = llvm.load %23 : !llvm.ptr -> !llvm.ptr
            %93 = llvm.load %70 : !llvm.ptr -> i32
            %94 = llvm.load %75 : !llvm.ptr -> i32
            %95 = llvm.load %86 : !llvm.ptr -> i32
            %92 = func.call @sidx(%93, %94, %95) : (i32, i32, i32) -> i32
            %96 = arith.extsi %92 : i32 to i64
            %97 = llvm.getelementptr %91[%96] : (!llvm.ptr, i64) -> !llvm.ptr, f64
            %90 = llvm.load %97 : !llvm.ptr -> f64
            %98 = arith.constant 0.0 : f32
            %100 = arith.extf %98 : f32 to f64
            %99 = arith.cmpf oeq, %90, %100 : f64
            cf.cond_br %99, ^bb18, ^bb19
            ^bb18:
              %101 = llvm.load %86 : !llvm.ptr -> i32
              %102 = arith.constant 1 : i32
              %103 = arith.addi %101, %102 : i32
              llvm.store %103, %86 : i32, !llvm.ptr
              cf.br ^bb15
            ^bb19:
              cf.br ^bb20
            ^bb20:
            %104 = llvm.load %70 : !llvm.ptr -> i32
            %105 = arith.subi %58, %104 : i32
            %106 = arith.constant 2 : i32
            %107 = llvm.load %75 : !llvm.ptr -> i32
            %108 = arith.muli %106, %107 : i32
            %109 = arith.subi %105, %108 : i32
            %110 = llvm.load %86 : !llvm.ptr -> i32
            %111 = arith.subi %109, %110 : i32
            %112 = arith.constant 0 : i32
            %113 = arith.cmpi slt, %111, %112 : i32
            cf.cond_br %113, ^bb21, ^bb22
            ^bb21:
              %114 = llvm.load %86 : !llvm.ptr -> i32
              %115 = arith.constant 1 : i32
              %116 = arith.addi %114, %115 : i32
              llvm.store %116, %86 : i32, !llvm.ptr
              cf.br ^bb15
            ^bb22:
              cf.br ^bb23
            ^bb23:
            %117 = arith.constant 0 : i32
            %118 = llvm.mlir.constant(1 : i64) : i64
            %119 = llvm.alloca %118 x i32 : (i64) -> !llvm.ptr
            llvm.store %117, %119 : i32, !llvm.ptr
            cf.br ^bb24
            ^bb24:
            %120 = llvm.load %119 : !llvm.ptr -> i32
            %121 = arith.constant 2 : i32
            %122 = arith.cmpi sle, %120, %121 : i32
            cf.cond_br %122, ^bb25, ^bb26
            ^bb25:
              %123 = llvm.load %75 : !llvm.ptr -> i32
              %124 = llvm.mlir.constant(1 : i64) : i64
              %125 = llvm.alloca %124 x i32 : (i64) -> !llvm.ptr
              llvm.store %123, %125 : i32, !llvm.ptr
              %126 = llvm.load %119 : !llvm.ptr -> i32
              %127 = arith.constant 0 : i32
              %128 = arith.cmpi eq, %126, %127 : i32
              cf.cond_br %128, ^bb27, ^bb28
              ^bb27:
                llvm.store %83, %125 : i32, !llvm.ptr
                cf.br ^bb29
              ^bb28:
                %129 = llvm.load %119 : !llvm.ptr -> i32
                %130 = arith.constant 1 : i32
                %131 = arith.cmpi eq, %129, %130 : i32
                cf.cond_br %131, ^bb30, ^bb31
                ^bb30:
                  %132 = llvm.load %70 : !llvm.ptr -> i32
                  llvm.store %132, %125 : i32, !llvm.ptr
                  cf.br ^bb32
                ^bb31:
                  cf.br ^bb32
                ^bb32:
                cf.br ^bb29
              ^bb29:
              %133 = llvm.load %125 : !llvm.ptr -> i32
              %134 = arith.constant 0 : i32
              %135 = arith.cmpi eq, %133, %134 : i32
              cf.cond_br %135, ^bb33, ^bb34
              ^bb33:
                %136 = llvm.load %119 : !llvm.ptr -> i32
                %137 = arith.constant 1 : i32
                %138 = arith.addi %136, %137 : i32
                llvm.store %138, %119 : i32, !llvm.ptr
                cf.br ^bb24
              ^bb34:
                cf.br ^bb35
              ^bb35:
              %139 = llvm.load %125 : !llvm.ptr -> i32
              %140 = arith.sitofp %139 : i32 to f64
              %141 = arith.sitofp %52 : i32 to f64
              %142 = arith.divf %140, %141 : f64
              %143 = arith.mulf %90, %142 : f64
              %144 = llvm.load %70 : !llvm.ptr -> i32
              %145 = llvm.mlir.constant(1 : i64) : i64
              %146 = llvm.alloca %145 x i32 : (i64) -> !llvm.ptr
              llvm.store %144, %146 : i32, !llvm.ptr
              %147 = llvm.load %75 : !llvm.ptr -> i32
              %148 = llvm.mlir.constant(1 : i64) : i64
              %149 = llvm.alloca %148 x i32 : (i64) -> !llvm.ptr
              llvm.store %147, %149 : i32, !llvm.ptr
              %150 = llvm.load %119 : !llvm.ptr -> i32
              %151 = arith.constant 1 : i32
              %152 = arith.cmpi eq, %150, %151 : i32
              cf.cond_br %152, ^bb36, ^bb37
              ^bb36:
                %153 = llvm.load %146 : !llvm.ptr -> i32
                %154 = arith.constant 1 : i32
                %155 = arith.subi %153, %154 : i32
                llvm.store %155, %146 : i32, !llvm.ptr
                cf.br ^bb38
              ^bb37:
                %156 = llvm.load %119 : !llvm.ptr -> i32
                %157 = arith.constant 2 : i32
                %158 = arith.cmpi eq, %156, %157 : i32
                cf.cond_br %158, ^bb39, ^bb40
                ^bb39:
                  %159 = llvm.load %149 : !llvm.ptr -> i32
                  %160 = arith.constant 1 : i32
                  %161 = arith.subi %159, %160 : i32
                  llvm.store %161, %149 : i32, !llvm.ptr
                  cf.br ^bb41
                ^bb40:
                  cf.br ^bb41
                ^bb41:
                cf.br ^bb38
              ^bb38:
              %162 = llvm.load %119 : !llvm.ptr -> i32
              %163 = arith.subi %58, %162 : i32
              %164 = arith.constant 1.0 : f32
              %165 = arith.sitofp %163 : i32 to f64
              %167 = arith.extf %164 : f32 to f64
              %166 = arith.divf %167, %165 : f64
              %168 = arith.constant 1 : i32
              %169 = arith.subi %58, %168 : i32
              %170 = llvm.load %119 : !llvm.ptr -> i32
              %171 = arith.subi %169, %170 : i32
              %172 = arith.constant 1.0 : f32
              %173 = arith.sitofp %171 : i32 to f64
              %175 = arith.extf %172 : f32 to f64
              %174 = arith.divf %175, %173 : f64
              %176 = llvm.load %86 : !llvm.ptr -> i32
              %177 = arith.constant 0 : i32
              %178 = arith.cmpi sgt, %176, %177 : i32
              cf.cond_br %178, ^bb42, ^bb43
              ^bb42:
                %179 = llvm.load %86 : !llvm.ptr -> i32
                %180 = arith.sitofp %179 : i32 to f64
                %181 = arith.mulf %180, %166 : f64
                %182 = llvm.load %146 : !llvm.ptr -> i32
                %183 = llvm.load %149 : !llvm.ptr -> i32
                %184 = llvm.load %86 : !llvm.ptr -> i32
                %185 = arith.constant 1 : i32
                %186 = arith.subi %184, %185 : i32
                %187 = arith.constant 0 : i32
                %188 = arith.cmpi sgt, %186, %187 : i32
                cf.cond_br %188, ^bb45, ^bb46
                ^bb45:
                  %190 = arith.constant 1 : i32
                  %191 = arith.subi %186, %190 : i32
                  %189 = func.call @sidx(%182, %183, %191) : (i32, i32, i32) -> i32
                  %193 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %194 = arith.extsi %189 : i32 to i64
                  %195 = llvm.getelementptr %193[%194] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %192 = llvm.load %195 : !llvm.ptr -> f64
                  %196 = arith.mulf %143, %181 : f64
                  %197 = arith.sitofp %186 : i32 to f64
                  %198 = arith.mulf %197, %174 : f64
                  %199 = arith.mulf %196, %198 : f64
                  %200 = arith.addf %192, %199 : f64
                  %201 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %202 = arith.extsi %189 : i32 to i64
                  %203 = llvm.getelementptr %201[%202] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %200, %203 : f64, !llvm.ptr
                  cf.br ^bb47
                ^bb46:
                  cf.br ^bb47
                ^bb47:
                %204 = arith.constant 0 : i32
                %205 = arith.cmpi sgt, %182, %204 : i32
                cf.cond_br %205, ^bb48, ^bb49
                ^bb48:
                  %207 = arith.constant 1 : i32
                  %208 = arith.subi %182, %207 : i32
                  %206 = func.call @sidx(%208, %183, %186) : (i32, i32, i32) -> i32
                  %210 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %211 = arith.extsi %206 : i32 to i64
                  %212 = llvm.getelementptr %210[%211] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %209 = llvm.load %212 : !llvm.ptr -> f64
                  %213 = arith.mulf %143, %181 : f64
                  %214 = arith.sitofp %182 : i32 to f64
                  %215 = arith.mulf %214, %174 : f64
                  %216 = arith.mulf %213, %215 : f64
                  %217 = arith.addf %209, %216 : f64
                  %218 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %219 = arith.extsi %206 : i32 to i64
                  %220 = llvm.getelementptr %218[%219] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %217, %220 : f64, !llvm.ptr
                  cf.br ^bb50
                ^bb49:
                  cf.br ^bb50
                ^bb50:
                %221 = arith.constant 0 : i32
                %222 = arith.cmpi sgt, %183, %221 : i32
                cf.cond_br %222, ^bb51, ^bb52
                ^bb51:
                  %224 = arith.constant 1 : i32
                  %225 = arith.addi %182, %224 : i32
                  %226 = arith.constant 1 : i32
                  %227 = arith.subi %183, %226 : i32
                  %223 = func.call @sidx(%225, %227, %186) : (i32, i32, i32) -> i32
                  %229 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %230 = arith.extsi %223 : i32 to i64
                  %231 = llvm.getelementptr %229[%230] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %228 = llvm.load %231 : !llvm.ptr -> f64
                  %232 = arith.mulf %143, %181 : f64
                  %233 = arith.constant 2.0 : f32
                  %234 = arith.sitofp %183 : i32 to f64
                  %236 = arith.extf %233 : f32 to f64
                  %235 = arith.mulf %236, %234 : f64
                  %237 = arith.mulf %235, %174 : f64
                  %238 = arith.mulf %232, %237 : f64
                  %239 = arith.addf %228, %238 : f64
                  %240 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %241 = arith.extsi %223 : i32 to i64
                  %242 = llvm.getelementptr %240[%241] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %239, %242 : f64, !llvm.ptr
                  cf.br ^bb53
                ^bb52:
                  cf.br ^bb53
                ^bb53:
                %243 = arith.constant 0 : i32
                %244 = arith.cmpi sgt, %111, %243 : i32
                cf.cond_br %244, ^bb54, ^bb55
                ^bb54:
                  %245 = func.call @sidx(%182, %183, %186) : (i32, i32, i32) -> i32
                  %247 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %248 = arith.extsi %245 : i32 to i64
                  %249 = llvm.getelementptr %247[%248] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %246 = llvm.load %249 : !llvm.ptr -> f64
                  %250 = arith.mulf %143, %181 : f64
                  %251 = arith.sitofp %111 : i32 to f64
                  %252 = arith.mulf %251, %174 : f64
                  %253 = arith.mulf %250, %252 : f64
                  %254 = arith.addf %246, %253 : f64
                  %255 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %256 = arith.extsi %245 : i32 to i64
                  %257 = llvm.getelementptr %255[%256] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %254, %257 : f64, !llvm.ptr
                  cf.br ^bb56
                ^bb55:
                  cf.br ^bb56
                ^bb56:
                cf.br ^bb44
              ^bb43:
                cf.br ^bb44
              ^bb44:
              %258 = llvm.load %146 : !llvm.ptr -> i32
              %259 = arith.constant 0 : i32
              %260 = arith.cmpi sgt, %258, %259 : i32
              cf.cond_br %260, ^bb57, ^bb58
              ^bb57:
                %261 = llvm.load %146 : !llvm.ptr -> i32
                %262 = arith.sitofp %261 : i32 to f64
                %263 = arith.mulf %262, %166 : f64
                %264 = llvm.load %146 : !llvm.ptr -> i32
                %265 = arith.constant 1 : i32
                %266 = arith.subi %264, %265 : i32
                %267 = llvm.load %149 : !llvm.ptr -> i32
                %268 = llvm.load %86 : !llvm.ptr -> i32
                %269 = arith.constant 0 : i32
                %270 = arith.cmpi sgt, %268, %269 : i32
                cf.cond_br %270, ^bb60, ^bb61
                ^bb60:
                  %272 = arith.constant 1 : i32
                  %273 = arith.subi %268, %272 : i32
                  %271 = func.call @sidx(%266, %267, %273) : (i32, i32, i32) -> i32
                  %275 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %276 = arith.extsi %271 : i32 to i64
                  %277 = llvm.getelementptr %275[%276] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %274 = llvm.load %277 : !llvm.ptr -> f64
                  %278 = arith.mulf %143, %263 : f64
                  %279 = arith.sitofp %268 : i32 to f64
                  %280 = arith.mulf %279, %174 : f64
                  %281 = arith.mulf %278, %280 : f64
                  %282 = arith.addf %274, %281 : f64
                  %283 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %284 = arith.extsi %271 : i32 to i64
                  %285 = llvm.getelementptr %283[%284] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %282, %285 : f64, !llvm.ptr
                  cf.br ^bb62
                ^bb61:
                  cf.br ^bb62
                ^bb62:
                %286 = arith.constant 0 : i32
                %287 = arith.cmpi sgt, %266, %286 : i32
                cf.cond_br %287, ^bb63, ^bb64
                ^bb63:
                  %289 = arith.constant 1 : i32
                  %290 = arith.subi %266, %289 : i32
                  %288 = func.call @sidx(%290, %267, %268) : (i32, i32, i32) -> i32
                  %292 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %293 = arith.extsi %288 : i32 to i64
                  %294 = llvm.getelementptr %292[%293] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %291 = llvm.load %294 : !llvm.ptr -> f64
                  %295 = arith.mulf %143, %263 : f64
                  %296 = arith.sitofp %266 : i32 to f64
                  %297 = arith.mulf %296, %174 : f64
                  %298 = arith.mulf %295, %297 : f64
                  %299 = arith.addf %291, %298 : f64
                  %300 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %301 = arith.extsi %288 : i32 to i64
                  %302 = llvm.getelementptr %300[%301] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %299, %302 : f64, !llvm.ptr
                  cf.br ^bb65
                ^bb64:
                  cf.br ^bb65
                ^bb65:
                %303 = arith.constant 0 : i32
                %304 = arith.cmpi sgt, %267, %303 : i32
                cf.cond_br %304, ^bb66, ^bb67
                ^bb66:
                  %306 = arith.constant 1 : i32
                  %307 = arith.addi %266, %306 : i32
                  %308 = arith.constant 1 : i32
                  %309 = arith.subi %267, %308 : i32
                  %305 = func.call @sidx(%307, %309, %268) : (i32, i32, i32) -> i32
                  %311 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %312 = arith.extsi %305 : i32 to i64
                  %313 = llvm.getelementptr %311[%312] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %310 = llvm.load %313 : !llvm.ptr -> f64
                  %314 = arith.mulf %143, %263 : f64
                  %315 = arith.constant 2.0 : f32
                  %316 = arith.sitofp %267 : i32 to f64
                  %318 = arith.extf %315 : f32 to f64
                  %317 = arith.mulf %318, %316 : f64
                  %319 = arith.mulf %317, %174 : f64
                  %320 = arith.mulf %314, %319 : f64
                  %321 = arith.addf %310, %320 : f64
                  %322 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %323 = arith.extsi %305 : i32 to i64
                  %324 = llvm.getelementptr %322[%323] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %321, %324 : f64, !llvm.ptr
                  cf.br ^bb68
                ^bb67:
                  cf.br ^bb68
                ^bb68:
                %325 = arith.constant 0 : i32
                %326 = arith.cmpi sgt, %111, %325 : i32
                cf.cond_br %326, ^bb69, ^bb70
                ^bb69:
                  %327 = func.call @sidx(%266, %267, %268) : (i32, i32, i32) -> i32
                  %329 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %330 = arith.extsi %327 : i32 to i64
                  %331 = llvm.getelementptr %329[%330] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %328 = llvm.load %331 : !llvm.ptr -> f64
                  %332 = arith.mulf %143, %263 : f64
                  %333 = arith.sitofp %111 : i32 to f64
                  %334 = arith.mulf %333, %174 : f64
                  %335 = arith.mulf %332, %334 : f64
                  %336 = arith.addf %328, %335 : f64
                  %337 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %338 = arith.extsi %327 : i32 to i64
                  %339 = llvm.getelementptr %337[%338] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %336, %339 : f64, !llvm.ptr
                  cf.br ^bb71
                ^bb70:
                  cf.br ^bb71
                ^bb71:
                cf.br ^bb59
              ^bb58:
                cf.br ^bb59
              ^bb59:
              %340 = llvm.load %149 : !llvm.ptr -> i32
              %341 = arith.constant 0 : i32
              %342 = arith.cmpi sgt, %340, %341 : i32
              cf.cond_br %342, ^bb72, ^bb73
              ^bb72:
                %343 = arith.constant 2.0 : f32
                %344 = llvm.load %149 : !llvm.ptr -> i32
                %345 = arith.sitofp %344 : i32 to f64
                %347 = arith.extf %343 : f32 to f64
                %346 = arith.mulf %347, %345 : f64
                %348 = arith.mulf %346, %166 : f64
                %349 = llvm.load %146 : !llvm.ptr -> i32
                %350 = arith.constant 1 : i32
                %351 = arith.addi %349, %350 : i32
                %352 = llvm.load %149 : !llvm.ptr -> i32
                %353 = arith.constant 1 : i32
                %354 = arith.subi %352, %353 : i32
                %355 = llvm.load %86 : !llvm.ptr -> i32
                %356 = arith.constant 0 : i32
                %357 = arith.cmpi sgt, %355, %356 : i32
                cf.cond_br %357, ^bb75, ^bb76
                ^bb75:
                  %359 = arith.constant 1 : i32
                  %360 = arith.subi %355, %359 : i32
                  %358 = func.call @sidx(%351, %354, %360) : (i32, i32, i32) -> i32
                  %362 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %363 = arith.extsi %358 : i32 to i64
                  %364 = llvm.getelementptr %362[%363] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %361 = llvm.load %364 : !llvm.ptr -> f64
                  %365 = arith.mulf %143, %348 : f64
                  %366 = arith.sitofp %355 : i32 to f64
                  %367 = arith.mulf %366, %174 : f64
                  %368 = arith.mulf %365, %367 : f64
                  %369 = arith.addf %361, %368 : f64
                  %370 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %371 = arith.extsi %358 : i32 to i64
                  %372 = llvm.getelementptr %370[%371] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %369, %372 : f64, !llvm.ptr
                  cf.br ^bb77
                ^bb76:
                  cf.br ^bb77
                ^bb77:
                %373 = arith.constant 0 : i32
                %374 = arith.cmpi sgt, %351, %373 : i32
                cf.cond_br %374, ^bb78, ^bb79
                ^bb78:
                  %376 = arith.constant 1 : i32
                  %377 = arith.subi %351, %376 : i32
                  %375 = func.call @sidx(%377, %354, %355) : (i32, i32, i32) -> i32
                  %379 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %380 = arith.extsi %375 : i32 to i64
                  %381 = llvm.getelementptr %379[%380] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %378 = llvm.load %381 : !llvm.ptr -> f64
                  %382 = arith.mulf %143, %348 : f64
                  %383 = arith.sitofp %351 : i32 to f64
                  %384 = arith.mulf %383, %174 : f64
                  %385 = arith.mulf %382, %384 : f64
                  %386 = arith.addf %378, %385 : f64
                  %387 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %388 = arith.extsi %375 : i32 to i64
                  %389 = llvm.getelementptr %387[%388] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %386, %389 : f64, !llvm.ptr
                  cf.br ^bb80
                ^bb79:
                  cf.br ^bb80
                ^bb80:
                %390 = arith.constant 0 : i32
                %391 = arith.cmpi sgt, %354, %390 : i32
                cf.cond_br %391, ^bb81, ^bb82
                ^bb81:
                  %393 = arith.constant 1 : i32
                  %394 = arith.addi %351, %393 : i32
                  %395 = arith.constant 1 : i32
                  %396 = arith.subi %354, %395 : i32
                  %392 = func.call @sidx(%394, %396, %355) : (i32, i32, i32) -> i32
                  %398 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %399 = arith.extsi %392 : i32 to i64
                  %400 = llvm.getelementptr %398[%399] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %397 = llvm.load %400 : !llvm.ptr -> f64
                  %401 = arith.mulf %143, %348 : f64
                  %402 = arith.constant 2.0 : f32
                  %403 = arith.sitofp %354 : i32 to f64
                  %405 = arith.extf %402 : f32 to f64
                  %404 = arith.mulf %405, %403 : f64
                  %406 = arith.mulf %404, %174 : f64
                  %407 = arith.mulf %401, %406 : f64
                  %408 = arith.addf %397, %407 : f64
                  %409 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %410 = arith.extsi %392 : i32 to i64
                  %411 = llvm.getelementptr %409[%410] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %408, %411 : f64, !llvm.ptr
                  cf.br ^bb83
                ^bb82:
                  cf.br ^bb83
                ^bb83:
                %412 = arith.constant 0 : i32
                %413 = arith.cmpi sgt, %111, %412 : i32
                cf.cond_br %413, ^bb84, ^bb85
                ^bb84:
                  %414 = func.call @sidx(%351, %354, %355) : (i32, i32, i32) -> i32
                  %416 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %417 = arith.extsi %414 : i32 to i64
                  %418 = llvm.getelementptr %416[%417] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %415 = llvm.load %418 : !llvm.ptr -> f64
                  %419 = arith.mulf %143, %348 : f64
                  %420 = arith.sitofp %111 : i32 to f64
                  %421 = arith.mulf %420, %174 : f64
                  %422 = arith.mulf %419, %421 : f64
                  %423 = arith.addf %415, %422 : f64
                  %424 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %425 = arith.extsi %414 : i32 to i64
                  %426 = llvm.getelementptr %424[%425] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %423, %426 : f64, !llvm.ptr
                  cf.br ^bb86
                ^bb85:
                  cf.br ^bb86
                ^bb86:
                cf.br ^bb74
              ^bb73:
                cf.br ^bb74
              ^bb74:
              %427 = arith.constant 0 : i32
              %428 = arith.cmpi sgt, %111, %427 : i32
              cf.cond_br %428, ^bb87, ^bb88
              ^bb87:
                %429 = arith.sitofp %111 : i32 to f64
                %430 = arith.mulf %429, %166 : f64
                %431 = llvm.load %146 : !llvm.ptr -> i32
                %432 = llvm.load %149 : !llvm.ptr -> i32
                %433 = llvm.load %86 : !llvm.ptr -> i32
                %434 = arith.constant 1 : i32
                %435 = arith.subi %111, %434 : i32
                %436 = arith.constant 0 : i32
                %437 = arith.cmpi sgt, %433, %436 : i32
                cf.cond_br %437, ^bb90, ^bb91
                ^bb90:
                  %439 = arith.constant 1 : i32
                  %440 = arith.subi %433, %439 : i32
                  %438 = func.call @sidx(%431, %432, %440) : (i32, i32, i32) -> i32
                  %442 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %443 = arith.extsi %438 : i32 to i64
                  %444 = llvm.getelementptr %442[%443] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %441 = llvm.load %444 : !llvm.ptr -> f64
                  %445 = arith.mulf %143, %430 : f64
                  %446 = arith.sitofp %433 : i32 to f64
                  %447 = arith.mulf %446, %174 : f64
                  %448 = arith.mulf %445, %447 : f64
                  %449 = arith.addf %441, %448 : f64
                  %450 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %451 = arith.extsi %438 : i32 to i64
                  %452 = llvm.getelementptr %450[%451] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %449, %452 : f64, !llvm.ptr
                  cf.br ^bb92
                ^bb91:
                  cf.br ^bb92
                ^bb92:
                %453 = arith.constant 0 : i32
                %454 = arith.cmpi sgt, %431, %453 : i32
                cf.cond_br %454, ^bb93, ^bb94
                ^bb93:
                  %456 = arith.constant 1 : i32
                  %457 = arith.subi %431, %456 : i32
                  %455 = func.call @sidx(%457, %432, %433) : (i32, i32, i32) -> i32
                  %459 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %460 = arith.extsi %455 : i32 to i64
                  %461 = llvm.getelementptr %459[%460] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %458 = llvm.load %461 : !llvm.ptr -> f64
                  %462 = arith.mulf %143, %430 : f64
                  %463 = arith.sitofp %431 : i32 to f64
                  %464 = arith.mulf %463, %174 : f64
                  %465 = arith.mulf %462, %464 : f64
                  %466 = arith.addf %458, %465 : f64
                  %467 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %468 = arith.extsi %455 : i32 to i64
                  %469 = llvm.getelementptr %467[%468] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %466, %469 : f64, !llvm.ptr
                  cf.br ^bb95
                ^bb94:
                  cf.br ^bb95
                ^bb95:
                %470 = arith.constant 0 : i32
                %471 = arith.cmpi sgt, %432, %470 : i32
                cf.cond_br %471, ^bb96, ^bb97
                ^bb96:
                  %473 = arith.constant 1 : i32
                  %474 = arith.addi %431, %473 : i32
                  %475 = arith.constant 1 : i32
                  %476 = arith.subi %432, %475 : i32
                  %472 = func.call @sidx(%474, %476, %433) : (i32, i32, i32) -> i32
                  %478 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %479 = arith.extsi %472 : i32 to i64
                  %480 = llvm.getelementptr %478[%479] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %477 = llvm.load %480 : !llvm.ptr -> f64
                  %481 = arith.mulf %143, %430 : f64
                  %482 = arith.constant 2.0 : f32
                  %483 = arith.sitofp %432 : i32 to f64
                  %485 = arith.extf %482 : f32 to f64
                  %484 = arith.mulf %485, %483 : f64
                  %486 = arith.mulf %484, %174 : f64
                  %487 = arith.mulf %481, %486 : f64
                  %488 = arith.addf %477, %487 : f64
                  %489 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %490 = arith.extsi %472 : i32 to i64
                  %491 = llvm.getelementptr %489[%490] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %488, %491 : f64, !llvm.ptr
                  cf.br ^bb98
                ^bb97:
                  cf.br ^bb98
                ^bb98:
                %492 = arith.constant 0 : i32
                %493 = arith.cmpi sgt, %435, %492 : i32
                cf.cond_br %493, ^bb99, ^bb100
                ^bb99:
                  %494 = func.call @sidx(%431, %432, %433) : (i32, i32, i32) -> i32
                  %496 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %497 = arith.extsi %494 : i32 to i64
                  %498 = llvm.getelementptr %496[%497] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  %495 = llvm.load %498 : !llvm.ptr -> f64
                  %499 = arith.mulf %143, %430 : f64
                  %500 = arith.sitofp %435 : i32 to f64
                  %501 = arith.mulf %500, %174 : f64
                  %502 = arith.mulf %499, %501 : f64
                  %503 = arith.addf %495, %502 : f64
                  %504 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
                  %505 = arith.extsi %494 : i32 to i64
                  %506 = llvm.getelementptr %504[%505] : (!llvm.ptr, i64) -> !llvm.ptr, f64
                  llvm.store %503, %506 : f64, !llvm.ptr
                  cf.br ^bb101
                ^bb100:
                  cf.br ^bb101
                ^bb101:
                cf.br ^bb89
              ^bb88:
                cf.br ^bb89
              ^bb89:
              %507 = llvm.load %119 : !llvm.ptr -> i32
              %508 = arith.constant 1 : i32
              %509 = arith.addi %507, %508 : i32
              llvm.store %509, %119 : i32, !llvm.ptr
              cf.br ^bb24
            ^bb26:
            %510 = llvm.load %86 : !llvm.ptr -> i32
            %511 = arith.constant 1 : i32
            %512 = arith.addi %510, %511 : i32
            llvm.store %512, %86 : i32, !llvm.ptr
            cf.br ^bb15
          ^bb17:
          %513 = llvm.load %75 : !llvm.ptr -> i32
          %514 = arith.constant 1 : i32
          %515 = arith.addi %513, %514 : i32
          llvm.store %515, %75 : i32, !llvm.ptr
          cf.br ^bb12
        ^bb14:
        %516 = llvm.load %70 : !llvm.ptr -> i32
        %517 = arith.constant 1 : i32
        %518 = arith.addi %516, %517 : i32
        llvm.store %518, %70 : i32, !llvm.ptr
        cf.br ^bb9
      ^bb11:
      %519 = llvm.load %23 : !llvm.ptr -> !llvm.ptr
      %520 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
      llvm.store %520, %23 : !llvm.ptr, !llvm.ptr
      llvm.store %519, %31 : !llvm.ptr, !llvm.ptr
      %521 = llvm.load %44 : !llvm.ptr -> i32
      %522 = arith.constant 1 : i32
      %523 = arith.addi %521, %522 : i32
      llvm.store %523, %44 : i32, !llvm.ptr
      cf.br ^bb6
    ^bb8:
    %524 = arith.constant 0.0 : f32
    %525 = arith.extf %524 : f32 to f64
    %526 = llvm.mlir.constant(1 : i64) : i64
    %527 = llvm.alloca %526 x f64 : (i64) -> !llvm.ptr
    llvm.store %525, %527 : f64, !llvm.ptr
    %528 = arith.constant 0 : i32
    %529 = llvm.mlir.constant(1 : i64) : i64
    %530 = llvm.alloca %529 x i32 : (i64) -> !llvm.ptr
    llvm.store %528, %530 : i32, !llvm.ptr
    cf.br ^bb102
    ^bb102:
    %531 = llvm.load %530 : !llvm.ptr -> i32
    %532 = llvm.mlir.addressof @STATE_SIZE : !llvm.ptr
    %533 = llvm.load %532 : !llvm.ptr -> i32
    %534 = arith.cmpi slt, %531, %533 : i32
    cf.cond_br %534, ^bb103, ^bb104
    ^bb103:
      %535 = llvm.load %530 : !llvm.ptr -> i32
      %536 = llvm.mlir.addressof @MAXK : !llvm.ptr
      %537 = llvm.load %536 : !llvm.ptr -> i32
      %538 = arith.remsi %535, %537 : i32
      %539 = arith.constant 0 : i32
      %540 = arith.cmpi sgt, %538, %539 : i32
      cf.cond_br %540, ^bb105, ^bb106
      ^bb105:
        %541 = llvm.load %527 : !llvm.ptr -> f64
        %543 = llvm.load %23 : !llvm.ptr -> !llvm.ptr
        %544 = llvm.load %530 : !llvm.ptr -> i32
        %545 = arith.extsi %544 : i32 to i64
        %546 = llvm.getelementptr %543[%545] : (!llvm.ptr, i64) -> !llvm.ptr, f64
        %542 = llvm.load %546 : !llvm.ptr -> f64
        %547 = arith.addf %541, %542 : f64
        llvm.store %547, %527 : f64, !llvm.ptr
        cf.br ^bb107
      ^bb106:
        cf.br ^bb107
      ^bb107:
      %548 = llvm.load %530 : !llvm.ptr -> i32
      %549 = arith.constant 1 : i32
      %550 = arith.addi %548, %549 : i32
      llvm.store %550, %530 : i32, !llvm.ptr
      cf.br ^bb102
    ^bb104:
    %552 = llvm.load %23 : !llvm.ptr -> !llvm.ptr
    func.call @free(%552) : (!llvm.ptr) -> ()
    %554 = llvm.load %31 : !llvm.ptr -> !llvm.ptr
    func.call @free(%554) : (!llvm.ptr) -> ()
    %555 = llvm.load %527 : !llvm.ptr -> f64
    func.return %555 : f64
  }
  func.func @main() -> i32 {
    %556 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %558 = arith.constant 100 : i32
    %557 = func.call @q(%558) : (i32) -> f64
    %559 = llvm.call @printf(%556, %557) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, f64) -> i32
    %560 = arith.constant 0 : i32
    func.return %560 : i32
  }
}