Problem 111

Sum of S(10, d) for d=0..9 — primes with maximal repeated digit d.

Answer612407567715
Output612407567715
StatusPASS
Native helperno
Runtime0 ms
Peak memory1072 KB
Time complexityO(n^4) (estimated)
Space complexityO(1) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^4)O(n log log n)
Space complexityO(1)O(n)
ApproachFlow solutionSieve or enumeration
VerdictSuboptimal

Flow source

# Project Euler 111
# Sum of S(10, d) for d=0..9 — primes with maximal repeated digit d.

function mulmod(a0: i64, b0: i64, mod: i64) -> i64 {
    let mut a: i64 = a0 % mod
    let mut b: i64 = b0 % mod
    if a < 0 { a = a + mod }
    if b < 0 { b = b + mod }
    let mut result: i64 = 0
    while b > 0 {
        if b % 2 == 1 {
            result = (result + a) % mod
        }
        a = (a * 2) % mod
        b = b / 2
    }
    return result
}

function modpow(base: i64, exp: i64, mod: i64) -> i64 {
    let mut result: i64 = 1
    let mut b: i64 = base % mod
    let mut e: i64 = exp
    while e > 0 {
        if e % 2 == 1 {
            result = mulmod(result, b, mod)
        }
        b = mulmod(b, b, mod)
        e = e / 2
    }
    return result
}

function is_prime(n: i64) -> bool {
    if n < 2 { return false }
    if n % 2 == 0 { return n == 2 }
    if n % 3 == 0 { return n == 3 }
    let bases: array<i64, 7>
    bases[0] = 2
    bases[1] = 325
    bases[2] = 9375
    bases[3] = 28178
    bases[4] = 450775
    bases[5] = 9780504
    bases[6] = 1795265022
    let mut d: i64 = n - 1
    let mut s: i32 = 0
    while d % 2 == 0 {
        d = d / 2
        s = s + 1
    }
    let mut bi: i32 = 0
    while bi < 7 {
        let a: i64 = bases[bi] % n
        if a != 0 {
            let mut x: i64 = modpow(a, d, n)
            if x != 1 && x != n - 1 {
                let mut r: i32 = 1
                let mut composite: bool = true
                while r < s {
                    x = mulmod(x, x, n)
                    if x == n - 1 {
                        composite = false
                        break
                    }
                    r = r + 1
                }
                if composite { return false }
            }
        }
        bi = bi + 1
    }
    return true
}

function popcount(x0: i32) -> i32 {
    let mut x: i32 = x0
    let mut c: i32 = 0
    while x > 0 {
        c = c + (x & 1)
        x = x / 2
    }
    return c
}

function sum_for_digit(d: i32, N: i32) -> i64 {
    let mut M: i32 = N
    while M >= 0 {
        let freec: i32 = N - M
        let mut total: i64 = 0
        let mut found: bool = false
        let lim: i32 = 1 << N
        let mut maxv: i32 = 1
        let mut i: i32 = 0
        while i < freec {
            maxv = maxv * 10
            i = i + 1
        }
        let mut mask: i32 = 0
        while mask < lim {
            if popcount(mask) == freec {
                let mut v: i32 = 0
                while v < maxv {
                    let mut num: i64 = 0
                    let mut vv: i32 = v
                    let mut ok: bool = true
                    let mut pos: i32 = 0
                    while pos < N {
                        let mut digit: i32 = d
                        if ((mask >> pos) & 1) == 1 {
                            digit = vv % 10
                            vv = vv / 10
                            if digit == d {
                                ok = false
                                break
                            }
                        }
                        if pos == 0 && digit == 0 {
                            ok = false
                            break
                        }
                        num = num * 10 + (digit as i64)
                        pos = pos + 1
                    }
                    if ok && is_prime(num) {
                        total = total + num
                        found = true
                    }
                    v = v + 1
                }
            }
            mask = mask + 1
        }
        if found {
            return total
        }
        M = M - 1
    }
    return 0
}

function main() -> i32 {
    let N: i32 = 10
    let mut ans: i64 = 0
    let mut d: i32 = 0
    while d <= 9 {
        ans = ans + sum_for_digit(d, N)
        d = d + 1
    }
    printf("%lld\n", ans)
    return 0
}

Generated C

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

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

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

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

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

#include <math.h>

void* _ui_state = NULL;

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

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

int64_t mulmod_i64_i64_i64(int64_t a0, int64_t b0, int64_t mod);
int64_t modpow_i64_i64_i64(int64_t base, int64_t exp, int64_t mod);
bool is_prime_i64(int64_t n);
int32_t popcount_i32(int32_t x0);
int64_t sum_for_digit_i32_i32(int32_t d, int32_t N);
int32_t main(void);

int64_t mulmod_i64_i64_i64(int64_t a0, int64_t b0, int64_t mod) {
    int64_t a = FLOW_CHECKED_MOD((a0), (mod));
    int64_t b = FLOW_CHECKED_MOD((b0), (mod));
    if (a < 0) {
        a = (a + mod);
    }
    if (b < 0) {
        b = (b + mod);
    }
    int64_t result = 0;
    while (b > 0) {
        if (FLOW_CHECKED_MOD((b), (2)) == 1) {
            result = FLOW_CHECKED_MOD(((result + a)), (mod));
        }
        a = FLOW_CHECKED_MOD(((a * 2)), (mod));
        b = FLOW_CHECKED_DIV((b), (2));
    }
    return result;
}

int64_t modpow_i64_i64_i64(int64_t base, int64_t exp, int64_t mod) {
    int64_t result = 1;
    int64_t b = FLOW_CHECKED_MOD((base), (mod));
    int64_t e = exp;
    while (e > 0) {
        if (FLOW_CHECKED_MOD((e), (2)) == 1) {
            result = mulmod_i64_i64_i64(result, b, mod);
        }
        b = mulmod_i64_i64_i64(b, b, mod);
        e = FLOW_CHECKED_DIV((e), (2));
    }
    return result;
}

bool is_prime_i64(int64_t n) {
    if (n < 2) {
        return 0;
    }
    if (FLOW_CHECKED_MOD((n), (2)) == 0) {
        return n == 2;
    }
    if (FLOW_CHECKED_MOD((n), (3)) == 0) {
        return n == 3;
    }
    int64_t bases[7];
    bases[0] = 2;
    bases[1] = 325;
    bases[2] = 9375;
    bases[3] = 28178;
    bases[4] = 450775;
    bases[5] = 9780504;
    bases[6] = 1795265022;
    int64_t d = (n - 1);
    int32_t s = 0;
    while (FLOW_CHECKED_MOD((d), (2)) == 0) {
        d = FLOW_CHECKED_DIV((d), (2));
        s = (s + 1);
    }
    int32_t bi = 0;
    while (bi < 7) {
        int64_t a = FLOW_CHECKED_MOD(((((unsigned)(bi) < 7) ? bases[bi] : (fprintf(stderr, "array index %d out of bounds (size %d)\n", (int)(bi), 7), flow_fault_handler("array index out of bounds"), bases[0]))), (n));
        if (a != 0) {
            int64_t x = modpow_i64_i64_i64(a, d, n);
            if ((x != 1 && x != (n - 1))) {
                int32_t r = 1;
                bool composite = 1;
                while (r < s) {
                    x = mulmod_i64_i64_i64(x, x, n);
                    if (x == (n - 1)) {
                        composite = 0;
                        break;
                    }
                    r = (r + 1);
                }
                if (composite) {
                    return 0;
                }
            }
        }
        bi = (bi + 1);
    }
    return 1;
}

int32_t popcount_i32(int32_t x0) {
    int32_t x = x0;
    int32_t c = 0;
    while (x > 0) {
        c = (c + (x & 1));
        x = FLOW_CHECKED_DIV((x), (2));
    }
    return c;
}

int64_t sum_for_digit_i32_i32(int32_t d, int32_t N) {
    int32_t M = N;
    while (M >= 0) {
        int32_t freec = (N - M);
        int64_t total = 0;
        bool found = 0;
        int32_t lim = FLOW_CHECKED_SHL((1), (N));
        int32_t maxv = 1;
        int32_t i = 0;
        while (i < freec) {
            maxv = (maxv * 10);
            i = (i + 1);
        }
        int32_t mask = 0;
        while (mask < lim) {
            if (popcount_i32(mask) == freec) {
                int32_t v = 0;
                while (v < maxv) {
                    int64_t num = 0;
                    int32_t vv = v;
                    bool ok = 1;
                    int32_t pos = 0;
                    while (pos < N) {
                        int32_t digit = d;
                        if ((FLOW_CHECKED_SHR((mask), (pos)) & 1) == 1) {
                            digit = FLOW_CHECKED_MOD((vv), (10));
                            vv = FLOW_CHECKED_DIV((vv), (10));
                            if (digit == d) {
                                ok = 0;
                                break;
                            }
                        }
                        if ((pos == 0 && digit == 0)) {
                            ok = 0;
                            break;
                        }
                        num = ((num * 10) + ((int64_t)(digit)));
                        pos = (pos + 1);
                    }
                    if ((ok && is_prime_i64(num))) {
                        total = (total + num);
                        found = 1;
                    }
                    v = (v + 1);
                }
            }
            mask = (mask + 1);
        }
        if (found) {
            return total;
        }
        M = (M - 1);
    }
    return 0;
}

int32_t main(void) {
    int32_t N = 10;
    int64_t ans = 0;
    int32_t d = 0;
    while (d <= 9) {
        ans = (ans + sum_for_digit_i32_i32(d, N));
        d = (d + 1);
    }
    printf("%lld\n", ans);
    return 0;
}

Generated MLIR

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