Problem 849

The Tournament — F(100) mod 10^9+7. DP over tournament steps with a sliding-window prefix sum. State is (height, displacement) tracked in flat arrays.

Answer936203459
Output936203459
StatusPASS
Native helperno
Runtime430 ms
Peak memory311648 KB
Time complexityO(n^2) (estimated)
Space complexityO(n) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^2)O(n log n)
Space complexityO(n)O(n)
ApproachFlow solutionModular DP or matrix exponentiation
VerdictSuboptimal

Flow source

# Project Euler 849
# The Tournament — F(100) mod 10^9+7.
#
# DP over tournament steps with a sliding-window prefix sum.
# State is (height, displacement) tracked in flat arrays.

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

const MOD: i64 = 1000000007

function main() -> i32 {
    let n: i32 = 100
    let vmax: i32 = 2 * (n - 1)
    let off: i32 = vmax
    let v: i32 = 2 * vmax + 1

    let maxh: ptr<i32> = malloc(((n + 1) as i64) * 4)
    let mut i: i32 = 0
    while i <= n {
        maxh[i] = 2 * i * (n - i)
        i = i + 1
    }

    let mh: i32 = maxh[1]
    let mut dp: ptr<i64> = calloc(((mh + 1) as i64) * ((v as i64)), 8)

    let mut d: i32 = 0
    while d <= vmax {
        dp[((d as i64) * (v as i64)) + ((d + off) as i64)] = 1
        d = d + 1
    }

    let mut step: i32 = 1
    while step < n {
        let mh_cur: i32 = maxh[step]
        let mh_next: i32 = maxh[step + 1]
        let nxt: ptr<i64> = calloc(((mh_next + 1) as i64) * ((v as i64)), 8)

        let mut h: i32 = 0
        while h <= mh_cur {
            let row_base: i64 = (h as i64) * (v as i64)
            let mut cum: i64 = 0
            let base: i32 = h - off - 4
            let mut vi_start: i32 = -base
            if vi_start < 4 {
                vi_start = 4
            }
            if vi_start > v {
                vi_start = v
            }
            let mut vi_end: i32 = mh_next - base
            if vi_end > v - 1 {
                vi_end = v - 1
            }

            let mut vi: i32 = 0
            while vi < vi_start {
                cum = cum + dp[row_base + (vi as i64)]
                if cum >= MOD {
                    cum = cum - MOD
                }
                vi = vi + 1
            }

            if vi_start <= vi_end {
                vi = vi_start
                while vi <= vi_end {
                    cum = cum + dp[row_base + (vi as i64)]
                    if cum >= MOD {
                        cum = cum - MOD
                    }
                    let h2: i32 = base + vi
                    let idx2: i32 = vi - 4
                    let val: i64 = nxt[((h2 as i64) * (v as i64)) + (idx2 as i64)] + cum
                    let mut val2: i64 = val
                    if val2 >= MOD {
                        val2 = val2 - MOD
                    }
                    nxt[((h2 as i64) * (v as i64)) + (idx2 as i64)] = val2
                    vi = vi + 1
                }
                vi = vi_end + 1
                while vi < v {
                    cum = cum + dp[row_base + (vi as i64)]
                    if cum >= MOD {
                        cum = cum - MOD
                    }
                    vi = vi + 1
                }
            }
            else {
                vi = vi_start
                while vi < v {
                    cum = cum + dp[row_base + (vi as i64)]
                    if cum >= MOD {
                        cum = cum - MOD
                    }
                    vi = vi + 1
                }
            }

            let total: i64 = cum
            if total != 0 {
                let base_h: i32 = h - off
                vi = v - 4
                while vi < v {
                    let h2: i32 = base_h + vi
                    if 0 <= h2 && h2 <= mh_next {
                        let val: i64 = nxt[((h2 as i64) * (v as i64)) + (vi as i64)] + total
                        let mut val2: i64 = val
                        if val2 >= MOD {
                            val2 = val2 - MOD
                        }
                        nxt[((h2 as i64) * (v as i64)) + (vi as i64)] = val2
                    }
                    vi = vi + 1
                }
            }

            h = h + 1
        }

        free(dp)
        dp = nxt
        step = step + 1
    }

    let mut ans: i64 = 0
    let mut vi: i32 = 0
    while vi < v {
        ans = ans + dp[(vi as i64)]
        if ans >= MOD {
            ans = ans - MOD
        }
        vi = vi + 1
    }

    free(dp)
    free(maxh)
    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; }

int32_t main(void);

static const int64_t MOD = 1000000007;




int32_t main(void) {
    int32_t n = 100;
    int32_t vmax = (2 * (n - 1));
    int32_t off = vmax;
    int32_t v = ((2 * vmax) + 1);
    int32_t* maxh = (int32_t*)(malloc((((int64_t)((n + 1))) * 4)));
    int32_t i = 0;
    while (i <= n) {
        maxh[i] = ((2 * i) * (n - i));
        i = (i + 1);
    }
    int32_t mh = maxh[1];
    int64_t* dp = (int64_t*)(calloc((((int64_t)((mh + 1))) * ((int64_t)(v))), 8));
    int32_t d = 0;
    while (d <= vmax) {
        dp[((((int64_t)(d)) * ((int64_t)(v))) + ((int64_t)((d + off))))] = 1;
        d = (d + 1);
    }
    int32_t step = 1;
    while (step < n) {
        int32_t mh_cur = maxh[step];
        int32_t mh_next = maxh[(step + 1)];
        int64_t* nxt = (int64_t*)(calloc((((int64_t)((mh_next + 1))) * ((int64_t)(v))), 8));
        int32_t h = 0;
        while (h <= mh_cur) {
            int64_t row_base = (((int64_t)(h)) * ((int64_t)(v)));
            int64_t cum = 0;
            int32_t base = ((h - off) - 4);
            int32_t vi_start = (-base);
            if (vi_start < 4) {
                vi_start = 4;
            }
            if (vi_start > v) {
                vi_start = v;
            }
            int32_t vi_end = (mh_next - base);
            if (vi_end > (v - 1)) {
                vi_end = (v - 1);
            }
            int32_t vi = 0;
            while (vi < vi_start) {
                cum = (cum + dp[(row_base + ((int64_t)(vi)))]);
                if (cum >= MOD) {
                    cum = (cum - MOD);
                }
                vi = (vi + 1);
            }
            if (vi_start <= vi_end) {
                vi = vi_start;
                while (vi <= vi_end) {
                    cum = (cum + dp[(row_base + ((int64_t)(vi)))]);
                    if (cum >= MOD) {
                        cum = (cum - MOD);
                    }
                    int32_t h2 = (base + vi);
                    int32_t idx2 = (vi - 4);
                    int64_t val = (nxt[((((int64_t)(h2)) * ((int64_t)(v))) + ((int64_t)(idx2)))] + cum);
                    int64_t val2 = val;
                    if (val2 >= MOD) {
                        val2 = (val2 - MOD);
                    }
                    nxt[((((int64_t)(h2)) * ((int64_t)(v))) + ((int64_t)(idx2)))] = val2;
                    vi = (vi + 1);
                }
                vi = (vi_end + 1);
                while (vi < v) {
                    cum = (cum + dp[(row_base + ((int64_t)(vi)))]);
                    if (cum >= MOD) {
                        cum = (cum - MOD);
                    }
                    vi = (vi + 1);
                }
            } else {
                vi = vi_start;
                while (vi < v) {
                    cum = (cum + dp[(row_base + ((int64_t)(vi)))]);
                    if (cum >= MOD) {
                        cum = (cum - MOD);
                    }
                    vi = (vi + 1);
                }
            }
            int64_t total = cum;
            if (total != 0) {
                int32_t base_h = (h - off);
                vi = (v - 4);
                while (vi < v) {
                    int32_t h2 = (base_h + vi);
                    if ((0 <= h2 && h2 <= mh_next)) {
                        int64_t val = (nxt[((((int64_t)(h2)) * ((int64_t)(v))) + ((int64_t)(vi)))] + total);
                        int64_t val2 = val;
                        if (val2 >= MOD) {
                            val2 = (val2 - MOD);
                        }
                        nxt[((((int64_t)(h2)) * ((int64_t)(v))) + ((int64_t)(vi)))] = val2;
                    }
                    vi = (vi + 1);
                }
            }
            h = (h + 1);
        }
        free(dp);
        dp = nxt;
        step = (step + 1);
    }
    int64_t ans = 0;
    int32_t vi = 0;
    while (vi < v) {
        ans = (ans + dp[((int64_t)(vi))]);
        if (ans >= MOD) {
            ans = (ans - MOD);
        }
        vi = (vi + 1);
    }
    free(dp);
    free(maxh);
    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 @malloc(i64) -> !llvm.ptr
  // Constant: MOD
  llvm.mlir.global internal constant @MOD(1000000007 : i64) : i64
  func.func @main() -> i32 {
    %0 = arith.constant 100 : i32
    %1 = arith.constant 2 : i32
    %2 = arith.constant 1 : i32
    %3 = arith.subi %0, %2 : i32
    %4 = arith.muli %1, %3 : i32
    %5 = arith.constant 2 : i32
    %6 = arith.muli %5, %4 : i32
    %7 = arith.constant 1 : i32
    %8 = arith.addi %6, %7 : i32
    %10 = arith.constant 1 : i32
    %11 = arith.addi %0, %10 : i32
    %12 = arith.extsi %11 : i32 to i64
    %13 = arith.constant 4 : i32
    %15 = arith.extsi %13 : i32 to i64
    %14 = arith.muli %12, %15 : i64
    %9 = func.call @malloc(%14) : (i64) -> !llvm.ptr
    %16 = arith.constant 0 : i32
    %17 = llvm.mlir.constant(1 : i64) : i64
    %18 = llvm.alloca %17 x i32 : (i64) -> !llvm.ptr
    llvm.store %16, %18 : i32, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %19 = llvm.load %18 : !llvm.ptr -> i32
    %20 = arith.cmpi sle, %19, %0 : i32
    cf.cond_br %20, ^bb1, ^bb2
    ^bb1:
      %21 = arith.constant 2 : i32
      %22 = llvm.load %18 : !llvm.ptr -> i32
      %23 = arith.muli %21, %22 : i32
      %24 = llvm.load %18 : !llvm.ptr -> i32
      %25 = arith.subi %0, %24 : i32
      %26 = arith.muli %23, %25 : i32
      %27 = llvm.load %18 : !llvm.ptr -> i32
      %28 = arith.extsi %27 : i32 to i64
      %29 = llvm.getelementptr %9[%28] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %26, %29 : i32, !llvm.ptr
      %30 = llvm.load %18 : !llvm.ptr -> i32
      %31 = arith.constant 1 : i32
      %32 = arith.addi %30, %31 : i32
      llvm.store %32, %18 : i32, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %34 = arith.constant 1 : i32
    %35 = arith.extsi %34 : i32 to i64
    %36 = llvm.getelementptr %9[%35] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %33 = llvm.load %36 : !llvm.ptr -> i32
    %38 = arith.constant 1 : i32
    %39 = arith.addi %33, %38 : i32
    %40 = arith.extsi %39 : i32 to i64
    %41 = arith.extsi %8 : i32 to i64
    %42 = arith.muli %40, %41 : i64
    %43 = arith.constant 8 : i32
    %44 = arith.extsi %43 : i32 to i64
    %37 = func.call @calloc(%42, %44) : (i64, i64) -> !llvm.ptr
    %45 = llvm.mlir.constant(1 : i64) : i64
    %46 = llvm.alloca %45 x !llvm.ptr : (i64) -> !llvm.ptr
    llvm.store %37, %46 : !llvm.ptr, !llvm.ptr
    %47 = arith.constant 0 : i32
    %48 = llvm.mlir.constant(1 : i64) : i64
    %49 = llvm.alloca %48 x i32 : (i64) -> !llvm.ptr
    llvm.store %47, %49 : i32, !llvm.ptr
    cf.br ^bb3
    ^bb3:
    %50 = llvm.load %49 : !llvm.ptr -> i32
    %51 = arith.cmpi sle, %50, %4 : i32
    cf.cond_br %51, ^bb4, ^bb5
    ^bb4:
      %52 = arith.constant 1 : i32
      %53 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
      %54 = llvm.load %49 : !llvm.ptr -> i32
      %55 = arith.extsi %54 : i32 to i64
      %56 = arith.extsi %8 : i32 to i64
      %57 = arith.muli %55, %56 : i64
      %58 = llvm.load %49 : !llvm.ptr -> i32
      %59 = arith.addi %58, %4 : i32
      %60 = arith.extsi %59 : i32 to i64
      %61 = arith.addi %57, %60 : i64
      %62 = arith.extsi %52 : i32 to i64
      %63 = llvm.getelementptr %53[%61] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      llvm.store %62, %63 : i64, !llvm.ptr
      %64 = llvm.load %49 : !llvm.ptr -> i32
      %65 = arith.constant 1 : i32
      %66 = arith.addi %64, %65 : i32
      llvm.store %66, %49 : i32, !llvm.ptr
      cf.br ^bb3
    ^bb5:
    %67 = arith.constant 1 : i32
    %68 = llvm.mlir.constant(1 : i64) : i64
    %69 = llvm.alloca %68 x i32 : (i64) -> !llvm.ptr
    llvm.store %67, %69 : i32, !llvm.ptr
    cf.br ^bb6
    ^bb6:
    %70 = llvm.load %69 : !llvm.ptr -> i32
    %71 = arith.cmpi slt, %70, %0 : i32
    cf.cond_br %71, ^bb7, ^bb8
    ^bb7:
      %73 = llvm.load %69 : !llvm.ptr -> i32
      %74 = arith.extsi %73 : i32 to i64
      %75 = llvm.getelementptr %9[%74] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %72 = llvm.load %75 : !llvm.ptr -> i32
      %77 = llvm.load %69 : !llvm.ptr -> i32
      %78 = arith.constant 1 : i32
      %79 = arith.addi %77, %78 : i32
      %80 = arith.extsi %79 : i32 to i64
      %81 = llvm.getelementptr %9[%80] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %76 = llvm.load %81 : !llvm.ptr -> i32
      %83 = arith.constant 1 : i32
      %84 = arith.addi %76, %83 : i32
      %85 = arith.extsi %84 : i32 to i64
      %86 = arith.extsi %8 : i32 to i64
      %87 = arith.muli %85, %86 : i64
      %88 = arith.constant 8 : i32
      %89 = arith.extsi %88 : i32 to i64
      %82 = func.call @calloc(%87, %89) : (i64, i64) -> !llvm.ptr
      %90 = arith.constant 0 : i32
      %91 = llvm.mlir.constant(1 : i64) : i64
      %92 = llvm.alloca %91 x i32 : (i64) -> !llvm.ptr
      llvm.store %90, %92 : i32, !llvm.ptr
      cf.br ^bb9
      ^bb9:
      %93 = llvm.load %92 : !llvm.ptr -> i32
      %94 = arith.cmpi sle, %93, %72 : i32
      cf.cond_br %94, ^bb10, ^bb11
      ^bb10:
        %95 = llvm.load %92 : !llvm.ptr -> i32
        %96 = arith.extsi %95 : i32 to i64
        %97 = arith.extsi %8 : i32 to i64
        %98 = arith.muli %96, %97 : i64
        %99 = arith.constant 0 : i32
        %100 = arith.extsi %99 : i32 to i64
        %101 = llvm.mlir.constant(1 : i64) : i64
        %102 = llvm.alloca %101 x i64 : (i64) -> !llvm.ptr
        llvm.store %100, %102 : i64, !llvm.ptr
        %103 = llvm.load %92 : !llvm.ptr -> i32
        %104 = arith.subi %103, %4 : i32
        %105 = arith.constant 4 : i32
        %106 = arith.subi %104, %105 : i32
        %108 = arith.constant 0 : i32
        %107 = arith.subi %108, %106 : i32
        %109 = llvm.mlir.constant(1 : i64) : i64
        %110 = llvm.alloca %109 x i32 : (i64) -> !llvm.ptr
        llvm.store %107, %110 : i32, !llvm.ptr
        %111 = llvm.load %110 : !llvm.ptr -> i32
        %112 = arith.constant 4 : i32
        %113 = arith.cmpi slt, %111, %112 : i32
        cf.cond_br %113, ^bb12, ^bb13
        ^bb12:
          %114 = arith.constant 4 : i32
          llvm.store %114, %110 : i32, !llvm.ptr
          cf.br ^bb14
        ^bb13:
          cf.br ^bb14
        ^bb14:
        %115 = llvm.load %110 : !llvm.ptr -> i32
        %116 = arith.cmpi sgt, %115, %8 : i32
        cf.cond_br %116, ^bb15, ^bb16
        ^bb15:
          llvm.store %8, %110 : i32, !llvm.ptr
          cf.br ^bb17
        ^bb16:
          cf.br ^bb17
        ^bb17:
        %117 = arith.subi %76, %106 : i32
        %118 = llvm.mlir.constant(1 : i64) : i64
        %119 = llvm.alloca %118 x i32 : (i64) -> !llvm.ptr
        llvm.store %117, %119 : i32, !llvm.ptr
        %120 = llvm.load %119 : !llvm.ptr -> i32
        %121 = arith.constant 1 : i32
        %122 = arith.subi %8, %121 : i32
        %123 = arith.cmpi sgt, %120, %122 : i32
        cf.cond_br %123, ^bb18, ^bb19
        ^bb18:
          %124 = arith.constant 1 : i32
          %125 = arith.subi %8, %124 : i32
          llvm.store %125, %119 : i32, !llvm.ptr
          cf.br ^bb20
        ^bb19:
          cf.br ^bb20
        ^bb20:
        %126 = arith.constant 0 : i32
        %127 = llvm.mlir.constant(1 : i64) : i64
        %128 = llvm.alloca %127 x i32 : (i64) -> !llvm.ptr
        llvm.store %126, %128 : i32, !llvm.ptr
        cf.br ^bb21
        ^bb21:
        %129 = llvm.load %128 : !llvm.ptr -> i32
        %130 = llvm.load %110 : !llvm.ptr -> i32
        %131 = arith.cmpi slt, %129, %130 : i32
        cf.cond_br %131, ^bb22, ^bb23
        ^bb22:
          %132 = llvm.load %102 : !llvm.ptr -> i64
          %134 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
          %135 = llvm.load %128 : !llvm.ptr -> i32
          %136 = arith.extsi %135 : i32 to i64
          %137 = arith.addi %98, %136 : i64
          %138 = llvm.getelementptr %134[%137] : (!llvm.ptr, i64) -> !llvm.ptr, i64
          %133 = llvm.load %138 : !llvm.ptr -> i64
          %139 = arith.addi %132, %133 : i64
          llvm.store %139, %102 : i64, !llvm.ptr
          %140 = llvm.load %102 : !llvm.ptr -> i64
          %141 = llvm.mlir.addressof @MOD : !llvm.ptr
          %142 = llvm.load %141 : !llvm.ptr -> i64
          %143 = arith.cmpi sge, %140, %142 : i64
          cf.cond_br %143, ^bb24, ^bb25
          ^bb24:
            %144 = llvm.load %102 : !llvm.ptr -> i64
            %145 = llvm.mlir.addressof @MOD : !llvm.ptr
            %146 = llvm.load %145 : !llvm.ptr -> i64
            %147 = arith.subi %144, %146 : i64
            llvm.store %147, %102 : i64, !llvm.ptr
            cf.br ^bb26
          ^bb25:
            cf.br ^bb26
          ^bb26:
          %148 = llvm.load %128 : !llvm.ptr -> i32
          %149 = arith.constant 1 : i32
          %150 = arith.addi %148, %149 : i32
          llvm.store %150, %128 : i32, !llvm.ptr
          cf.br ^bb21
        ^bb23:
        %151 = llvm.load %110 : !llvm.ptr -> i32
        %152 = llvm.load %119 : !llvm.ptr -> i32
        %153 = arith.cmpi sle, %151, %152 : i32
        cf.cond_br %153, ^bb27, ^bb28
        ^bb27:
          %154 = llvm.load %110 : !llvm.ptr -> i32
          llvm.store %154, %128 : i32, !llvm.ptr
          cf.br ^bb30
          ^bb30:
          %155 = llvm.load %128 : !llvm.ptr -> i32
          %156 = llvm.load %119 : !llvm.ptr -> i32
          %157 = arith.cmpi sle, %155, %156 : i32
          cf.cond_br %157, ^bb31, ^bb32
          ^bb31:
            %158 = llvm.load %102 : !llvm.ptr -> i64
            %160 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
            %161 = llvm.load %128 : !llvm.ptr -> i32
            %162 = arith.extsi %161 : i32 to i64
            %163 = arith.addi %98, %162 : i64
            %164 = llvm.getelementptr %160[%163] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %159 = llvm.load %164 : !llvm.ptr -> i64
            %165 = arith.addi %158, %159 : i64
            llvm.store %165, %102 : i64, !llvm.ptr
            %166 = llvm.load %102 : !llvm.ptr -> i64
            %167 = llvm.mlir.addressof @MOD : !llvm.ptr
            %168 = llvm.load %167 : !llvm.ptr -> i64
            %169 = arith.cmpi sge, %166, %168 : i64
            cf.cond_br %169, ^bb33, ^bb34
            ^bb33:
              %170 = llvm.load %102 : !llvm.ptr -> i64
              %171 = llvm.mlir.addressof @MOD : !llvm.ptr
              %172 = llvm.load %171 : !llvm.ptr -> i64
              %173 = arith.subi %170, %172 : i64
              llvm.store %173, %102 : i64, !llvm.ptr
              cf.br ^bb35
            ^bb34:
              cf.br ^bb35
            ^bb35:
            %174 = llvm.load %128 : !llvm.ptr -> i32
            %175 = arith.addi %106, %174 : i32
            %176 = llvm.load %128 : !llvm.ptr -> i32
            %177 = arith.constant 4 : i32
            %178 = arith.subi %176, %177 : i32
            %180 = arith.extsi %175 : i32 to i64
            %181 = arith.extsi %8 : i32 to i64
            %182 = arith.muli %180, %181 : i64
            %183 = arith.extsi %178 : i32 to i64
            %184 = arith.addi %182, %183 : i64
            %185 = llvm.getelementptr %82[%184] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %179 = llvm.load %185 : !llvm.ptr -> i64
            %186 = llvm.load %102 : !llvm.ptr -> i64
            %187 = arith.addi %179, %186 : i64
            %188 = llvm.mlir.constant(1 : i64) : i64
            %189 = llvm.alloca %188 x i64 : (i64) -> !llvm.ptr
            llvm.store %187, %189 : i64, !llvm.ptr
            %190 = llvm.load %189 : !llvm.ptr -> i64
            %191 = llvm.mlir.addressof @MOD : !llvm.ptr
            %192 = llvm.load %191 : !llvm.ptr -> i64
            %193 = arith.cmpi sge, %190, %192 : i64
            cf.cond_br %193, ^bb36, ^bb37
            ^bb36:
              %194 = llvm.load %189 : !llvm.ptr -> i64
              %195 = llvm.mlir.addressof @MOD : !llvm.ptr
              %196 = llvm.load %195 : !llvm.ptr -> i64
              %197 = arith.subi %194, %196 : i64
              llvm.store %197, %189 : i64, !llvm.ptr
              cf.br ^bb38
            ^bb37:
              cf.br ^bb38
            ^bb38:
            %198 = llvm.load %189 : !llvm.ptr -> i64
            %199 = arith.extsi %175 : i32 to i64
            %200 = arith.extsi %8 : i32 to i64
            %201 = arith.muli %199, %200 : i64
            %202 = arith.extsi %178 : i32 to i64
            %203 = arith.addi %201, %202 : i64
            %204 = llvm.getelementptr %82[%203] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            llvm.store %198, %204 : i64, !llvm.ptr
            %205 = llvm.load %128 : !llvm.ptr -> i32
            %206 = arith.constant 1 : i32
            %207 = arith.addi %205, %206 : i32
            llvm.store %207, %128 : i32, !llvm.ptr
            cf.br ^bb30
          ^bb32:
          %208 = llvm.load %119 : !llvm.ptr -> i32
          %209 = arith.constant 1 : i32
          %210 = arith.addi %208, %209 : i32
          llvm.store %210, %128 : i32, !llvm.ptr
          cf.br ^bb39
          ^bb39:
          %211 = llvm.load %128 : !llvm.ptr -> i32
          %212 = arith.cmpi slt, %211, %8 : i32
          cf.cond_br %212, ^bb40, ^bb41
          ^bb40:
            %213 = llvm.load %102 : !llvm.ptr -> i64
            %215 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
            %216 = llvm.load %128 : !llvm.ptr -> i32
            %217 = arith.extsi %216 : i32 to i64
            %218 = arith.addi %98, %217 : i64
            %219 = llvm.getelementptr %215[%218] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %214 = llvm.load %219 : !llvm.ptr -> i64
            %220 = arith.addi %213, %214 : i64
            llvm.store %220, %102 : i64, !llvm.ptr
            %221 = llvm.load %102 : !llvm.ptr -> i64
            %222 = llvm.mlir.addressof @MOD : !llvm.ptr
            %223 = llvm.load %222 : !llvm.ptr -> i64
            %224 = arith.cmpi sge, %221, %223 : i64
            cf.cond_br %224, ^bb42, ^bb43
            ^bb42:
              %225 = llvm.load %102 : !llvm.ptr -> i64
              %226 = llvm.mlir.addressof @MOD : !llvm.ptr
              %227 = llvm.load %226 : !llvm.ptr -> i64
              %228 = arith.subi %225, %227 : i64
              llvm.store %228, %102 : i64, !llvm.ptr
              cf.br ^bb44
            ^bb43:
              cf.br ^bb44
            ^bb44:
            %229 = llvm.load %128 : !llvm.ptr -> i32
            %230 = arith.constant 1 : i32
            %231 = arith.addi %229, %230 : i32
            llvm.store %231, %128 : i32, !llvm.ptr
            cf.br ^bb39
          ^bb41:
          cf.br ^bb29
        ^bb28:
          %232 = llvm.load %110 : !llvm.ptr -> i32
          llvm.store %232, %128 : i32, !llvm.ptr
          cf.br ^bb45
          ^bb45:
          %233 = llvm.load %128 : !llvm.ptr -> i32
          %234 = arith.cmpi slt, %233, %8 : i32
          cf.cond_br %234, ^bb46, ^bb47
          ^bb46:
            %235 = llvm.load %102 : !llvm.ptr -> i64
            %237 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
            %238 = llvm.load %128 : !llvm.ptr -> i32
            %239 = arith.extsi %238 : i32 to i64
            %240 = arith.addi %98, %239 : i64
            %241 = llvm.getelementptr %237[%240] : (!llvm.ptr, i64) -> !llvm.ptr, i64
            %236 = llvm.load %241 : !llvm.ptr -> i64
            %242 = arith.addi %235, %236 : i64
            llvm.store %242, %102 : i64, !llvm.ptr
            %243 = llvm.load %102 : !llvm.ptr -> i64
            %244 = llvm.mlir.addressof @MOD : !llvm.ptr
            %245 = llvm.load %244 : !llvm.ptr -> i64
            %246 = arith.cmpi sge, %243, %245 : i64
            cf.cond_br %246, ^bb48, ^bb49
            ^bb48:
              %247 = llvm.load %102 : !llvm.ptr -> i64
              %248 = llvm.mlir.addressof @MOD : !llvm.ptr
              %249 = llvm.load %248 : !llvm.ptr -> i64
              %250 = arith.subi %247, %249 : i64
              llvm.store %250, %102 : i64, !llvm.ptr
              cf.br ^bb50
            ^bb49:
              cf.br ^bb50
            ^bb50:
            %251 = llvm.load %128 : !llvm.ptr -> i32
            %252 = arith.constant 1 : i32
            %253 = arith.addi %251, %252 : i32
            llvm.store %253, %128 : i32, !llvm.ptr
            cf.br ^bb45
          ^bb47:
          cf.br ^bb29
        ^bb29:
        %254 = llvm.load %102 : !llvm.ptr -> i64
        %255 = arith.constant 0 : i32
        %257 = arith.extsi %255 : i32 to i64
        %256 = arith.cmpi ne, %254, %257 : i64
        cf.cond_br %256, ^bb51, ^bb52
        ^bb51:
          %258 = llvm.load %92 : !llvm.ptr -> i32
          %259 = arith.subi %258, %4 : i32
          %260 = arith.constant 4 : i32
          %261 = arith.subi %8, %260 : i32
          llvm.store %261, %128 : i32, !llvm.ptr
          cf.br ^bb54
          ^bb54:
          %262 = llvm.load %128 : !llvm.ptr -> i32
          %263 = arith.cmpi slt, %262, %8 : i32
          cf.cond_br %263, ^bb55, ^bb56
          ^bb55:
            %264 = llvm.load %128 : !llvm.ptr -> i32
            %265 = arith.addi %259, %264 : i32
            %266 = arith.constant 0 : i32
            %267 = arith.cmpi sle, %266, %265 : i32
            %268 = scf.if %267 -> (i1) {
              %269 = arith.cmpi sle, %265, %76 : i32
              scf.yield %269 : i1
            } else {
              %270 = arith.constant false
              scf.yield %270 : i1
            }
            cf.cond_br %268, ^bb57, ^bb58
            ^bb57:
              %272 = arith.extsi %265 : i32 to i64
              %273 = arith.extsi %8 : i32 to i64
              %274 = arith.muli %272, %273 : i64
              %275 = llvm.load %128 : !llvm.ptr -> i32
              %276 = arith.extsi %275 : i32 to i64
              %277 = arith.addi %274, %276 : i64
              %278 = llvm.getelementptr %82[%277] : (!llvm.ptr, i64) -> !llvm.ptr, i64
              %271 = llvm.load %278 : !llvm.ptr -> i64
              %279 = arith.addi %271, %254 : i64
              %280 = llvm.mlir.constant(1 : i64) : i64
              %281 = llvm.alloca %280 x i64 : (i64) -> !llvm.ptr
              llvm.store %279, %281 : i64, !llvm.ptr
              %282 = llvm.load %281 : !llvm.ptr -> i64
              %283 = llvm.mlir.addressof @MOD : !llvm.ptr
              %284 = llvm.load %283 : !llvm.ptr -> i64
              %285 = arith.cmpi sge, %282, %284 : i64
              cf.cond_br %285, ^bb60, ^bb61
              ^bb60:
                %286 = llvm.load %281 : !llvm.ptr -> i64
                %287 = llvm.mlir.addressof @MOD : !llvm.ptr
                %288 = llvm.load %287 : !llvm.ptr -> i64
                %289 = arith.subi %286, %288 : i64
                llvm.store %289, %281 : i64, !llvm.ptr
                cf.br ^bb62
              ^bb61:
                cf.br ^bb62
              ^bb62:
              %290 = llvm.load %281 : !llvm.ptr -> i64
              %291 = arith.extsi %265 : i32 to i64
              %292 = arith.extsi %8 : i32 to i64
              %293 = arith.muli %291, %292 : i64
              %294 = llvm.load %128 : !llvm.ptr -> i32
              %295 = arith.extsi %294 : i32 to i64
              %296 = arith.addi %293, %295 : i64
              %297 = llvm.getelementptr %82[%296] : (!llvm.ptr, i64) -> !llvm.ptr, i64
              llvm.store %290, %297 : i64, !llvm.ptr
              cf.br ^bb59
            ^bb58:
              cf.br ^bb59
            ^bb59:
            %298 = llvm.load %128 : !llvm.ptr -> i32
            %299 = arith.constant 1 : i32
            %300 = arith.addi %298, %299 : i32
            llvm.store %300, %128 : i32, !llvm.ptr
            cf.br ^bb54
          ^bb56:
          cf.br ^bb53
        ^bb52:
          cf.br ^bb53
        ^bb53:
        %301 = llvm.load %92 : !llvm.ptr -> i32
        %302 = arith.constant 1 : i32
        %303 = arith.addi %301, %302 : i32
        llvm.store %303, %92 : i32, !llvm.ptr
        cf.br ^bb9
      ^bb11:
      %305 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
      func.call @free(%305) : (!llvm.ptr) -> ()
      llvm.store %82, %46 : !llvm.ptr, !llvm.ptr
      %306 = llvm.load %69 : !llvm.ptr -> i32
      %307 = arith.constant 1 : i32
      %308 = arith.addi %306, %307 : i32
      llvm.store %308, %69 : i32, !llvm.ptr
      cf.br ^bb6
    ^bb8:
    %309 = arith.constant 0 : i32
    %310 = arith.extsi %309 : i32 to i64
    %311 = llvm.mlir.constant(1 : i64) : i64
    %312 = llvm.alloca %311 x i64 : (i64) -> !llvm.ptr
    llvm.store %310, %312 : i64, !llvm.ptr
    %313 = arith.constant 0 : i32
    %314 = llvm.mlir.constant(1 : i64) : i64
    %315 = llvm.alloca %314 x i32 : (i64) -> !llvm.ptr
    llvm.store %313, %315 : i32, !llvm.ptr
    cf.br ^bb63
    ^bb63:
    %316 = llvm.load %315 : !llvm.ptr -> i32
    %317 = arith.cmpi slt, %316, %8 : i32
    cf.cond_br %317, ^bb64, ^bb65
    ^bb64:
      %318 = llvm.load %312 : !llvm.ptr -> i64
      %320 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
      %321 = llvm.load %315 : !llvm.ptr -> i32
      %322 = arith.extsi %321 : i32 to i64
      %323 = llvm.getelementptr %320[%322] : (!llvm.ptr, i64) -> !llvm.ptr, i64
      %319 = llvm.load %323 : !llvm.ptr -> i64
      %324 = arith.addi %318, %319 : i64
      llvm.store %324, %312 : i64, !llvm.ptr
      %325 = llvm.load %312 : !llvm.ptr -> i64
      %326 = llvm.mlir.addressof @MOD : !llvm.ptr
      %327 = llvm.load %326 : !llvm.ptr -> i64
      %328 = arith.cmpi sge, %325, %327 : i64
      cf.cond_br %328, ^bb66, ^bb67
      ^bb66:
        %329 = llvm.load %312 : !llvm.ptr -> i64
        %330 = llvm.mlir.addressof @MOD : !llvm.ptr
        %331 = llvm.load %330 : !llvm.ptr -> i64
        %332 = arith.subi %329, %331 : i64
        llvm.store %332, %312 : i64, !llvm.ptr
        cf.br ^bb68
      ^bb67:
        cf.br ^bb68
      ^bb68:
      %333 = llvm.load %315 : !llvm.ptr -> i32
      %334 = arith.constant 1 : i32
      %335 = arith.addi %333, %334 : i32
      llvm.store %335, %315 : i32, !llvm.ptr
      cf.br ^bb63
    ^bb65:
    %337 = llvm.load %46 : !llvm.ptr -> !llvm.ptr
    func.call @free(%337) : (!llvm.ptr) -> ()
    func.call @free(%9) : (!llvm.ptr) -> ()
    %339 = llvm.mlir.addressof @str_0 : !llvm.ptr
    %340 = llvm.load %312 : !llvm.ptr -> i64
    %341 = llvm.call @printf(%339, %340) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %342 = arith.constant 0 : i32
    func.return %342 : i32
  }
}