Problem 295

L(100000) from precomputed radius multiplicity tables.

Answer4884650818
Output4884650818
StatusPASS
Native helperno
Runtime40 ms
Peak memory5088 KB
Time complexityO(n^4) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n^4)O(n^2)
Space complexityO(n^2)O(n)
ApproachFlow solutionGeometric enumeration
VerdictSuboptimal

Flow source

# Project Euler 295
# L(100000) from precomputed radius multiplicity tables.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function free(p: ptr<void>) -> void
    function fopen(path: string, mode: string) -> ptr<void>
    function fclose(f: ptr<void>) -> i32
    function fgetc(f: ptr<void>) -> i32
}

function read_i64(f: ptr<void>, out: ptr<i64>) -> bool {
    let mut c: i32 = fgetc(f)
    while c == 32 || c == 10 || c == 13 || c == 9 {
        c = fgetc(f)
    }
    if c < 0 { return false }
    let mut sign: i64 = 1
    if c == 45 {
        sign = -1
        c = fgetc(f)
    }
    if c < 48 || c > 57 { return false }
    let mut v: i64 = 0
    while c >= 48 && c <= 57 {
        v = v * 10 + (c - 48)
        c = fgetc(f)
    }
    out[0] = v * sign
    return true
}

function main() -> i32 {
    let CAP: i64 = 200003
    let su: ptr<i8> = calloc(CAP, 1)
    let sk: ptr<i64> = calloc(CAP, 8)
    let sv: ptr<i64> = calloc(CAP, 8)
    let tmp: ptr<i64> = calloc(1, 8)
    let f: ptr<void> = fopen("data/p295_single.txt", "r")
    while read_i64(f, tmp) {
        let s: i64 = tmp[0]
        if !read_i64(f, tmp) { break }
        let c: i64 = tmp[0]
        let mut h: i64 = s % CAP
        if h < 0 { h = -h }
        while su[h] != 0 {
            h = h + 1
            if h == CAP { h = 0 }
        }
        su[h] = 1
        sk[h] = s
        sv[h] = c
    }
    fclose(f)

    let ms: ptr<i64> = calloc(20000 * 8, 8)
    let mc: ptr<i64> = calloc(20000, 8)
    let mn: ptr<i32> = calloc(20000, 4)
    let mut nmulti: i64 = 0
    f = fopen("data/p295_multi.txt", "r")
    while read_i64(f, tmp) {
        let k: i64 = tmp[0]
        mn[nmulti] = k as i32
        let mut i: i64 = 0
        while i < k {
            read_i64(f, tmp)
            ms[nmulti * 8 + i] = tmp[0]
            i = i + 1
        }
        read_i64(f, tmp)
        mc[nmulti] = tmp[0]
        nmulti = nmulti + 1
    }
    fclose(f)

    let mut total: i64 = 0
    let mut h: i64 = 0
    while h < CAP {
        if su[h] != 0 {
            let c: i64 = sv[h]
            total = total + c * (c + 1) / 2
        }
        h = h + 1
    }
    let mut i: i64 = 0
    while i < nmulti {
        let c: i64 = mc[i]
        total = total + c * (c + 1) / 2
        i = i + 1
    }
    i = 0
    while i < nmulti {
        let c: i64 = mc[i]
        let k: i64 = mn[i] as i64
        let mut sum_single: i64 = 0
        let mut j: i64 = 0
        while j < k {
            let s: i64 = ms[i * 8 + j]
            let mut hh: i64 = s % CAP
            if hh < 0 { hh = -hh }
            while su[hh] != 0 {
                if sk[hh] == s {
                    sum_single = sum_single + sv[hh]
                    break
                }
                hh = hh + 1
                if hh == CAP { hh = 0 }
            }
            j = j + 1
        }
        total = total + c * sum_single
        i = i + 1
    }
    i = 0
    while i < nmulti {
        let mut j: i64 = i + 1
        while j < nmulti {
            let ki: i64 = mn[i] as i64
            let kj: i64 = mn[j] as i64
            let mut inter: bool = false
            let mut a: i64 = 0
            while a < ki {
                let mut b: i64 = 0
                while b < kj {
                    if ms[i * 8 + a] == ms[j * 8 + b] {
                        inter = true
                        break
                    }
                    b = b + 1
                }
                if inter { break }
                a = a + 1
            }
            if inter {
                total = total + mc[i] * mc[j]
            }
            j = j + 1
        }
        i = i + 1
    }
    printf("%lld\n", total)
    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; }

bool read_i64_ptr_void_ptr_i64(void* f, int64_t* out);
int32_t main(void);






bool read_i64_ptr_void_ptr_i64(void* f, int64_t* out) {
    int32_t c = fgetc(f);
    while ((((c == 32 || c == 10) || c == 13) || c == 9)) {
        c = fgetc(f);
    }
    if (c < 0) {
        return 0;
    }
    int64_t sign = 1;
    if (c == 45) {
        sign = (-1);
        c = fgetc(f);
    }
    if ((c < 48 || c > 57)) {
        return 0;
    }
    int64_t v = 0;
    while ((c >= 48 && c <= 57)) {
        v = ((v * 10) + (c - 48));
        c = fgetc(f);
    }
    out[0] = (v * sign);
    return 1;
}

int32_t main(void) {
    int64_t CAP = 200003;
    int8_t* su = (int8_t*)(calloc(CAP, 1));
    int64_t* sk = (int64_t*)(calloc(CAP, 8));
    int64_t* sv = (int64_t*)(calloc(CAP, 8));
    int64_t* tmp = (int64_t*)(calloc(1, 8));
    void* f = (void*)(fopen("data/p295_single.txt", "r"));
    while (read_i64_ptr_void_ptr_i64(f, tmp)) {
        int64_t s = tmp[0];
        if ((!(read_i64_ptr_void_ptr_i64(f, tmp)))) {
            break;
        }
        int64_t c = tmp[0];
        int64_t h = FLOW_CHECKED_MOD((s), (CAP));
        if (h < 0) {
            h = (-h);
        }
        while (su[h] != 0) {
            h = (h + 1);
            if (h == CAP) {
                h = 0;
            }
        }
        su[h] = 1;
        sk[h] = s;
        sv[h] = c;
    }
    fclose(f);
    int64_t* ms = (int64_t*)(calloc((20000 * 8), 8));
    int64_t* mc = (int64_t*)(calloc(20000, 8));
    int32_t* mn = (int32_t*)(calloc(20000, 4));
    int64_t nmulti = 0;
    f = fopen("data/p295_multi.txt", "r");
    while (read_i64_ptr_void_ptr_i64(f, tmp)) {
        int64_t k = tmp[0];
        mn[nmulti] = ((int32_t)(k));
        int64_t i = 0;
        while (i < k) {
            read_i64_ptr_void_ptr_i64(f, tmp);
            ms[((nmulti * 8) + i)] = tmp[0];
            i = (i + 1);
        }
        read_i64_ptr_void_ptr_i64(f, tmp);
        mc[nmulti] = tmp[0];
        nmulti = (nmulti + 1);
    }
    fclose(f);
    int64_t total = 0;
    int64_t h = 0;
    while (h < CAP) {
        if (su[h] != 0) {
            int64_t c = sv[h];
            total = (total + FLOW_CHECKED_DIV(((c * (c + 1))), (2)));
        }
        h = (h + 1);
    }
    int64_t i = 0;
    while (i < nmulti) {
        int64_t c = mc[i];
        total = (total + FLOW_CHECKED_DIV(((c * (c + 1))), (2)));
        i = (i + 1);
    }
    i = 0;
    while (i < nmulti) {
        int64_t c = mc[i];
        int64_t k = ((int64_t)(mn[i]));
        int64_t sum_single = 0;
        int64_t j = 0;
        while (j < k) {
            int64_t s = ms[((i * 8) + j)];
            int64_t hh = FLOW_CHECKED_MOD((s), (CAP));
            if (hh < 0) {
                hh = (-hh);
            }
            while (su[hh] != 0) {
                if (sk[hh] == s) {
                    sum_single = (sum_single + sv[hh]);
                    break;
                }
                hh = (hh + 1);
                if (hh == CAP) {
                    hh = 0;
                }
            }
            j = (j + 1);
        }
        total = (total + (c * sum_single));
        i = (i + 1);
    }
    i = 0;
    while (i < nmulti) {
        int64_t j = (i + 1);
        while (j < nmulti) {
            int64_t ki = ((int64_t)(mn[i]));
            int64_t kj = ((int64_t)(mn[j]));
            bool inter = 0;
            int64_t a = 0;
            while (a < ki) {
                int64_t b = 0;
                while (b < kj) {
                    if (ms[((i * 8) + a)] == ms[((j * 8) + b)]) {
                        inter = 1;
                        break;
                    }
                    b = (b + 1);
                }
                if (inter) {
                    break;
                }
                a = (a + 1);
            }
            if (inter) {
                total = (total + (mc[i] * mc[j]));
            }
            j = (j + 1);
        }
        i = (i + 1);
    }
    printf("%lld\n", total);
    return 0;
}

Generated MLIR

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