Problem 845

Prime Digit Sum - D(10^16), the 10^16-th number whose digit sum is prime.

Answer45009328011709400
Output45009328011709400
StatusPASS
Native helperno
Runtime0 ms
Peak memory1168 KB
Time complexityO(n^3) (estimated)
Space complexityO(n) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^3)O(n)
Space complexityO(n)O(n)
ApproachFlow solutionBig-integer arithmetic
VerdictSuboptimal

Flow source

# Project Euler 845
# Prime Digit Sum - D(10^16), the 10^16-th number whose digit sum is prime.

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

const MAXL: i64 = 25
const MAXS: i64 = 225

function main() -> i32 {
    # is_prime_arr: sieve up to MAXS
    let is_prime_arr: ptr<i32> = calloc(MAXS + 1, 4)
    if is_prime_arr == null { return 1 }
    # memset with 1 to set all to true
    memset(is_prime_arr, 1, (MAXS + 1) * 4)
    is_prime_arr[0] = 0
    is_prime_arr[1] = 0
    let mut p: i64 = 2
    while p * p <= MAXS {
        if is_prime_arr[p] != 0 {
            let mut j: i64 = p * p
            while j <= MAXS {
                is_prime_arr[j] = 0
                j = j + p
            }
        }
        p = p + 1
    }

    # counts[L][s] - use 2D via flat array: (MAXL+1)*(MAXS+1)
    let ncol: i64 = MAXS + 1
    let counts: ptr<i64> = calloc((MAXL + 1) * ncol, 8)
    if counts == null { return 1 }
    counts[0 * ncol + 0] = 1
    let mut L: i64 = 1
    while L <= MAXL {
        let mut s: i64 = 0
        while s <= 9 * L {
            let mut total: i64 = 0
            let mut d: i64 = 0
            while d <= 9 && d <= s {
                total = total + counts[(L - 1) * ncol + (s - d)]
                d = d + 1
            }
            counts[L * ncol + s] = total
            s = s + 1
        }
        L = L + 1
    }

    # count_len(length)
    let mut remaining: i64 = 10000000000000000
    let mut length: i64 = 1
    while length <= MAXL {
        # compute count_len(length)
        let mut cnt: i64 = 0
        if length <= 0 {
            cnt = 0
        } else {
            if length == 1 {
                let mut d: i64 = 1
                while d <= 9 {
                    if is_prime_arr[d] != 0 { cnt = cnt + 1 }
                    d = d + 1
                }
            } else {
                let rem: i64 = length - 1
                let mut first: i64 = 1
                while first <= 9 {
                    let mut ts: i64 = 0
                    while ts <= 9 * rem {
                        if is_prime_arr[first + ts] != 0 {
                            cnt = cnt + counts[rem * ncol + ts]
                        }
                        ts = ts + 1
                    }
                    first = first + 1
                }
            }
        }

        if remaining > cnt {
            remaining = remaining - cnt
        } else {
            # kth_len(length, remaining)
            let digits: ptr<i32> = calloc(MAXL, 4)
            if digits == null { return 1 }
            let mut prefix_sum: i32 = 0
            let mut pos: i64 = 0
            while pos < length {
                let rem: i64 = length - pos - 1
                let mut start: i32 = 0
                if pos == 0 { start = 1 } else { start = 0 }
                let mut d: i32 = start
                while d <= 9 {
                    let mut c: i64 = 0
                    let base: i32 = prefix_sum + d
                    let mut ts: i64 = 0
                    while ts <= 9 * rem {
                        if is_prime_arr[(base as i64) + ts] != 0 {
                            c = c + counts[rem * ncol + ts]
                        }
                        ts = ts + 1
                    }
                    if remaining > c {
                        remaining = remaining - c
                    } else {
                        digits[pos] = d
                        prefix_sum = prefix_sum + d
                        break
                    }
                    d = d + 1
                }
                pos = pos + 1
            }
            let mut ans: i64 = 0
            let mut i: i64 = 0
            while i < length {
                ans = ans * 10 + (digits[i] as i64)
                i = i + 1
            }
            printf("%lld\n", ans)
            free(digits)
            free(is_prime_arr)
            free(counts)
            return 0
        }
        length = length + 1
    }

    printf("%lld\n", -1 as i64)
    free(is_prime_arr)
    free(counts)
    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 MAXL = 25;
static const int64_t MAXS = 225;




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