Problem 185

Number Mind: recover unique 16-digit sequence from guesses.

Answer4640261571849533
Output4640261571849533
StatusPASS
Native helperno
Runtime540 ms
Peak memory1120 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 solutionPermutation enumeration or constraint search
VerdictOptimal

Flow source

# Project Euler 185
# Number Mind: recover unique 16-digit sequence from guesses.

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

let mut seed: i64 = 0

function myrand(modulo: i32) -> i32 {
    seed = seed * 1103515245 + 12345
    # keep lower 32 bits
    seed = seed - (seed / 4294967296) * 4294967296
    if seed < 0 { seed = seed + 4294967296 }
    return (seed % (modulo as i64)) as i32
}

function shuffle_digit(digit: i32) -> i32 {
    let old: i32 = digit
    let mut d: i32 = myrand(10)
    while d == old {
        d = myrand(10)
    }
    return d
}

function distance(cur: ptr<i32>, seqs: ptr<i32>, hits: ptr<i32>, ng: i32, nd: i32) -> i32 {
    let mut errors: i32 = 0
    let mut i: i32 = 0
    while i < ng {
        let mut same: i32 = 0
        let mut j: i32 = 0
        while j < nd {
            if cur[j] == seqs[i * nd + j] { same = same + 1 }
            j = j + 1
        }
        if same > hits[i] { errors = errors + (same - hits[i]) }
        else { errors = errors + (hits[i] - same) }
        i = i + 1
    }
    return errors
}

function main() -> i32 {
    let f: ptr<void> = fopen("data/p185.txt", "r")
    if f == null {
        printf("missing data\n")
        return 1
    }
    let NG: i32 = 22
    let ND: i32 = 16
    let seqs: ptr<i32> = calloc((NG * ND) as i64, 4)
    let hits: ptr<i32> = calloc(NG as i64, 4)
    let cur: ptr<i32> = calloc(ND as i64, 4)
    if seqs == null || hits == null || cur == null { return 1 }

    let mut gi: i32 = 0
    let mut di: i32 = 0
    let mut in_guess: bool = true
    let mut hit_val: i32 = 0
    let mut reading_hit: bool = false
    let mut c: i32 = fgetc(f)
    while c >= 0 && gi < NG {
        if c >= 48 && c <= 57 {
            if in_guess && di < ND {
                seqs[gi * ND + di] = c - 48
                di = di + 1
            } elif reading_hit {
                hit_val = hit_val * 10 + (c - 48)
            }
        } elif c == 59 {
            in_guess = false
            reading_hit = true
            hit_val = 0
        } elif c == 10 || c == 13 {
            if di == ND {
                hits[gi] = hit_val
                gi = gi + 1
            }
            di = 0
            in_guess = true
            reading_hit = false
            hit_val = 0
        }
        c = fgetc(f)
    }
    # last line without newline
    if gi < NG && di == ND {
        hits[gi] = hit_val
        gi = gi + 1
    }
    fclose(f)
    if gi != NG {
        printf("parse fail %d\n", gi)
        return 1
    }

    let mut attempt: i32 = 0
    while attempt < 100 {
        seed = attempt as i64
        let mut i: i32 = 0
        while i < ND {
            cur[i] = myrand(10)
            i = i + 1
        }
        let mut errors: i32 = distance(cur, seqs, hits, NG, ND)
        let mut previous: i32 = errors
        let mut quiet: i32 = 0
        let mut steps: i32 = 0
        while errors != 0 && steps < 100000 {
            i = 0
            while i < ND {
                let prev_d: i32 = cur[i]
                cur[i] = shuffle_digit(prev_d)
                let modified: i32 = distance(cur, seqs, hits, NG, ND)
                if modified <= errors {
                    errors = modified
                } else {
                    cur[i] = prev_d
                }
                i = i + 1
            }
            if errors == previous {
                quiet = quiet + 1
                if quiet == 20 {
                    let idx: i32 = myrand(ND)
                    cur[idx] = shuffle_digit(cur[idx])
                    errors = distance(cur, seqs, hits, NG, ND)
                    quiet = 0
                }
            } else {
                quiet = 0
                previous = errors
            }
            steps = steps + 1
        }
        if errors == 0 { break }
        attempt = attempt + 1
    }

    let mut ans: i64 = 0
    let mut i: i32 = 0
    while i < ND {
        ans = ans * 10 + (cur[i] as i64)
        i = i + 1
    }
    printf("%lld\n", ans)
    free(seqs); free(hits); free(cur)
    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 myrand_i32(int32_t modulo);
int32_t shuffle_digit_i32(int32_t digit);
int32_t distance_ptr_i32_ptr_i32_ptr_i32_i32_i32(int32_t* cur, int32_t* seqs, int32_t* hits, int32_t ng, int32_t nd);
int32_t main(void);

/* Module statics */
static int64_t seed = 0;






int32_t myrand_i32(int32_t modulo) {
    seed = ((seed * 1103515245) + 12345);
    seed = (seed - (FLOW_CHECKED_DIV((seed), (4294967296)) * 4294967296));
    if (seed < 0) {
        seed = (seed + 4294967296);
    }
    return ((int32_t)(FLOW_CHECKED_MOD((seed), (((int64_t)(modulo))))));
}

int32_t shuffle_digit_i32(int32_t digit) {
    int32_t old = digit;
    int32_t d = myrand_i32(10);
    while (d == old) {
        d = myrand_i32(10);
    }
    return d;
}

int32_t distance_ptr_i32_ptr_i32_ptr_i32_i32_i32(int32_t* cur, int32_t* seqs, int32_t* hits, int32_t ng, int32_t nd) {
    int32_t errors = 0;
    int32_t i = 0;
    while (i < ng) {
        int32_t same = 0;
        int32_t j = 0;
        while (j < nd) {
            if (cur[j] == seqs[((i * nd) + j)]) {
                same = (same + 1);
            }
            j = (j + 1);
        }
        if (same > hits[i]) {
            errors = (errors + (same - hits[i]));
        } else {
            errors = (errors + (hits[i] - same));
        }
        i = (i + 1);
    }
    return errors;
}

int32_t main(void) {
    void* f = (void*)(fopen("data/p185.txt", "r"));
    if (f == NULL) {
        printf("missing data\n");
        return 1;
    }
    int32_t NG = 22;
    int32_t ND = 16;
    int32_t* seqs = (int32_t*)(calloc(((int64_t)((NG * ND))), 4));
    int32_t* hits = (int32_t*)(calloc(((int64_t)(NG)), 4));
    int32_t* cur = (int32_t*)(calloc(((int64_t)(ND)), 4));
    if (((seqs == NULL || hits == NULL) || cur == NULL)) {
        return 1;
    }
    int32_t gi = 0;
    int32_t di = 0;
    bool in_guess = 1;
    int32_t hit_val = 0;
    bool reading_hit = 0;
    int32_t c = fgetc(f);
    while ((c >= 0 && gi < NG)) {
        if ((c >= 48 && c <= 57)) {
            if ((in_guess && di < ND)) {
                seqs[((gi * ND) + di)] = (c - 48);
                di = (di + 1);
            } else if (reading_hit) {
                hit_val = ((hit_val * 10) + (c - 48));
            }
        } else if (c == 59) {
            in_guess = 0;
            reading_hit = 1;
            hit_val = 0;
        } else if ((c == 10 || c == 13)) {
            if (di == ND) {
                hits[gi] = hit_val;
                gi = (gi + 1);
            }
            di = 0;
            in_guess = 1;
            reading_hit = 0;
            hit_val = 0;
        }
        c = fgetc(f);
    }
    if ((gi < NG && di == ND)) {
        hits[gi] = hit_val;
        gi = (gi + 1);
    }
    fclose(f);
    if (gi != NG) {
        printf("parse fail %d\n", gi);
        return 1;
    }
    int32_t attempt = 0;
    while (attempt < 100) {
        seed = ((int64_t)(attempt));
        int32_t i = 0;
        while (i < ND) {
            cur[i] = myrand_i32(10);
            i = (i + 1);
        }
        int32_t errors = distance_ptr_i32_ptr_i32_ptr_i32_i32_i32(cur, seqs, hits, NG, ND);
        int32_t previous = errors;
        int32_t quiet = 0;
        int32_t steps = 0;
        while ((errors != 0 && steps < 100000)) {
            i = 0;
            while (i < ND) {
                int32_t prev_d = cur[i];
                cur[i] = shuffle_digit_i32(prev_d);
                int32_t modified = distance_ptr_i32_ptr_i32_ptr_i32_i32_i32(cur, seqs, hits, NG, ND);
                if (modified <= errors) {
                    errors = modified;
                } else {
                    cur[i] = prev_d;
                }
                i = (i + 1);
            }
            if (errors == previous) {
                quiet = (quiet + 1);
                if (quiet == 20) {
                    int32_t idx = myrand_i32(ND);
                    cur[idx] = shuffle_digit_i32(cur[idx]);
                    errors = distance_ptr_i32_ptr_i32_ptr_i32_i32_i32(cur, seqs, hits, NG, ND);
                    quiet = 0;
                }
            } else {
                quiet = 0;
                previous = errors;
            }
            steps = (steps + 1);
        }
        if (errors == 0) {
            break;
        }
        attempt = (attempt + 1);
    }
    int64_t ans = 0;
    int32_t i = 0;
    while (i < ND) {
        ans = ((ans * 10) + ((int64_t)(cur[i])));
        i = (i + 1);
    }
    printf("%lld\n", ans);
    free(seqs);
    free(hits);
    free(cur);
    return 0;
}

Generated MLIR

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