Problem 828
Numbers Challenge: minimum score expression from given numbers. Pure Flow port of the native C solver.
View problem on Project Euler
Performance comparison
| Metric | Our solution | Best known |
| Time complexity | O(2^n) | O(n log n) |
| Space complexity | O(n^2) | O(n) |
| Approach | Flow solution | Search with pruning or sieve |
| Verdict | Suboptimal |
Flow source
# Project Euler 828
# Numbers Challenge: minimum score expression from given numbers.
# Pure Flow port of the native C solver.
extern {
function fopen(path: string, mode: string) -> ptr<void>
function fgetc(f: ptr<void>) -> i32
function fclose(f: ptr<void>) -> i32
function calloc(n: i64, size: i64) -> ptr<void>
function free(p: ptr<void>) -> void
function malloc(n: i64) -> ptr<void>
function memcpy(dst: ptr<void>, src: ptr<void>, n: i64) -> ptr<void>
function memset(p: ptr<void>, c: i32, n: i64) -> void
}
const MOD: i64 = 1005075251
const CACHE_CAP: i32 = 1048576
const MAX_PROBS: i32 = 200
const MAX_NUMS: i32 = 6
struct CacheSlot {
key: i64
vals: ptr<i32>
count: i32
used: i32
}
# Global cache
let mut g_cache: ptr<CacheSlot> = null
# Global dynamic array state
let mut g_da_vals: ptr<i32> = null
let mut g_da_count: i32 = 0
let mut g_da_cap: i32 = 0
# Problem data
let mut g_targets: ptr<i32> = null
let mut g_counts: ptr<i32> = null
let mut g_nums: ptr<i32> = null
let mut g_num_problems: i32 = 0
function da_init() -> void {
g_da_cap = 16
g_da_vals = malloc((g_da_cap as i64) * 4)
g_da_count = 0
}
function da_free() -> void {
free(g_da_vals)
g_da_vals = null
g_da_count = 0
g_da_cap = 0
}
function da_add(v: i32) -> void {
if g_da_count >= g_da_cap {
let new_cap: i32 = g_da_cap * 2
let new_vals: ptr<i32> = malloc((new_cap as i64) * 4)
memcpy(new_vals, g_da_vals, (g_da_count as i64) * 4)
free(g_da_vals)
g_da_vals = new_vals
g_da_cap = new_cap
}
g_da_vals[g_da_count] = v
g_da_count = g_da_count + 1
}
function cache_reset() -> void {
g_cache = calloc(CACHE_CAP as i64, 24)
}
function cache_hash(key: i64) -> i32 {
return ((key * 1099511628211) & ((CACHE_CAP as i64) - 1)) as i32
}
function cache_find(key: i64) -> i32 {
let mut h: i32 = cache_hash(key)
while g_cache[h].used != 0 {
if g_cache[h].key == key { return h }
h = (h + 1) & (CACHE_CAP - 1)
}
return -1
}
function cache_insert(key: i64) -> i32 {
let mut h: i32 = cache_hash(key)
while g_cache[h].used != 0 {
if g_cache[h].key == key { return h }
h = (h + 1) & (CACHE_CAP - 1)
}
g_cache[h].used = 1
g_cache[h].key = key
g_cache[h].vals = null
g_cache[h].count = 0
return h
}
function encode_key(nums: ptr<i32>, len: i32) -> i64 {
let sorted: ptr<i32> = malloc(24)
let mut i: i32 = 0
while i < len {
sorted[i] = nums[i]
i = i + 1
}
let mut i2: i32 = 1
while i2 < len {
let key: i32 = sorted[i2]
let mut j: i32 = i2 - 1
while j >= 0 {
if sorted[j] > key {
sorted[j + 1] = sorted[j]
j = j - 1
} else {
break
}
}
sorted[j + 1] = key
i2 = i2 + 1
}
let mut k: i64 = 0
let mut i3: i32 = 0
while i3 < len {
k = k * 201 + ((sorted[i3] + 1) as i64)
i3 = i3 + 1
}
free(sorted)
return k
}
function sort_i32(arr: ptr<i32>, n: i32) -> void {
let mut i: i32 = 1
while i < n {
let key: i32 = arr[i]
let mut j: i32 = i - 1
while j >= 0 {
if arr[j] > key {
arr[j + 1] = arr[j]
j = j - 1
} else {
break
}
}
arr[j + 1] = key
i = i + 1
}
}
function dedup_sorted(arr: ptr<i32>, n: i32) -> i32 {
if n <= 1 { return n }
let mut w: i32 = 1
let mut r: i32 = 1
while r < n {
if arr[r] != arr[r - 1] {
arr[w] = arr[r]
w = w + 1
}
r = r + 1
}
return w
}
# Generate all achievable values from nums[0..len-1].
# Results are added to the global dynamic array g_da_vals.
function generate_values(nums: ptr<i32>, len: i32) -> void {
let key: i64 = encode_key(nums, len)
let slot_idx: i32 = cache_find(key)
if slot_idx >= 0 {
let mut i: i32 = 0
while i < g_cache[slot_idx].count {
da_add(g_cache[slot_idx].vals[i])
i = i + 1
}
return
}
# Build result in a new dynamic array
let saved_vals: ptr<i32> = g_da_vals
let saved_count: i32 = g_da_count
let saved_cap: i32 = g_da_cap
da_init()
if len == 1 {
da_add(nums[0])
} else {
let total: i32 = 1 << len
let mut mask: i32 = 1
while mask < total - 1 {
let complement: i32 = (~mask) & (total - 1)
if mask > complement {
mask = mask + 1
continue
}
let left: ptr<i32> = malloc(24)
let right: ptr<i32> = malloc(24)
let mut nl: i32 = 0
let mut nr: i32 = 0
let mut i: i32 = 0
while i < len {
if (mask & (1 << i)) != 0 {
left[nl] = nums[i]
nl = nl + 1
} else {
right[nr] = nums[i]
nr = nr + 1
}
i = i + 1
}
# Generate values for left group into a temp array
let save_l_vals: ptr<i32> = g_da_vals
let save_l_count: i32 = g_da_count
let save_l_cap: i32 = g_da_cap
da_init()
generate_values(left, nl)
let vl: ptr<i32> = g_da_vals
let vl_count: i32 = g_da_count
# Generate values for right group into a temp array
g_da_vals = save_l_vals
g_da_count = save_l_count
g_da_cap = save_l_cap
let save_r_vals: ptr<i32> = g_da_vals
let save_r_count: i32 = g_da_count
let save_r_cap: i32 = g_da_cap
da_init()
generate_values(right, nr)
let vr: ptr<i32> = g_da_vals
let vr_count: i32 = g_da_count
# Restore to result array
g_da_vals = save_r_vals
g_da_count = save_r_count
g_da_cap = save_r_cap
# Combine
let mut i2: i32 = 0
while i2 < vl_count {
let mut j: i32 = 0
while j < vr_count {
let a: i32 = vl[i2]
let b: i32 = vr[j]
da_add(a + b)
da_add(a * b)
if a > b { da_add(a - b) }
if b > a { da_add(b - a) }
if b > 0 && a % b == 0 { da_add(a / b) }
if a > 0 && b % a == 0 { da_add(b / a) }
j = j + 1
}
i2 = i2 + 1
}
free(vl)
free(vr)
free(left)
free(right)
mask = mask + 1
}
}
# Sort and dedup
sort_i32(g_da_vals, g_da_count)
g_da_count = dedup_sorted(g_da_vals, g_da_count)
# Store in cache
let s_idx: i32 = cache_insert(key)
let stored_vals: ptr<i32> = malloc((g_da_count as i64) * 4)
memcpy(stored_vals, g_da_vals, (g_da_count as i64) * 4)
g_cache[s_idx].vals = stored_vals
g_cache[s_idx].count = g_da_count
# Copy results to the caller's array
let result_vals: ptr<i32> = g_da_vals
let result_count: i32 = g_da_count
# Restore caller's dynamic array
g_da_vals = saved_vals
g_da_count = saved_count
g_da_cap = saved_cap
# Add results to caller's array
let mut i3: i32 = 0
while i3 < result_count {
da_add(result_vals[i3])
i3 = i3 + 1
}
free(result_vals)
}
function min_score(target: i32, nums_base: ptr<i32>, nums_offset: i32, count: i32) -> i32 {
let mut best: i32 = 0
let total: i32 = 1 << count
let mut mask: i32 = 1
while mask < total {
let subset: ptr<i32> = malloc(24)
let mut ns: i32 = 0
let mut sum: i32 = 0
let mut i: i32 = 0
while i < count {
if (mask & (1 << i)) != 0 {
subset[ns] = nums_base[nums_offset + i]
sum = sum + nums_base[nums_offset + i]
ns = ns + 1
}
i = i + 1
}
if best > 0 && sum >= best {
free(subset)
mask = mask + 1
continue
}
da_init()
generate_values(subset, ns)
# Binary search for target
let mut lo: i32 = 0
let mut hi: i32 = g_da_count - 1
let mut found: i32 = 0
while lo <= hi {
let mid: i32 = (lo + hi) / 2
if g_da_vals[mid] == target {
found = 1
break
}
if g_da_vals[mid] < target {
lo = mid + 1
} else {
hi = mid - 1
}
}
if found != 0 {
if best == 0 || sum < best { best = sum }
}
da_free()
free(subset)
mask = mask + 1
}
return best
}
function read_data(path: string) -> void {
g_targets = malloc((MAX_PROBS as i64) * 4)
g_counts = malloc((MAX_PROBS as i64) * 4)
g_nums = malloc((MAX_PROBS as i64) * (MAX_NUMS as i64) * 4)
let f: ptr<void> = fopen(path, "r")
if f == null { return }
g_num_problems = 0
let mut c: i32 = fgetc(f)
while c >= 0 {
# Skip whitespace
while c >= 0 && c <= 32 { c = fgetc(f) }
if c < 0 { break }
# Read target
let mut target: i32 = 0
while c >= 48 && c <= 57 {
target = target * 10 + (c - 48)
c = fgetc(f)
}
g_targets[g_num_problems] = target
# Skip ':'
if c == 58 { c = fgetc(f) }
# Read numbers
let mut cnt: i32 = 0
while c >= 0 && c != 10 && c != 13 {
# Skip comma
while c == 44 { c = fgetc(f) }
if c < 0 || c == 10 || c == 13 { break }
# Read number
let mut val: i32 = 0
while c >= 48 && c <= 57 {
val = val * 10 + (c - 48)
c = fgetc(f)
}
if val > 0 {
g_nums[g_num_problems * MAX_NUMS + cnt] = val
cnt = cnt + 1
}
}
g_counts[g_num_problems] = cnt
g_num_problems = g_num_problems + 1
# Skip to next line
while c >= 0 && c != 10 { c = fgetc(f) }
if c == 10 { c = fgetc(f) }
}
fclose(f)
}
function main() -> i32 {
cache_reset()
read_data("data/0828_number_challenges.txt")
let mut total: i64 = 0
let mut pow3: i64 = 3
let mut n: i32 = 0
while n < g_num_problems {
let target: i32 = g_targets[n]
let count: i32 = g_counts[n]
let s: i32 = min_score(target, g_nums, n * MAX_NUMS, count)
total = (total + pow3 * (s as i64)) % MOD
pow3 = (pow3 * 3) % MOD
n = n + 1
}
free(g_targets)
free(g_counts)
free(g_nums)
free(g_cache)
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; }
typedef struct CacheSlot CacheSlot;
struct CacheSlot {
int64_t key;
int32_t* vals;
int32_t count;
int32_t used;
};
void da_init(void);
void da_free(void);
void da_add_i32(int32_t v);
void cache_reset(void);
int32_t cache_hash_i64(int64_t key);
int32_t cache_find_i64(int64_t key);
int32_t cache_insert_i64(int64_t key);
int64_t encode_key_ptr_i32_i32(int32_t* nums, int32_t len);
void sort_i32_ptr_i32_i32(int32_t* arr, int32_t n);
int32_t dedup_sorted_ptr_i32_i32(int32_t* arr, int32_t n);
void generate_values_ptr_i32_i32(int32_t* nums, int32_t len);
int32_t min_score_i32_ptr_i32_i32_i32(int32_t target, int32_t* nums_base, int32_t nums_offset, int32_t count);
void read_data_string(char* path);
int32_t main(void);
static const int64_t MOD = 1005075251;
static const int32_t CACHE_CAP = 1048576;
static const int32_t MAX_PROBS = 200;
static const int32_t MAX_NUMS = 6;
/* Module statics */
static CacheSlot* g_cache = NULL;
static int32_t* g_da_vals = NULL;
static int32_t g_da_count = 0;
static int32_t g_da_cap = 0;
static int32_t* g_targets = NULL;
static int32_t* g_counts = NULL;
static int32_t* g_nums = NULL;
static int32_t g_num_problems = 0;
void da_init(void) {
g_da_cap = 16;
g_da_vals = malloc((((int64_t)(g_da_cap)) * 4));
g_da_count = 0;
}
void da_free(void) {
free(g_da_vals);
g_da_vals = NULL;
g_da_count = 0;
g_da_cap = 0;
}
void da_add_i32(int32_t v) {
if (g_da_count >= g_da_cap) {
int32_t new_cap = (g_da_cap * 2);
int32_t* new_vals = (int32_t*)(malloc((((int64_t)(new_cap)) * 4)));
memcpy(new_vals, g_da_vals, (((int64_t)(g_da_count)) * 4));
free(g_da_vals);
g_da_vals = new_vals;
g_da_cap = new_cap;
}
g_da_vals[g_da_count] = v;
g_da_count = (g_da_count + 1);
}
void cache_reset(void) {
g_cache = calloc(((int64_t)(CACHE_CAP)), 24);
}
int32_t cache_hash_i64(int64_t key) {
return ((int32_t)(((key * 1099511628211) & (((int64_t)(CACHE_CAP)) - 1))));
}
int32_t cache_find_i64(int64_t key) {
int32_t h = cache_hash_i64(key);
while (g_cache[h].used != 0) {
if (g_cache[h].key == key) {
return h;
}
h = ((h + 1) & (CACHE_CAP - 1));
}
return (-1);
}
int32_t cache_insert_i64(int64_t key) {
int32_t h = cache_hash_i64(key);
while (g_cache[h].used != 0) {
if (g_cache[h].key == key) {
return h;
}
h = ((h + 1) & (CACHE_CAP - 1));
}
g_cache[h].used = 1;
g_cache[h].key = key;
g_cache[h].vals = NULL;
g_cache[h].count = 0;
return h;
}
int64_t encode_key_ptr_i32_i32(int32_t* nums, int32_t len) {
int32_t* sorted = (int32_t*)(malloc(24));
int32_t i = 0;
while (i < len) {
sorted[i] = nums[i];
i = (i + 1);
}
int32_t i2 = 1;
while (i2 < len) {
int32_t key = sorted[i2];
int32_t j = (i2 - 1);
while (j >= 0) {
if (sorted[j] > key) {
sorted[(j + 1)] = sorted[j];
j = (j - 1);
} else {
break;
}
}
sorted[(j + 1)] = key;
i2 = (i2 + 1);
}
int64_t k = 0;
int32_t i3 = 0;
while (i3 < len) {
k = ((k * 201) + ((int64_t)((sorted[i3] + 1))));
i3 = (i3 + 1);
}
free(sorted);
return k;
}
void sort_i32_ptr_i32_i32(int32_t* arr, int32_t n) {
int32_t i = 1;
while (i < n) {
int32_t key = arr[i];
int32_t j = (i - 1);
while (j >= 0) {
if (arr[j] > key) {
arr[(j + 1)] = arr[j];
j = (j - 1);
} else {
break;
}
}
arr[(j + 1)] = key;
i = (i + 1);
}
}
int32_t dedup_sorted_ptr_i32_i32(int32_t* arr, int32_t n) {
if (n <= 1) {
return n;
}
int32_t w = 1;
int32_t r = 1;
while (r < n) {
if (arr[r] != arr[(r - 1)]) {
arr[w] = arr[r];
w = (w + 1);
}
r = (r + 1);
}
return w;
}
void generate_values_ptr_i32_i32(int32_t* nums, int32_t len) {
int64_t key = encode_key_ptr_i32_i32(nums, len);
int32_t slot_idx = cache_find_i64(key);
if (slot_idx >= 0) {
int32_t i = 0;
while (i < g_cache[slot_idx].count) {
da_add_i32(g_cache[slot_idx].vals[i]);
i = (i + 1);
}
return;
}
int32_t* saved_vals = (int32_t*)(g_da_vals);
int32_t saved_count = g_da_count;
int32_t saved_cap = g_da_cap;
da_init();
if (len == 1) {
da_add_i32(nums[0]);
} else {
int32_t total = FLOW_CHECKED_SHL((1), (len));
int32_t mask = 1;
while (mask < (total - 1)) {
int32_t complement = ((~mask) & (total - 1));
if (mask > complement) {
mask = (mask + 1);
continue;
}
int32_t* left = (int32_t*)(malloc(24));
int32_t* right = (int32_t*)(malloc(24));
int32_t nl = 0;
int32_t nr = 0;
int32_t i = 0;
while (i < len) {
if ((mask & FLOW_CHECKED_SHL((1), (i))) != 0) {
left[nl] = nums[i];
nl = (nl + 1);
} else {
right[nr] = nums[i];
nr = (nr + 1);
}
i = (i + 1);
}
int32_t* save_l_vals = (int32_t*)(g_da_vals);
int32_t save_l_count = g_da_count;
int32_t save_l_cap = g_da_cap;
da_init();
generate_values_ptr_i32_i32(left, nl);
int32_t* vl = (int32_t*)(g_da_vals);
int32_t vl_count = g_da_count;
g_da_vals = save_l_vals;
g_da_count = save_l_count;
g_da_cap = save_l_cap;
int32_t* save_r_vals = (int32_t*)(g_da_vals);
int32_t save_r_count = g_da_count;
int32_t save_r_cap = g_da_cap;
da_init();
generate_values_ptr_i32_i32(right, nr);
int32_t* vr = (int32_t*)(g_da_vals);
int32_t vr_count = g_da_count;
g_da_vals = save_r_vals;
g_da_count = save_r_count;
g_da_cap = save_r_cap;
int32_t i2 = 0;
while (i2 < vl_count) {
int32_t j = 0;
while (j < vr_count) {
int32_t a = vl[i2];
int32_t b = vr[j];
da_add_i32((a + b));
da_add_i32((a * b));
if (a > b) {
da_add_i32((a - b));
}
if (b > a) {
da_add_i32((b - a));
}
if ((b > 0 && FLOW_CHECKED_MOD((a), (b)) == 0)) {
da_add_i32(FLOW_CHECKED_DIV((a), (b)));
}
if ((a > 0 && FLOW_CHECKED_MOD((b), (a)) == 0)) {
da_add_i32(FLOW_CHECKED_DIV((b), (a)));
}
j = (j + 1);
}
i2 = (i2 + 1);
}
free(vl);
free(vr);
free(left);
free(right);
mask = (mask + 1);
}
}
sort_i32_ptr_i32_i32(g_da_vals, g_da_count);
g_da_count = dedup_sorted_ptr_i32_i32(g_da_vals, g_da_count);
int32_t s_idx = cache_insert_i64(key);
int32_t* stored_vals = (int32_t*)(malloc((((int64_t)(g_da_count)) * 4)));
memcpy(stored_vals, g_da_vals, (((int64_t)(g_da_count)) * 4));
g_cache[s_idx].vals = stored_vals;
g_cache[s_idx].count = g_da_count;
int32_t* result_vals = (int32_t*)(g_da_vals);
int32_t result_count = g_da_count;
g_da_vals = saved_vals;
g_da_count = saved_count;
g_da_cap = saved_cap;
int32_t i3 = 0;
while (i3 < result_count) {
da_add_i32(result_vals[i3]);
i3 = (i3 + 1);
}
free(result_vals);
}
int32_t min_score_i32_ptr_i32_i32_i32(int32_t target, int32_t* nums_base, int32_t nums_offset, int32_t count) {
int32_t best = 0;
int32_t total = FLOW_CHECKED_SHL((1), (count));
int32_t mask = 1;
while (mask < total) {
int32_t* subset = (int32_t*)(malloc(24));
int32_t ns = 0;
int32_t sum = 0;
int32_t i = 0;
while (i < count) {
if ((mask & FLOW_CHECKED_SHL((1), (i))) != 0) {
subset[ns] = nums_base[(nums_offset + i)];
sum = (sum + nums_base[(nums_offset + i)]);
ns = (ns + 1);
}
i = (i + 1);
}
if ((best > 0 && sum >= best)) {
free(subset);
mask = (mask + 1);
continue;
}
da_init();
generate_values_ptr_i32_i32(subset, ns);
int32_t lo = 0;
int32_t hi = (g_da_count - 1);
int32_t found = 0;
while (lo <= hi) {
int32_t mid = FLOW_CHECKED_DIV(((lo + hi)), (2));
if (g_da_vals[mid] == target) {
found = 1;
break;
}
if (g_da_vals[mid] < target) {
lo = (mid + 1);
} else {
hi = (mid - 1);
}
}
if (found != 0) {
if ((best == 0 || sum < best)) {
best = sum;
}
}
da_free();
free(subset);
mask = (mask + 1);
}
return best;
}
void read_data_string(char* path) {
g_targets = malloc((((int64_t)(MAX_PROBS)) * 4));
g_counts = malloc((((int64_t)(MAX_PROBS)) * 4));
g_nums = malloc(((((int64_t)(MAX_PROBS)) * ((int64_t)(MAX_NUMS))) * 4));
void* f = (void*)(fopen(path, "r"));
if (f == NULL) {
return;
}
g_num_problems = 0;
int32_t c = fgetc(f);
while (c >= 0) {
while ((c >= 0 && c <= 32)) {
c = fgetc(f);
}
if (c < 0) {
break;
}
int32_t target = 0;
while ((c >= 48 && c <= 57)) {
target = ((target * 10) + (c - 48));
c = fgetc(f);
}
g_targets[g_num_problems] = target;
if (c == 58) {
c = fgetc(f);
}
int32_t cnt = 0;
while (((c >= 0 && c != 10) && c != 13)) {
while (c == 44) {
c = fgetc(f);
}
if (((c < 0 || c == 10) || c == 13)) {
break;
}
int32_t val = 0;
while ((c >= 48 && c <= 57)) {
val = ((val * 10) + (c - 48));
c = fgetc(f);
}
if (val > 0) {
g_nums[((g_num_problems * MAX_NUMS) + cnt)] = val;
cnt = (cnt + 1);
}
}
g_counts[g_num_problems] = cnt;
g_num_problems = (g_num_problems + 1);
while ((c >= 0 && c != 10)) {
c = fgetc(f);
}
if (c == 10) {
c = fgetc(f);
}
}
fclose(f);
}
int32_t main(void) {
cache_reset();
read_data_string("data/0828_number_challenges.txt");
int64_t total = 0;
int64_t pow3 = 3;
int32_t n = 0;
while (n < g_num_problems) {
int32_t target = g_targets[n];
int32_t count = g_counts[n];
int32_t s = min_score_i32_ptr_i32_i32_i32(target, g_nums, (n * MAX_NUMS), count);
total = FLOW_CHECKED_MOD(((total + (pow3 * ((int64_t)(s))))), (MOD));
pow3 = FLOW_CHECKED_MOD(((pow3 * 3)), (MOD));
n = (n + 1);
}
free(g_targets);
free(g_counts);
free(g_nums);
free(g_cache);
printf("%lld\n", total);
return 0;
}
Generated MLIR
module {
llvm.func @printf(!llvm.ptr, ...) -> i32
llvm.mlir.global internal constant @str_0("r\00") {addr_space = 0 : i32} : !llvm.array<2 x i8>
llvm.mlir.global internal constant @str_1("data/0828_number_challenges.txt\00") {addr_space = 0 : i32} : !llvm.array<32 x i8>
llvm.mlir.global internal constant @str_2("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
func.func private @fopen(!llvm.ptr, !llvm.ptr) -> !llvm.ptr
func.func private @fgetc(!llvm.ptr) -> i32
func.func private @fclose(!llvm.ptr) -> i32
func.func private @calloc(i64, i64) -> !llvm.ptr
func.func private @free(!llvm.ptr) -> ()
func.func private @malloc(i64) -> !llvm.ptr
func.func private @memcpy(!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
func.func private @memset(!llvm.ptr, i32, i64) -> ()
// Constant: MOD
llvm.mlir.global internal constant @MOD(1005075251 : i64) : i64
// Constant: CACHE_CAP
llvm.mlir.global internal constant @CACHE_CAP(1048576 : i32) : i32
// Constant: MAX_PROBS
llvm.mlir.global internal constant @MAX_PROBS(200 : i32) : i32
// Constant: MAX_NUMS
llvm.mlir.global internal constant @MAX_NUMS(6 : i32) : i32
// Struct: CacheSlot
// Fields:
// key: i64
// vals: !llvm.ptr
// count: i32
// used: i32
// Module static: g_cache
llvm.mlir.global internal @g_cache() {addr_space = 0 : i32} : !llvm.ptr {
%0 = llvm.mlir.zero : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
// Module static: g_da_vals
llvm.mlir.global internal @g_da_vals() {addr_space = 0 : i32} : !llvm.ptr {
%1 = llvm.mlir.zero : !llvm.ptr
llvm.return %1 : !llvm.ptr
}
// Module static: g_da_count
llvm.mlir.global internal @g_da_count(0 : i32) : i32
// Module static: g_da_cap
llvm.mlir.global internal @g_da_cap(0 : i32) : i32
// Module static: g_targets
llvm.mlir.global internal @g_targets() {addr_space = 0 : i32} : !llvm.ptr {
%2 = llvm.mlir.zero : !llvm.ptr
llvm.return %2 : !llvm.ptr
}
// Module static: g_counts
llvm.mlir.global internal @g_counts() {addr_space = 0 : i32} : !llvm.ptr {
%3 = llvm.mlir.zero : !llvm.ptr
llvm.return %3 : !llvm.ptr
}
// Module static: g_nums
llvm.mlir.global internal @g_nums() {addr_space = 0 : i32} : !llvm.ptr {
%4 = llvm.mlir.zero : !llvm.ptr
llvm.return %4 : !llvm.ptr
}
// Module static: g_num_problems
llvm.mlir.global internal @g_num_problems(0 : i32) : i32
func.func @da_init() -> () {
%5 = arith.constant 16 : i32
%6 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
llvm.store %5, %6 : i32, !llvm.ptr
%8 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
%9 = llvm.load %8 : !llvm.ptr -> i32
%10 = arith.extsi %9 : i32 to i64
%11 = arith.constant 4 : i32
%13 = arith.extsi %11 : i32 to i64
%12 = arith.muli %10, %13 : i64
%7 = func.call @malloc(%12) : (i64) -> !llvm.ptr
%14 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
llvm.store %7, %14 : !llvm.ptr, !llvm.ptr
%15 = arith.constant 0 : i32
%16 = llvm.mlir.addressof @g_da_count : !llvm.ptr
llvm.store %15, %16 : i32, !llvm.ptr
func.return
}
func.func @da_free() -> () {
%18 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%19 = llvm.load %18 : !llvm.ptr -> !llvm.ptr
func.call @free(%19) : (!llvm.ptr) -> ()
%20 = llvm.mlir.zero : !llvm.ptr
%21 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
llvm.store %20, %21 : !llvm.ptr, !llvm.ptr
%22 = arith.constant 0 : i32
%23 = llvm.mlir.addressof @g_da_count : !llvm.ptr
llvm.store %22, %23 : i32, !llvm.ptr
%24 = arith.constant 0 : i32
%25 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
llvm.store %24, %25 : i32, !llvm.ptr
func.return
}
func.func @da_add(%arg0: i32) -> () {
%26 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%27 = llvm.load %26 : !llvm.ptr -> i32
%28 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
%29 = llvm.load %28 : !llvm.ptr -> i32
%30 = arith.cmpi sge, %27, %29 : i32
cf.cond_br %30, ^bb0, ^bb1
^bb0:
%31 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
%32 = llvm.load %31 : !llvm.ptr -> i32
%33 = arith.constant 2 : i32
%34 = arith.muli %32, %33 : i32
%36 = arith.extsi %34 : i32 to i64
%37 = arith.constant 4 : i32
%39 = arith.extsi %37 : i32 to i64
%38 = arith.muli %36, %39 : i64
%35 = func.call @malloc(%38) : (i64) -> !llvm.ptr
%41 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%42 = llvm.load %41 : !llvm.ptr -> !llvm.ptr
%43 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%44 = llvm.load %43 : !llvm.ptr -> i32
%45 = arith.extsi %44 : i32 to i64
%46 = arith.constant 4 : i32
%48 = arith.extsi %46 : i32 to i64
%47 = arith.muli %45, %48 : i64
%40 = func.call @memcpy(%35, %42, %47) : (!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
%50 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%51 = llvm.load %50 : !llvm.ptr -> !llvm.ptr
func.call @free(%51) : (!llvm.ptr) -> ()
%52 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
llvm.store %35, %52 : !llvm.ptr, !llvm.ptr
%53 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
llvm.store %34, %53 : i32, !llvm.ptr
cf.br ^bb2
^bb1:
cf.br ^bb2
^bb2:
%54 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%55 = llvm.load %54 : !llvm.ptr -> !llvm.ptr
%56 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%57 = llvm.load %56 : !llvm.ptr -> i32
%58 = arith.extsi %57 : i32 to i64
%59 = llvm.getelementptr %55[%58] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %arg0, %59 : i32, !llvm.ptr
%60 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%61 = llvm.load %60 : !llvm.ptr -> i32
%62 = arith.constant 1 : i32
%63 = arith.addi %61, %62 : i32
%64 = llvm.mlir.addressof @g_da_count : !llvm.ptr
llvm.store %63, %64 : i32, !llvm.ptr
func.return
}
func.func @cache_reset() -> () {
%66 = llvm.mlir.addressof @CACHE_CAP : !llvm.ptr
%67 = llvm.load %66 : !llvm.ptr -> i32
%68 = arith.extsi %67 : i32 to i64
%69 = arith.constant 24 : i32
%70 = arith.extsi %69 : i32 to i64
%65 = func.call @calloc(%68, %70) : (i64, i64) -> !llvm.ptr
%71 = llvm.mlir.addressof @g_cache : !llvm.ptr
llvm.store %65, %71 : !llvm.ptr, !llvm.ptr
func.return
}
func.func @cache_hash(%arg0: i64) -> i32 {
%72 = arith.constant 1095216660915 : i32
%74 = arith.extsi %72 : i32 to i64
%73 = arith.muli %arg0, %74 : i64
%75 = llvm.mlir.addressof @CACHE_CAP : !llvm.ptr
%76 = llvm.load %75 : !llvm.ptr -> i32
%77 = arith.extsi %76 : i32 to i64
%78 = arith.constant 1 : i32
%80 = arith.extsi %78 : i32 to i64
%79 = arith.subi %77, %80 : i64
%81 = arith.andi %73, %79 : i64
%82 = arith.trunci %81 : i64 to i32
func.return %82 : i32
}
func.func @cache_find(%arg0: i64) -> i32 {
%83 = func.call @cache_hash(%arg0) : (i64) -> i32
%84 = llvm.mlir.constant(1 : i64) : i64
%85 = llvm.alloca %84 x i32 : (i64) -> !llvm.ptr
llvm.store %83, %85 : i32, !llvm.ptr
cf.br ^bb3
^bb3:
%87 = llvm.mlir.addressof @g_cache : !llvm.ptr
%88 = llvm.load %87 : !llvm.ptr -> !llvm.ptr
%89 = llvm.load %85 : !llvm.ptr -> i32
%90 = arith.extsi %89 : i32 to i64
%91 = llvm.getelementptr %88[%90] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%86 = llvm.load %91 : !llvm.ptr -> !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%92 = llvm.mlir.addressof @g_cache : !llvm.ptr
%93 = llvm.load %92 : !llvm.ptr -> !llvm.ptr
%94 = llvm.load %85 : !llvm.ptr -> i32
%95 = arith.extsi %94 : i32 to i64
%96 = llvm.getelementptr %93[%95] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%97 = llvm.getelementptr %96[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%98 = llvm.load %97 : !llvm.ptr -> i32
%99 = arith.constant 0 : i32
%100 = arith.cmpi ne, %98, %99 : i32
cf.cond_br %100, ^bb4, ^bb5
^bb4:
%102 = llvm.mlir.addressof @g_cache : !llvm.ptr
%103 = llvm.load %102 : !llvm.ptr -> !llvm.ptr
%104 = llvm.load %85 : !llvm.ptr -> i32
%105 = arith.extsi %104 : i32 to i64
%106 = llvm.getelementptr %103[%105] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%101 = llvm.load %106 : !llvm.ptr -> !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%107 = llvm.mlir.addressof @g_cache : !llvm.ptr
%108 = llvm.load %107 : !llvm.ptr -> !llvm.ptr
%109 = llvm.load %85 : !llvm.ptr -> i32
%110 = arith.extsi %109 : i32 to i64
%111 = llvm.getelementptr %108[%110] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%112 = llvm.getelementptr %111[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%113 = llvm.load %112 : !llvm.ptr -> i64
%114 = arith.cmpi eq, %113, %arg0 : i64
cf.cond_br %114, ^bb6, ^bb7
^bb6:
%115 = llvm.load %85 : !llvm.ptr -> i32
func.return %115 : i32
^bb7:
cf.br ^bb8
^bb8:
%116 = llvm.load %85 : !llvm.ptr -> i32
%117 = arith.constant 1 : i32
%118 = arith.addi %116, %117 : i32
%119 = llvm.mlir.addressof @CACHE_CAP : !llvm.ptr
%120 = llvm.load %119 : !llvm.ptr -> i32
%121 = arith.constant 1 : i32
%122 = arith.subi %120, %121 : i32
%123 = arith.andi %118, %122 : i32
llvm.store %123, %85 : i32, !llvm.ptr
cf.br ^bb3
^bb5:
%124 = arith.constant 1 : i32
%126 = arith.constant 0 : i32
%125 = arith.subi %126, %124 : i32
func.return %125 : i32
}
func.func @cache_insert(%arg0: i64) -> i32 {
%127 = func.call @cache_hash(%arg0) : (i64) -> i32
%128 = llvm.mlir.constant(1 : i64) : i64
%129 = llvm.alloca %128 x i32 : (i64) -> !llvm.ptr
llvm.store %127, %129 : i32, !llvm.ptr
cf.br ^bb9
^bb9:
%131 = llvm.mlir.addressof @g_cache : !llvm.ptr
%132 = llvm.load %131 : !llvm.ptr -> !llvm.ptr
%133 = llvm.load %129 : !llvm.ptr -> i32
%134 = arith.extsi %133 : i32 to i64
%135 = llvm.getelementptr %132[%134] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%130 = llvm.load %135 : !llvm.ptr -> !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%136 = llvm.mlir.addressof @g_cache : !llvm.ptr
%137 = llvm.load %136 : !llvm.ptr -> !llvm.ptr
%138 = llvm.load %129 : !llvm.ptr -> i32
%139 = arith.extsi %138 : i32 to i64
%140 = llvm.getelementptr %137[%139] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%141 = llvm.getelementptr %140[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%142 = llvm.load %141 : !llvm.ptr -> i32
%143 = arith.constant 0 : i32
%144 = arith.cmpi ne, %142, %143 : i32
cf.cond_br %144, ^bb10, ^bb11
^bb10:
%146 = llvm.mlir.addressof @g_cache : !llvm.ptr
%147 = llvm.load %146 : !llvm.ptr -> !llvm.ptr
%148 = llvm.load %129 : !llvm.ptr -> i32
%149 = arith.extsi %148 : i32 to i64
%150 = llvm.getelementptr %147[%149] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%145 = llvm.load %150 : !llvm.ptr -> !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%151 = llvm.mlir.addressof @g_cache : !llvm.ptr
%152 = llvm.load %151 : !llvm.ptr -> !llvm.ptr
%153 = llvm.load %129 : !llvm.ptr -> i32
%154 = arith.extsi %153 : i32 to i64
%155 = llvm.getelementptr %152[%154] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%156 = llvm.getelementptr %155[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%157 = llvm.load %156 : !llvm.ptr -> i64
%158 = arith.cmpi eq, %157, %arg0 : i64
cf.cond_br %158, ^bb12, ^bb13
^bb12:
%159 = llvm.load %129 : !llvm.ptr -> i32
func.return %159 : i32
^bb13:
cf.br ^bb14
^bb14:
%160 = llvm.load %129 : !llvm.ptr -> i32
%161 = arith.constant 1 : i32
%162 = arith.addi %160, %161 : i32
%163 = llvm.mlir.addressof @CACHE_CAP : !llvm.ptr
%164 = llvm.load %163 : !llvm.ptr -> i32
%165 = arith.constant 1 : i32
%166 = arith.subi %164, %165 : i32
%167 = arith.andi %162, %166 : i32
llvm.store %167, %129 : i32, !llvm.ptr
cf.br ^bb9
^bb11:
%168 = arith.constant 1 : i32
%169 = llvm.mlir.addressof @g_cache : !llvm.ptr
%170 = llvm.load %169 : !llvm.ptr -> !llvm.ptr
%171 = llvm.load %129 : !llvm.ptr -> i32
%172 = arith.extsi %171 : i32 to i64
%173 = llvm.getelementptr %170[%172] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%174 = llvm.getelementptr %173[0, 3] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
llvm.store %168, %174 : i32, !llvm.ptr
%175 = llvm.mlir.addressof @g_cache : !llvm.ptr
%176 = llvm.load %175 : !llvm.ptr -> !llvm.ptr
%177 = llvm.load %129 : !llvm.ptr -> i32
%178 = arith.extsi %177 : i32 to i64
%179 = llvm.getelementptr %176[%178] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%180 = llvm.getelementptr %179[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
llvm.store %arg0, %180 : i64, !llvm.ptr
%181 = llvm.mlir.zero : !llvm.ptr
%182 = llvm.mlir.addressof @g_cache : !llvm.ptr
%183 = llvm.load %182 : !llvm.ptr -> !llvm.ptr
%184 = llvm.load %129 : !llvm.ptr -> i32
%185 = arith.extsi %184 : i32 to i64
%186 = llvm.getelementptr %183[%185] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%187 = llvm.getelementptr %186[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
llvm.store %181, %187 : !llvm.ptr, !llvm.ptr
%188 = arith.constant 0 : i32
%189 = llvm.mlir.addressof @g_cache : !llvm.ptr
%190 = llvm.load %189 : !llvm.ptr -> !llvm.ptr
%191 = llvm.load %129 : !llvm.ptr -> i32
%192 = arith.extsi %191 : i32 to i64
%193 = llvm.getelementptr %190[%192] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%194 = llvm.getelementptr %193[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
llvm.store %188, %194 : i32, !llvm.ptr
%195 = llvm.load %129 : !llvm.ptr -> i32
func.return %195 : i32
}
func.func @encode_key(%arg0: !llvm.ptr, %arg1: i32) -> i64 {
%197 = arith.constant 24 : i32
%198 = arith.extsi %197 : i32 to i64
%196 = func.call @malloc(%198) : (i64) -> !llvm.ptr
%199 = arith.constant 0 : i32
%200 = llvm.mlir.constant(1 : i64) : i64
%201 = llvm.alloca %200 x i32 : (i64) -> !llvm.ptr
llvm.store %199, %201 : i32, !llvm.ptr
cf.br ^bb15
^bb15:
%202 = llvm.load %201 : !llvm.ptr -> i32
%203 = arith.cmpi slt, %202, %arg1 : i32
cf.cond_br %203, ^bb16, ^bb17
^bb16:
%205 = llvm.load %201 : !llvm.ptr -> i32
%206 = arith.extsi %205 : i32 to i64
%207 = llvm.getelementptr %arg0[%206] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%204 = llvm.load %207 : !llvm.ptr -> i32
%208 = llvm.load %201 : !llvm.ptr -> i32
%209 = arith.extsi %208 : i32 to i64
%210 = llvm.getelementptr %196[%209] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %204, %210 : i32, !llvm.ptr
%211 = llvm.load %201 : !llvm.ptr -> i32
%212 = arith.constant 1 : i32
%213 = arith.addi %211, %212 : i32
llvm.store %213, %201 : i32, !llvm.ptr
cf.br ^bb15
^bb17:
%214 = arith.constant 1 : i32
%215 = llvm.mlir.constant(1 : i64) : i64
%216 = llvm.alloca %215 x i32 : (i64) -> !llvm.ptr
llvm.store %214, %216 : i32, !llvm.ptr
cf.br ^bb18
^bb18:
%217 = llvm.load %216 : !llvm.ptr -> i32
%218 = arith.cmpi slt, %217, %arg1 : i32
cf.cond_br %218, ^bb19, ^bb20
^bb19:
%220 = llvm.load %216 : !llvm.ptr -> i32
%221 = arith.extsi %220 : i32 to i64
%222 = llvm.getelementptr %196[%221] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%219 = llvm.load %222 : !llvm.ptr -> i32
%223 = llvm.load %216 : !llvm.ptr -> i32
%224 = arith.constant 1 : i32
%225 = arith.subi %223, %224 : i32
%226 = llvm.mlir.constant(1 : i64) : i64
%227 = llvm.alloca %226 x i32 : (i64) -> !llvm.ptr
llvm.store %225, %227 : i32, !llvm.ptr
cf.br ^bb21
^bb21:
%228 = llvm.load %227 : !llvm.ptr -> i32
%229 = arith.constant 0 : i32
%230 = arith.cmpi sge, %228, %229 : i32
cf.cond_br %230, ^bb22, ^bb23
^bb22:
%232 = llvm.load %227 : !llvm.ptr -> i32
%233 = arith.extsi %232 : i32 to i64
%234 = llvm.getelementptr %196[%233] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%231 = llvm.load %234 : !llvm.ptr -> i32
%235 = arith.cmpi sgt, %231, %219 : i32
cf.cond_br %235, ^bb24, ^bb25
^bb24:
%237 = llvm.load %227 : !llvm.ptr -> i32
%238 = arith.extsi %237 : i32 to i64
%239 = llvm.getelementptr %196[%238] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%236 = llvm.load %239 : !llvm.ptr -> i32
%240 = llvm.load %227 : !llvm.ptr -> i32
%241 = arith.constant 1 : i32
%242 = arith.addi %240, %241 : i32
%243 = arith.extsi %242 : i32 to i64
%244 = llvm.getelementptr %196[%243] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %236, %244 : i32, !llvm.ptr
%245 = llvm.load %227 : !llvm.ptr -> i32
%246 = arith.constant 1 : i32
%247 = arith.subi %245, %246 : i32
llvm.store %247, %227 : i32, !llvm.ptr
cf.br ^bb26
^bb25:
cf.br ^bb23
^bb26:
cf.br ^bb21
^bb23:
%248 = llvm.load %227 : !llvm.ptr -> i32
%249 = arith.constant 1 : i32
%250 = arith.addi %248, %249 : i32
%251 = arith.extsi %250 : i32 to i64
%252 = llvm.getelementptr %196[%251] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %219, %252 : i32, !llvm.ptr
%253 = llvm.load %216 : !llvm.ptr -> i32
%254 = arith.constant 1 : i32
%255 = arith.addi %253, %254 : i32
llvm.store %255, %216 : i32, !llvm.ptr
cf.br ^bb18
^bb20:
%256 = arith.constant 0 : i32
%257 = arith.extsi %256 : i32 to i64
%258 = llvm.mlir.constant(1 : i64) : i64
%259 = llvm.alloca %258 x i64 : (i64) -> !llvm.ptr
llvm.store %257, %259 : i64, !llvm.ptr
%260 = arith.constant 0 : i32
%261 = llvm.mlir.constant(1 : i64) : i64
%262 = llvm.alloca %261 x i32 : (i64) -> !llvm.ptr
llvm.store %260, %262 : i32, !llvm.ptr
cf.br ^bb27
^bb27:
%263 = llvm.load %262 : !llvm.ptr -> i32
%264 = arith.cmpi slt, %263, %arg1 : i32
cf.cond_br %264, ^bb28, ^bb29
^bb28:
%265 = llvm.load %259 : !llvm.ptr -> i64
%266 = arith.constant 201 : i32
%268 = arith.extsi %266 : i32 to i64
%267 = arith.muli %265, %268 : i64
%270 = llvm.load %262 : !llvm.ptr -> i32
%271 = arith.extsi %270 : i32 to i64
%272 = llvm.getelementptr %196[%271] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%269 = llvm.load %272 : !llvm.ptr -> i32
%273 = arith.constant 1 : i32
%274 = arith.addi %269, %273 : i32
%275 = arith.extsi %274 : i32 to i64
%276 = arith.addi %267, %275 : i64
llvm.store %276, %259 : i64, !llvm.ptr
%277 = llvm.load %262 : !llvm.ptr -> i32
%278 = arith.constant 1 : i32
%279 = arith.addi %277, %278 : i32
llvm.store %279, %262 : i32, !llvm.ptr
cf.br ^bb27
^bb29:
func.call @free(%196) : (!llvm.ptr) -> ()
%281 = llvm.load %259 : !llvm.ptr -> i64
func.return %281 : i64
}
func.func @sort_i32(%arg0: !llvm.ptr, %arg1: i32) -> () {
%282 = arith.constant 1 : i32
%283 = llvm.mlir.constant(1 : i64) : i64
%284 = llvm.alloca %283 x i32 : (i64) -> !llvm.ptr
llvm.store %282, %284 : i32, !llvm.ptr
cf.br ^bb30
^bb30:
%285 = llvm.load %284 : !llvm.ptr -> i32
%286 = arith.cmpi slt, %285, %arg1 : i32
cf.cond_br %286, ^bb31, ^bb32
^bb31:
%288 = llvm.load %284 : !llvm.ptr -> i32
%289 = arith.extsi %288 : i32 to i64
%290 = llvm.getelementptr %arg0[%289] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%287 = llvm.load %290 : !llvm.ptr -> i32
%291 = llvm.load %284 : !llvm.ptr -> i32
%292 = arith.constant 1 : i32
%293 = arith.subi %291, %292 : i32
%294 = llvm.mlir.constant(1 : i64) : i64
%295 = llvm.alloca %294 x i32 : (i64) -> !llvm.ptr
llvm.store %293, %295 : i32, !llvm.ptr
cf.br ^bb33
^bb33:
%296 = llvm.load %295 : !llvm.ptr -> i32
%297 = arith.constant 0 : i32
%298 = arith.cmpi sge, %296, %297 : i32
cf.cond_br %298, ^bb34, ^bb35
^bb34:
%300 = llvm.load %295 : !llvm.ptr -> i32
%301 = arith.extsi %300 : i32 to i64
%302 = llvm.getelementptr %arg0[%301] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%299 = llvm.load %302 : !llvm.ptr -> i32
%303 = arith.cmpi sgt, %299, %287 : i32
cf.cond_br %303, ^bb36, ^bb37
^bb36:
%305 = llvm.load %295 : !llvm.ptr -> i32
%306 = arith.extsi %305 : i32 to i64
%307 = llvm.getelementptr %arg0[%306] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%304 = llvm.load %307 : !llvm.ptr -> i32
%308 = llvm.load %295 : !llvm.ptr -> i32
%309 = arith.constant 1 : i32
%310 = arith.addi %308, %309 : i32
%311 = arith.extsi %310 : i32 to i64
%312 = llvm.getelementptr %arg0[%311] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %304, %312 : i32, !llvm.ptr
%313 = llvm.load %295 : !llvm.ptr -> i32
%314 = arith.constant 1 : i32
%315 = arith.subi %313, %314 : i32
llvm.store %315, %295 : i32, !llvm.ptr
cf.br ^bb38
^bb37:
cf.br ^bb35
^bb38:
cf.br ^bb33
^bb35:
%316 = llvm.load %295 : !llvm.ptr -> i32
%317 = arith.constant 1 : i32
%318 = arith.addi %316, %317 : i32
%319 = arith.extsi %318 : i32 to i64
%320 = llvm.getelementptr %arg0[%319] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %287, %320 : i32, !llvm.ptr
%321 = llvm.load %284 : !llvm.ptr -> i32
%322 = arith.constant 1 : i32
%323 = arith.addi %321, %322 : i32
llvm.store %323, %284 : i32, !llvm.ptr
cf.br ^bb30
^bb32:
func.return
}
func.func @dedup_sorted(%arg0: !llvm.ptr, %arg1: i32) -> i32 {
%324 = arith.constant 1 : i32
%325 = arith.cmpi sle, %arg1, %324 : i32
cf.cond_br %325, ^bb39, ^bb40
^bb39:
func.return %arg1 : i32
^bb40:
cf.br ^bb41
^bb41:
%326 = arith.constant 1 : i32
%327 = llvm.mlir.constant(1 : i64) : i64
%328 = llvm.alloca %327 x i32 : (i64) -> !llvm.ptr
llvm.store %326, %328 : i32, !llvm.ptr
%329 = arith.constant 1 : i32
%330 = llvm.mlir.constant(1 : i64) : i64
%331 = llvm.alloca %330 x i32 : (i64) -> !llvm.ptr
llvm.store %329, %331 : i32, !llvm.ptr
cf.br ^bb42
^bb42:
%332 = llvm.load %331 : !llvm.ptr -> i32
%333 = arith.cmpi slt, %332, %arg1 : i32
cf.cond_br %333, ^bb43, ^bb44
^bb43:
%335 = llvm.load %331 : !llvm.ptr -> i32
%336 = arith.extsi %335 : i32 to i64
%337 = llvm.getelementptr %arg0[%336] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%334 = llvm.load %337 : !llvm.ptr -> i32
%339 = llvm.load %331 : !llvm.ptr -> i32
%340 = arith.constant 1 : i32
%341 = arith.subi %339, %340 : i32
%342 = arith.extsi %341 : i32 to i64
%343 = llvm.getelementptr %arg0[%342] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%338 = llvm.load %343 : !llvm.ptr -> i32
%344 = arith.cmpi ne, %334, %338 : i32
cf.cond_br %344, ^bb45, ^bb46
^bb45:
%346 = llvm.load %331 : !llvm.ptr -> i32
%347 = arith.extsi %346 : i32 to i64
%348 = llvm.getelementptr %arg0[%347] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%345 = llvm.load %348 : !llvm.ptr -> i32
%349 = llvm.load %328 : !llvm.ptr -> i32
%350 = arith.extsi %349 : i32 to i64
%351 = llvm.getelementptr %arg0[%350] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %345, %351 : i32, !llvm.ptr
%352 = llvm.load %328 : !llvm.ptr -> i32
%353 = arith.constant 1 : i32
%354 = arith.addi %352, %353 : i32
llvm.store %354, %328 : i32, !llvm.ptr
cf.br ^bb47
^bb46:
cf.br ^bb47
^bb47:
%355 = llvm.load %331 : !llvm.ptr -> i32
%356 = arith.constant 1 : i32
%357 = arith.addi %355, %356 : i32
llvm.store %357, %331 : i32, !llvm.ptr
cf.br ^bb42
^bb44:
%358 = llvm.load %328 : !llvm.ptr -> i32
func.return %358 : i32
}
func.func @generate_values(%arg0: !llvm.ptr, %arg1: i32) -> () {
%359 = func.call @encode_key(%arg0, %arg1) : (!llvm.ptr, i32) -> i64
%360 = func.call @cache_find(%359) : (i64) -> i32
%361 = arith.constant 0 : i32
%362 = arith.cmpi sge, %360, %361 : i32
cf.cond_br %362, ^bb48, ^bb49
^bb48:
%363 = arith.constant 0 : i32
%364 = llvm.mlir.constant(1 : i64) : i64
%365 = llvm.alloca %364 x i32 : (i64) -> !llvm.ptr
llvm.store %363, %365 : i32, !llvm.ptr
cf.br ^bb51
^bb51:
%366 = llvm.load %365 : !llvm.ptr -> i32
%368 = llvm.mlir.addressof @g_cache : !llvm.ptr
%369 = llvm.load %368 : !llvm.ptr -> !llvm.ptr
%370 = arith.extsi %360 : i32 to i64
%371 = llvm.getelementptr %369[%370] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%367 = llvm.load %371 : !llvm.ptr -> !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%372 = llvm.mlir.addressof @g_cache : !llvm.ptr
%373 = llvm.load %372 : !llvm.ptr -> !llvm.ptr
%374 = arith.extsi %360 : i32 to i64
%375 = llvm.getelementptr %373[%374] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%376 = llvm.getelementptr %375[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%377 = llvm.load %376 : !llvm.ptr -> i32
%378 = arith.cmpi slt, %366, %377 : i32
cf.cond_br %378, ^bb52, ^bb53
^bb52:
%382 = llvm.mlir.addressof @g_cache : !llvm.ptr
%383 = llvm.load %382 : !llvm.ptr -> !llvm.ptr
%384 = arith.extsi %360 : i32 to i64
%385 = llvm.getelementptr %383[%384] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%381 = llvm.load %385 : !llvm.ptr -> !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%386 = llvm.mlir.addressof @g_cache : !llvm.ptr
%387 = llvm.load %386 : !llvm.ptr -> !llvm.ptr
%388 = arith.extsi %360 : i32 to i64
%389 = llvm.getelementptr %387[%388] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%390 = llvm.getelementptr %389[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%391 = llvm.load %390 : !llvm.ptr -> !llvm.ptr
%392 = llvm.load %365 : !llvm.ptr -> i32
%393 = arith.extsi %392 : i32 to i64
%394 = llvm.getelementptr %391[%393] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%380 = llvm.load %394 : !llvm.ptr -> i32
func.call @da_add(%380) : (i32) -> ()
%395 = llvm.load %365 : !llvm.ptr -> i32
%396 = arith.constant 1 : i32
%397 = arith.addi %395, %396 : i32
llvm.store %397, %365 : i32, !llvm.ptr
cf.br ^bb51
^bb53:
func.return
^bb49:
cf.br ^bb50
^bb50:
%398 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%399 = llvm.load %398 : !llvm.ptr -> !llvm.ptr
%400 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%401 = llvm.load %400 : !llvm.ptr -> i32
%402 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
%403 = llvm.load %402 : !llvm.ptr -> i32
func.call @da_init() : () -> ()
%405 = arith.constant 1 : i32
%406 = arith.cmpi eq, %arg1, %405 : i32
cf.cond_br %406, ^bb54, ^bb55
^bb54:
%409 = arith.constant 0 : i32
%410 = arith.extsi %409 : i32 to i64
%411 = llvm.getelementptr %arg0[%410] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%408 = llvm.load %411 : !llvm.ptr -> i32
func.call @da_add(%408) : (i32) -> ()
cf.br ^bb56
^bb55:
%412 = arith.constant 1 : i32
%413 = arith.shli %412, %arg1 : i32
%414 = arith.constant 1 : i32
%415 = llvm.mlir.constant(1 : i64) : i64
%416 = llvm.alloca %415 x i32 : (i64) -> !llvm.ptr
llvm.store %414, %416 : i32, !llvm.ptr
cf.br ^bb57
^bb57:
%417 = llvm.load %416 : !llvm.ptr -> i32
%418 = arith.constant 1 : i32
%419 = arith.subi %413, %418 : i32
%420 = arith.cmpi slt, %417, %419 : i32
cf.cond_br %420, ^bb58, ^bb59
^bb58:
%421 = llvm.load %416 : !llvm.ptr -> i32
%423 = arith.constant -1 : i32
%422 = arith.xori %421, %423 : i32
%424 = arith.constant 1 : i32
%425 = arith.subi %413, %424 : i32
%426 = arith.andi %422, %425 : i32
%427 = llvm.load %416 : !llvm.ptr -> i32
%428 = arith.cmpi sgt, %427, %426 : i32
cf.cond_br %428, ^bb60, ^bb61
^bb60:
%429 = llvm.load %416 : !llvm.ptr -> i32
%430 = arith.constant 1 : i32
%431 = arith.addi %429, %430 : i32
llvm.store %431, %416 : i32, !llvm.ptr
cf.br ^bb57
^bb61:
cf.br ^bb62
^bb62:
%433 = arith.constant 24 : i32
%434 = arith.extsi %433 : i32 to i64
%432 = func.call @malloc(%434) : (i64) -> !llvm.ptr
%436 = arith.constant 24 : i32
%437 = arith.extsi %436 : i32 to i64
%435 = func.call @malloc(%437) : (i64) -> !llvm.ptr
%438 = arith.constant 0 : i32
%439 = llvm.mlir.constant(1 : i64) : i64
%440 = llvm.alloca %439 x i32 : (i64) -> !llvm.ptr
llvm.store %438, %440 : i32, !llvm.ptr
%441 = arith.constant 0 : i32
%442 = llvm.mlir.constant(1 : i64) : i64
%443 = llvm.alloca %442 x i32 : (i64) -> !llvm.ptr
llvm.store %441, %443 : i32, !llvm.ptr
%444 = arith.constant 0 : i32
%445 = llvm.mlir.constant(1 : i64) : i64
%446 = llvm.alloca %445 x i32 : (i64) -> !llvm.ptr
llvm.store %444, %446 : i32, !llvm.ptr
cf.br ^bb63
^bb63:
%447 = llvm.load %446 : !llvm.ptr -> i32
%448 = arith.cmpi slt, %447, %arg1 : i32
cf.cond_br %448, ^bb64, ^bb65
^bb64:
%449 = llvm.load %416 : !llvm.ptr -> i32
%450 = arith.constant 1 : i32
%451 = llvm.load %446 : !llvm.ptr -> i32
%452 = arith.shli %450, %451 : i32
%453 = arith.andi %449, %452 : i32
%454 = arith.constant 0 : i32
%455 = arith.cmpi ne, %453, %454 : i32
cf.cond_br %455, ^bb66, ^bb67
^bb66:
%457 = llvm.load %446 : !llvm.ptr -> i32
%458 = arith.extsi %457 : i32 to i64
%459 = llvm.getelementptr %arg0[%458] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%456 = llvm.load %459 : !llvm.ptr -> i32
%460 = llvm.load %440 : !llvm.ptr -> i32
%461 = arith.extsi %460 : i32 to i64
%462 = llvm.getelementptr %432[%461] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %456, %462 : i32, !llvm.ptr
%463 = llvm.load %440 : !llvm.ptr -> i32
%464 = arith.constant 1 : i32
%465 = arith.addi %463, %464 : i32
llvm.store %465, %440 : i32, !llvm.ptr
cf.br ^bb68
^bb67:
%467 = llvm.load %446 : !llvm.ptr -> i32
%468 = arith.extsi %467 : i32 to i64
%469 = llvm.getelementptr %arg0[%468] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%466 = llvm.load %469 : !llvm.ptr -> i32
%470 = llvm.load %443 : !llvm.ptr -> i32
%471 = arith.extsi %470 : i32 to i64
%472 = llvm.getelementptr %435[%471] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %466, %472 : i32, !llvm.ptr
%473 = llvm.load %443 : !llvm.ptr -> i32
%474 = arith.constant 1 : i32
%475 = arith.addi %473, %474 : i32
llvm.store %475, %443 : i32, !llvm.ptr
cf.br ^bb68
^bb68:
%476 = llvm.load %446 : !llvm.ptr -> i32
%477 = arith.constant 1 : i32
%478 = arith.addi %476, %477 : i32
llvm.store %478, %446 : i32, !llvm.ptr
cf.br ^bb63
^bb65:
%479 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%480 = llvm.load %479 : !llvm.ptr -> !llvm.ptr
%481 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%482 = llvm.load %481 : !llvm.ptr -> i32
%483 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
%484 = llvm.load %483 : !llvm.ptr -> i32
func.call @da_init() : () -> ()
%487 = llvm.load %440 : !llvm.ptr -> i32
func.call @generate_values(%432, %487) : (!llvm.ptr, i32) -> ()
%488 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%489 = llvm.load %488 : !llvm.ptr -> !llvm.ptr
%490 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%491 = llvm.load %490 : !llvm.ptr -> i32
%492 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
llvm.store %480, %492 : !llvm.ptr, !llvm.ptr
%493 = llvm.mlir.addressof @g_da_count : !llvm.ptr
llvm.store %482, %493 : i32, !llvm.ptr
%494 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
llvm.store %484, %494 : i32, !llvm.ptr
%495 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%496 = llvm.load %495 : !llvm.ptr -> !llvm.ptr
%497 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%498 = llvm.load %497 : !llvm.ptr -> i32
%499 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
%500 = llvm.load %499 : !llvm.ptr -> i32
func.call @da_init() : () -> ()
%503 = llvm.load %443 : !llvm.ptr -> i32
func.call @generate_values(%435, %503) : (!llvm.ptr, i32) -> ()
%504 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%505 = llvm.load %504 : !llvm.ptr -> !llvm.ptr
%506 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%507 = llvm.load %506 : !llvm.ptr -> i32
%508 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
llvm.store %496, %508 : !llvm.ptr, !llvm.ptr
%509 = llvm.mlir.addressof @g_da_count : !llvm.ptr
llvm.store %498, %509 : i32, !llvm.ptr
%510 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
llvm.store %500, %510 : i32, !llvm.ptr
%511 = arith.constant 0 : i32
%512 = llvm.mlir.constant(1 : i64) : i64
%513 = llvm.alloca %512 x i32 : (i64) -> !llvm.ptr
llvm.store %511, %513 : i32, !llvm.ptr
cf.br ^bb69
^bb69:
%514 = llvm.load %513 : !llvm.ptr -> i32
%515 = arith.cmpi slt, %514, %491 : i32
cf.cond_br %515, ^bb70, ^bb71
^bb70:
%516 = arith.constant 0 : i32
%517 = llvm.mlir.constant(1 : i64) : i64
%518 = llvm.alloca %517 x i32 : (i64) -> !llvm.ptr
llvm.store %516, %518 : i32, !llvm.ptr
cf.br ^bb72
^bb72:
%519 = llvm.load %518 : !llvm.ptr -> i32
%520 = arith.cmpi slt, %519, %507 : i32
cf.cond_br %520, ^bb73, ^bb74
^bb73:
%522 = llvm.load %513 : !llvm.ptr -> i32
%523 = arith.extsi %522 : i32 to i64
%524 = llvm.getelementptr %489[%523] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%521 = llvm.load %524 : !llvm.ptr -> i32
%526 = llvm.load %518 : !llvm.ptr -> i32
%527 = arith.extsi %526 : i32 to i64
%528 = llvm.getelementptr %505[%527] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%525 = llvm.load %528 : !llvm.ptr -> i32
%530 = arith.addi %521, %525 : i32
func.call @da_add(%530) : (i32) -> ()
%532 = arith.muli %521, %525 : i32
func.call @da_add(%532) : (i32) -> ()
%533 = arith.cmpi sgt, %521, %525 : i32
cf.cond_br %533, ^bb75, ^bb76
^bb75:
%535 = arith.subi %521, %525 : i32
func.call @da_add(%535) : (i32) -> ()
cf.br ^bb77
^bb76:
cf.br ^bb77
^bb77:
%536 = arith.cmpi sgt, %525, %521 : i32
cf.cond_br %536, ^bb78, ^bb79
^bb78:
%538 = arith.subi %525, %521 : i32
func.call @da_add(%538) : (i32) -> ()
cf.br ^bb80
^bb79:
cf.br ^bb80
^bb80:
%539 = arith.constant 0 : i32
%540 = arith.cmpi sgt, %525, %539 : i32
%541 = scf.if %540 -> (i1) {
%542 = arith.remsi %521, %525 : i32
%543 = arith.constant 0 : i32
%544 = arith.cmpi eq, %542, %543 : i32
scf.yield %544 : i1
} else {
%545 = arith.constant false
scf.yield %545 : i1
}
cf.cond_br %541, ^bb81, ^bb82
^bb81:
%547 = arith.divsi %521, %525 : i32
func.call @da_add(%547) : (i32) -> ()
cf.br ^bb83
^bb82:
cf.br ^bb83
^bb83:
%548 = arith.constant 0 : i32
%549 = arith.cmpi sgt, %521, %548 : i32
%550 = scf.if %549 -> (i1) {
%551 = arith.remsi %525, %521 : i32
%552 = arith.constant 0 : i32
%553 = arith.cmpi eq, %551, %552 : i32
scf.yield %553 : i1
} else {
%554 = arith.constant false
scf.yield %554 : i1
}
cf.cond_br %550, ^bb84, ^bb85
^bb84:
%556 = arith.divsi %525, %521 : i32
func.call @da_add(%556) : (i32) -> ()
cf.br ^bb86
^bb85:
cf.br ^bb86
^bb86:
%557 = llvm.load %518 : !llvm.ptr -> i32
%558 = arith.constant 1 : i32
%559 = arith.addi %557, %558 : i32
llvm.store %559, %518 : i32, !llvm.ptr
cf.br ^bb72
^bb74:
%560 = llvm.load %513 : !llvm.ptr -> i32
%561 = arith.constant 1 : i32
%562 = arith.addi %560, %561 : i32
llvm.store %562, %513 : i32, !llvm.ptr
cf.br ^bb69
^bb71:
func.call @free(%489) : (!llvm.ptr) -> ()
func.call @free(%505) : (!llvm.ptr) -> ()
func.call @free(%432) : (!llvm.ptr) -> ()
func.call @free(%435) : (!llvm.ptr) -> ()
%567 = llvm.load %416 : !llvm.ptr -> i32
%568 = arith.constant 1 : i32
%569 = arith.addi %567, %568 : i32
llvm.store %569, %416 : i32, !llvm.ptr
cf.br ^bb57
^bb59:
cf.br ^bb56
^bb56:
%571 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%572 = llvm.load %571 : !llvm.ptr -> !llvm.ptr
%573 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%574 = llvm.load %573 : !llvm.ptr -> i32
func.call @sort_i32(%572, %574) : (!llvm.ptr, i32) -> ()
%576 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%577 = llvm.load %576 : !llvm.ptr -> !llvm.ptr
%578 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%579 = llvm.load %578 : !llvm.ptr -> i32
%575 = func.call @dedup_sorted(%577, %579) : (!llvm.ptr, i32) -> i32
%580 = llvm.mlir.addressof @g_da_count : !llvm.ptr
llvm.store %575, %580 : i32, !llvm.ptr
%581 = func.call @cache_insert(%359) : (i64) -> i32
%583 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%584 = llvm.load %583 : !llvm.ptr -> i32
%585 = arith.extsi %584 : i32 to i64
%586 = arith.constant 4 : i32
%588 = arith.extsi %586 : i32 to i64
%587 = arith.muli %585, %588 : i64
%582 = func.call @malloc(%587) : (i64) -> !llvm.ptr
%590 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%591 = llvm.load %590 : !llvm.ptr -> !llvm.ptr
%592 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%593 = llvm.load %592 : !llvm.ptr -> i32
%594 = arith.extsi %593 : i32 to i64
%595 = arith.constant 4 : i32
%597 = arith.extsi %595 : i32 to i64
%596 = arith.muli %594, %597 : i64
%589 = func.call @memcpy(%582, %591, %596) : (!llvm.ptr, !llvm.ptr, i64) -> !llvm.ptr
%598 = llvm.mlir.addressof @g_cache : !llvm.ptr
%599 = llvm.load %598 : !llvm.ptr -> !llvm.ptr
%600 = arith.extsi %581 : i32 to i64
%601 = llvm.getelementptr %599[%600] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%602 = llvm.getelementptr %601[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
llvm.store %582, %602 : !llvm.ptr, !llvm.ptr
%603 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%604 = llvm.load %603 : !llvm.ptr -> i32
%605 = llvm.mlir.addressof @g_cache : !llvm.ptr
%606 = llvm.load %605 : !llvm.ptr -> !llvm.ptr
%607 = arith.extsi %581 : i32 to i64
%608 = llvm.getelementptr %606[%607] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
%609 = llvm.getelementptr %608[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i64, !llvm.ptr, i32, i32)>
llvm.store %604, %609 : i32, !llvm.ptr
%610 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%611 = llvm.load %610 : !llvm.ptr -> !llvm.ptr
%612 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%613 = llvm.load %612 : !llvm.ptr -> i32
%614 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
llvm.store %399, %614 : !llvm.ptr, !llvm.ptr
%615 = llvm.mlir.addressof @g_da_count : !llvm.ptr
llvm.store %401, %615 : i32, !llvm.ptr
%616 = llvm.mlir.addressof @g_da_cap : !llvm.ptr
llvm.store %403, %616 : i32, !llvm.ptr
%617 = arith.constant 0 : i32
%618 = llvm.mlir.constant(1 : i64) : i64
%619 = llvm.alloca %618 x i32 : (i64) -> !llvm.ptr
llvm.store %617, %619 : i32, !llvm.ptr
cf.br ^bb87
^bb87:
%620 = llvm.load %619 : !llvm.ptr -> i32
%621 = arith.cmpi slt, %620, %613 : i32
cf.cond_br %621, ^bb88, ^bb89
^bb88:
%624 = llvm.load %619 : !llvm.ptr -> i32
%625 = arith.extsi %624 : i32 to i64
%626 = llvm.getelementptr %611[%625] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%623 = llvm.load %626 : !llvm.ptr -> i32
func.call @da_add(%623) : (i32) -> ()
%627 = llvm.load %619 : !llvm.ptr -> i32
%628 = arith.constant 1 : i32
%629 = arith.addi %627, %628 : i32
llvm.store %629, %619 : i32, !llvm.ptr
cf.br ^bb87
^bb89:
func.call @free(%611) : (!llvm.ptr) -> ()
func.return
}
func.func @min_score(%arg0: i32, %arg1: !llvm.ptr, %arg2: i32, %arg3: i32) -> i32 {
%631 = arith.constant 0 : i32
%632 = llvm.mlir.constant(1 : i64) : i64
%633 = llvm.alloca %632 x i32 : (i64) -> !llvm.ptr
llvm.store %631, %633 : i32, !llvm.ptr
%634 = arith.constant 1 : i32
%635 = arith.shli %634, %arg3 : i32
%636 = arith.constant 1 : i32
%637 = llvm.mlir.constant(1 : i64) : i64
%638 = llvm.alloca %637 x i32 : (i64) -> !llvm.ptr
llvm.store %636, %638 : i32, !llvm.ptr
cf.br ^bb90
^bb90:
%639 = llvm.load %638 : !llvm.ptr -> i32
%640 = arith.cmpi slt, %639, %635 : i32
cf.cond_br %640, ^bb91, ^bb92
^bb91:
%642 = arith.constant 24 : i32
%643 = arith.extsi %642 : i32 to i64
%641 = func.call @malloc(%643) : (i64) -> !llvm.ptr
%644 = arith.constant 0 : i32
%645 = llvm.mlir.constant(1 : i64) : i64
%646 = llvm.alloca %645 x i32 : (i64) -> !llvm.ptr
llvm.store %644, %646 : i32, !llvm.ptr
%647 = arith.constant 0 : i32
%648 = llvm.mlir.constant(1 : i64) : i64
%649 = llvm.alloca %648 x i32 : (i64) -> !llvm.ptr
llvm.store %647, %649 : i32, !llvm.ptr
%650 = arith.constant 0 : i32
%651 = llvm.mlir.constant(1 : i64) : i64
%652 = llvm.alloca %651 x i32 : (i64) -> !llvm.ptr
llvm.store %650, %652 : i32, !llvm.ptr
cf.br ^bb93
^bb93:
%653 = llvm.load %652 : !llvm.ptr -> i32
%654 = arith.cmpi slt, %653, %arg3 : i32
cf.cond_br %654, ^bb94, ^bb95
^bb94:
%655 = llvm.load %638 : !llvm.ptr -> i32
%656 = arith.constant 1 : i32
%657 = llvm.load %652 : !llvm.ptr -> i32
%658 = arith.shli %656, %657 : i32
%659 = arith.andi %655, %658 : i32
%660 = arith.constant 0 : i32
%661 = arith.cmpi ne, %659, %660 : i32
cf.cond_br %661, ^bb96, ^bb97
^bb96:
%663 = llvm.load %652 : !llvm.ptr -> i32
%664 = arith.addi %arg2, %663 : i32
%665 = arith.extsi %664 : i32 to i64
%666 = llvm.getelementptr %arg1[%665] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%662 = llvm.load %666 : !llvm.ptr -> i32
%667 = llvm.load %646 : !llvm.ptr -> i32
%668 = arith.extsi %667 : i32 to i64
%669 = llvm.getelementptr %641[%668] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %662, %669 : i32, !llvm.ptr
%670 = llvm.load %649 : !llvm.ptr -> i32
%672 = llvm.load %652 : !llvm.ptr -> i32
%673 = arith.addi %arg2, %672 : i32
%674 = arith.extsi %673 : i32 to i64
%675 = llvm.getelementptr %arg1[%674] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%671 = llvm.load %675 : !llvm.ptr -> i32
%676 = arith.addi %670, %671 : i32
llvm.store %676, %649 : i32, !llvm.ptr
%677 = llvm.load %646 : !llvm.ptr -> i32
%678 = arith.constant 1 : i32
%679 = arith.addi %677, %678 : i32
llvm.store %679, %646 : i32, !llvm.ptr
cf.br ^bb98
^bb97:
cf.br ^bb98
^bb98:
%680 = llvm.load %652 : !llvm.ptr -> i32
%681 = arith.constant 1 : i32
%682 = arith.addi %680, %681 : i32
llvm.store %682, %652 : i32, !llvm.ptr
cf.br ^bb93
^bb95:
%683 = llvm.load %633 : !llvm.ptr -> i32
%684 = arith.constant 0 : i32
%685 = arith.cmpi sgt, %683, %684 : i32
%686 = scf.if %685 -> (i1) {
%687 = llvm.load %649 : !llvm.ptr -> i32
%688 = llvm.load %633 : !llvm.ptr -> i32
%689 = arith.cmpi sge, %687, %688 : i32
scf.yield %689 : i1
} else {
%690 = arith.constant false
scf.yield %690 : i1
}
cf.cond_br %686, ^bb99, ^bb100
^bb99:
func.call @free(%641) : (!llvm.ptr) -> ()
%692 = llvm.load %638 : !llvm.ptr -> i32
%693 = arith.constant 1 : i32
%694 = arith.addi %692, %693 : i32
llvm.store %694, %638 : i32, !llvm.ptr
cf.br ^bb90
^bb100:
cf.br ^bb101
^bb101:
func.call @da_init() : () -> ()
%697 = llvm.load %646 : !llvm.ptr -> i32
func.call @generate_values(%641, %697) : (!llvm.ptr, i32) -> ()
%698 = arith.constant 0 : i32
%699 = llvm.mlir.constant(1 : i64) : i64
%700 = llvm.alloca %699 x i32 : (i64) -> !llvm.ptr
llvm.store %698, %700 : i32, !llvm.ptr
%701 = llvm.mlir.addressof @g_da_count : !llvm.ptr
%702 = llvm.load %701 : !llvm.ptr -> i32
%703 = arith.constant 1 : i32
%704 = arith.subi %702, %703 : i32
%705 = llvm.mlir.constant(1 : i64) : i64
%706 = llvm.alloca %705 x i32 : (i64) -> !llvm.ptr
llvm.store %704, %706 : i32, !llvm.ptr
%707 = arith.constant 0 : i32
%708 = llvm.mlir.constant(1 : i64) : i64
%709 = llvm.alloca %708 x i32 : (i64) -> !llvm.ptr
llvm.store %707, %709 : i32, !llvm.ptr
cf.br ^bb102
^bb102:
%710 = llvm.load %700 : !llvm.ptr -> i32
%711 = llvm.load %706 : !llvm.ptr -> i32
%712 = arith.cmpi sle, %710, %711 : i32
cf.cond_br %712, ^bb103, ^bb104
^bb103:
%713 = llvm.load %700 : !llvm.ptr -> i32
%714 = llvm.load %706 : !llvm.ptr -> i32
%715 = arith.addi %713, %714 : i32
%716 = arith.constant 2 : i32
%717 = arith.divsi %715, %716 : i32
%719 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%720 = llvm.load %719 : !llvm.ptr -> !llvm.ptr
%721 = arith.extsi %717 : i32 to i64
%722 = llvm.getelementptr %720[%721] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%718 = llvm.load %722 : !llvm.ptr -> i32
%723 = arith.cmpi eq, %718, %arg0 : i32
cf.cond_br %723, ^bb105, ^bb106
^bb105:
%724 = arith.constant 1 : i32
llvm.store %724, %709 : i32, !llvm.ptr
cf.br ^bb104
^bb106:
cf.br ^bb107
^bb107:
%726 = llvm.mlir.addressof @g_da_vals : !llvm.ptr
%727 = llvm.load %726 : !llvm.ptr -> !llvm.ptr
%728 = arith.extsi %717 : i32 to i64
%729 = llvm.getelementptr %727[%728] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%725 = llvm.load %729 : !llvm.ptr -> i32
%730 = arith.cmpi slt, %725, %arg0 : i32
cf.cond_br %730, ^bb108, ^bb109
^bb108:
%731 = arith.constant 1 : i32
%732 = arith.addi %717, %731 : i32
llvm.store %732, %700 : i32, !llvm.ptr
cf.br ^bb110
^bb109:
%733 = arith.constant 1 : i32
%734 = arith.subi %717, %733 : i32
llvm.store %734, %706 : i32, !llvm.ptr
cf.br ^bb110
^bb110:
cf.br ^bb102
^bb104:
%735 = llvm.load %709 : !llvm.ptr -> i32
%736 = arith.constant 0 : i32
%737 = arith.cmpi ne, %735, %736 : i32
cf.cond_br %737, ^bb111, ^bb112
^bb111:
%738 = llvm.load %633 : !llvm.ptr -> i32
%739 = arith.constant 0 : i32
%740 = arith.cmpi eq, %738, %739 : i32
%741 = scf.if %740 -> (i1) {
%742 = arith.constant true
scf.yield %742 : i1
} else {
%743 = llvm.load %649 : !llvm.ptr -> i32
%744 = llvm.load %633 : !llvm.ptr -> i32
%745 = arith.cmpi slt, %743, %744 : i32
scf.yield %745 : i1
}
cf.cond_br %741, ^bb114, ^bb115
^bb114:
%746 = llvm.load %649 : !llvm.ptr -> i32
llvm.store %746, %633 : i32, !llvm.ptr
cf.br ^bb116
^bb115:
cf.br ^bb116
^bb116:
cf.br ^bb113
^bb112:
cf.br ^bb113
^bb113:
func.call @da_free() : () -> ()
func.call @free(%641) : (!llvm.ptr) -> ()
%749 = llvm.load %638 : !llvm.ptr -> i32
%750 = arith.constant 1 : i32
%751 = arith.addi %749, %750 : i32
llvm.store %751, %638 : i32, !llvm.ptr
cf.br ^bb90
^bb92:
%752 = llvm.load %633 : !llvm.ptr -> i32
func.return %752 : i32
}
func.func @read_data(%arg0: !llvm.ptr) -> () {
%754 = llvm.mlir.addressof @MAX_PROBS : !llvm.ptr
%755 = llvm.load %754 : !llvm.ptr -> i32
%756 = arith.extsi %755 : i32 to i64
%757 = arith.constant 4 : i32
%759 = arith.extsi %757 : i32 to i64
%758 = arith.muli %756, %759 : i64
%753 = func.call @malloc(%758) : (i64) -> !llvm.ptr
%760 = llvm.mlir.addressof @g_targets : !llvm.ptr
llvm.store %753, %760 : !llvm.ptr, !llvm.ptr
%762 = llvm.mlir.addressof @MAX_PROBS : !llvm.ptr
%763 = llvm.load %762 : !llvm.ptr -> i32
%764 = arith.extsi %763 : i32 to i64
%765 = arith.constant 4 : i32
%767 = arith.extsi %765 : i32 to i64
%766 = arith.muli %764, %767 : i64
%761 = func.call @malloc(%766) : (i64) -> !llvm.ptr
%768 = llvm.mlir.addressof @g_counts : !llvm.ptr
llvm.store %761, %768 : !llvm.ptr, !llvm.ptr
%770 = llvm.mlir.addressof @MAX_PROBS : !llvm.ptr
%771 = llvm.load %770 : !llvm.ptr -> i32
%772 = arith.extsi %771 : i32 to i64
%773 = llvm.mlir.addressof @MAX_NUMS : !llvm.ptr
%774 = llvm.load %773 : !llvm.ptr -> i32
%775 = arith.extsi %774 : i32 to i64
%776 = arith.muli %772, %775 : i64
%777 = arith.constant 4 : i32
%779 = arith.extsi %777 : i32 to i64
%778 = arith.muli %776, %779 : i64
%769 = func.call @malloc(%778) : (i64) -> !llvm.ptr
%780 = llvm.mlir.addressof @g_nums : !llvm.ptr
llvm.store %769, %780 : !llvm.ptr, !llvm.ptr
%782 = llvm.mlir.addressof @str_0 : !llvm.ptr
%781 = func.call @fopen(%arg0, %782) : (!llvm.ptr, !llvm.ptr) -> !llvm.ptr
%783 = llvm.mlir.zero : !llvm.ptr
%784 = llvm.icmp "eq" %781, %783 : !llvm.ptr
cf.cond_br %784, ^bb117, ^bb118
^bb117:
func.return
^bb118:
cf.br ^bb119
^bb119:
%785 = arith.constant 0 : i32
%786 = llvm.mlir.addressof @g_num_problems : !llvm.ptr
llvm.store %785, %786 : i32, !llvm.ptr
%787 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
%788 = llvm.mlir.constant(1 : i64) : i64
%789 = llvm.alloca %788 x i32 : (i64) -> !llvm.ptr
llvm.store %787, %789 : i32, !llvm.ptr
cf.br ^bb120
^bb120:
%790 = llvm.load %789 : !llvm.ptr -> i32
%791 = arith.constant 0 : i32
%792 = arith.cmpi sge, %790, %791 : i32
cf.cond_br %792, ^bb121, ^bb122
^bb121:
cf.br ^bb123
^bb123:
%793 = llvm.load %789 : !llvm.ptr -> i32
%794 = arith.constant 0 : i32
%795 = arith.cmpi sge, %793, %794 : i32
%796 = scf.if %795 -> (i1) {
%797 = llvm.load %789 : !llvm.ptr -> i32
%798 = arith.constant 32 : i32
%799 = arith.cmpi sle, %797, %798 : i32
scf.yield %799 : i1
} else {
%800 = arith.constant false
scf.yield %800 : i1
}
cf.cond_br %796, ^bb124, ^bb125
^bb124:
%801 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
llvm.store %801, %789 : i32, !llvm.ptr
cf.br ^bb123
^bb125:
%802 = llvm.load %789 : !llvm.ptr -> i32
%803 = arith.constant 0 : i32
%804 = arith.cmpi slt, %802, %803 : i32
cf.cond_br %804, ^bb126, ^bb127
^bb126:
cf.br ^bb122
^bb127:
cf.br ^bb128
^bb128:
%805 = arith.constant 0 : i32
%806 = llvm.mlir.constant(1 : i64) : i64
%807 = llvm.alloca %806 x i32 : (i64) -> !llvm.ptr
llvm.store %805, %807 : i32, !llvm.ptr
cf.br ^bb129
^bb129:
%808 = llvm.load %789 : !llvm.ptr -> i32
%809 = arith.constant 48 : i32
%810 = arith.cmpi sge, %808, %809 : i32
%811 = scf.if %810 -> (i1) {
%812 = llvm.load %789 : !llvm.ptr -> i32
%813 = arith.constant 57 : i32
%814 = arith.cmpi sle, %812, %813 : i32
scf.yield %814 : i1
} else {
%815 = arith.constant false
scf.yield %815 : i1
}
cf.cond_br %811, ^bb130, ^bb131
^bb130:
%816 = llvm.load %807 : !llvm.ptr -> i32
%817 = arith.constant 10 : i32
%818 = arith.muli %816, %817 : i32
%819 = llvm.load %789 : !llvm.ptr -> i32
%820 = arith.constant 48 : i32
%821 = arith.subi %819, %820 : i32
%822 = arith.addi %818, %821 : i32
llvm.store %822, %807 : i32, !llvm.ptr
%823 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
llvm.store %823, %789 : i32, !llvm.ptr
cf.br ^bb129
^bb131:
%824 = llvm.load %807 : !llvm.ptr -> i32
%825 = llvm.mlir.addressof @g_targets : !llvm.ptr
%826 = llvm.load %825 : !llvm.ptr -> !llvm.ptr
%827 = llvm.mlir.addressof @g_num_problems : !llvm.ptr
%828 = llvm.load %827 : !llvm.ptr -> i32
%829 = arith.extsi %828 : i32 to i64
%830 = llvm.getelementptr %826[%829] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %824, %830 : i32, !llvm.ptr
%831 = llvm.load %789 : !llvm.ptr -> i32
%832 = arith.constant 58 : i32
%833 = arith.cmpi eq, %831, %832 : i32
cf.cond_br %833, ^bb132, ^bb133
^bb132:
%834 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
llvm.store %834, %789 : i32, !llvm.ptr
cf.br ^bb134
^bb133:
cf.br ^bb134
^bb134:
%835 = arith.constant 0 : i32
%836 = llvm.mlir.constant(1 : i64) : i64
%837 = llvm.alloca %836 x i32 : (i64) -> !llvm.ptr
llvm.store %835, %837 : i32, !llvm.ptr
cf.br ^bb135
^bb135:
%838 = llvm.load %789 : !llvm.ptr -> i32
%839 = arith.constant 0 : i32
%840 = arith.cmpi sge, %838, %839 : i32
%841 = scf.if %840 -> (i1) {
%842 = llvm.load %789 : !llvm.ptr -> i32
%843 = arith.constant 10 : i32
%844 = arith.cmpi ne, %842, %843 : i32
scf.yield %844 : i1
} else {
%845 = arith.constant false
scf.yield %845 : i1
}
%846 = scf.if %841 -> (i1) {
%847 = llvm.load %789 : !llvm.ptr -> i32
%848 = arith.constant 13 : i32
%849 = arith.cmpi ne, %847, %848 : i32
scf.yield %849 : i1
} else {
%850 = arith.constant false
scf.yield %850 : i1
}
cf.cond_br %846, ^bb136, ^bb137
^bb136:
cf.br ^bb138
^bb138:
%851 = llvm.load %789 : !llvm.ptr -> i32
%852 = arith.constant 44 : i32
%853 = arith.cmpi eq, %851, %852 : i32
cf.cond_br %853, ^bb139, ^bb140
^bb139:
%854 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
llvm.store %854, %789 : i32, !llvm.ptr
cf.br ^bb138
^bb140:
%855 = llvm.load %789 : !llvm.ptr -> i32
%856 = arith.constant 0 : i32
%857 = arith.cmpi slt, %855, %856 : i32
%858 = scf.if %857 -> (i1) {
%859 = arith.constant true
scf.yield %859 : i1
} else {
%860 = llvm.load %789 : !llvm.ptr -> i32
%861 = arith.constant 10 : i32
%862 = arith.cmpi eq, %860, %861 : i32
scf.yield %862 : i1
}
%863 = scf.if %858 -> (i1) {
%864 = arith.constant true
scf.yield %864 : i1
} else {
%865 = llvm.load %789 : !llvm.ptr -> i32
%866 = arith.constant 13 : i32
%867 = arith.cmpi eq, %865, %866 : i32
scf.yield %867 : i1
}
cf.cond_br %863, ^bb141, ^bb142
^bb141:
cf.br ^bb137
^bb142:
cf.br ^bb143
^bb143:
%868 = arith.constant 0 : i32
%869 = llvm.mlir.constant(1 : i64) : i64
%870 = llvm.alloca %869 x i32 : (i64) -> !llvm.ptr
llvm.store %868, %870 : i32, !llvm.ptr
cf.br ^bb144
^bb144:
%871 = llvm.load %789 : !llvm.ptr -> i32
%872 = arith.constant 48 : i32
%873 = arith.cmpi sge, %871, %872 : i32
%874 = scf.if %873 -> (i1) {
%875 = llvm.load %789 : !llvm.ptr -> i32
%876 = arith.constant 57 : i32
%877 = arith.cmpi sle, %875, %876 : i32
scf.yield %877 : i1
} else {
%878 = arith.constant false
scf.yield %878 : i1
}
cf.cond_br %874, ^bb145, ^bb146
^bb145:
%879 = llvm.load %870 : !llvm.ptr -> i32
%880 = arith.constant 10 : i32
%881 = arith.muli %879, %880 : i32
%882 = llvm.load %789 : !llvm.ptr -> i32
%883 = arith.constant 48 : i32
%884 = arith.subi %882, %883 : i32
%885 = arith.addi %881, %884 : i32
llvm.store %885, %870 : i32, !llvm.ptr
%886 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
llvm.store %886, %789 : i32, !llvm.ptr
cf.br ^bb144
^bb146:
%887 = llvm.load %870 : !llvm.ptr -> i32
%888 = arith.constant 0 : i32
%889 = arith.cmpi sgt, %887, %888 : i32
cf.cond_br %889, ^bb147, ^bb148
^bb147:
%890 = llvm.load %870 : !llvm.ptr -> i32
%891 = llvm.mlir.addressof @g_nums : !llvm.ptr
%892 = llvm.load %891 : !llvm.ptr -> !llvm.ptr
%893 = llvm.mlir.addressof @g_num_problems : !llvm.ptr
%894 = llvm.load %893 : !llvm.ptr -> i32
%895 = llvm.mlir.addressof @MAX_NUMS : !llvm.ptr
%896 = llvm.load %895 : !llvm.ptr -> i32
%897 = arith.muli %894, %896 : i32
%898 = llvm.load %837 : !llvm.ptr -> i32
%899 = arith.addi %897, %898 : i32
%900 = arith.extsi %899 : i32 to i64
%901 = llvm.getelementptr %892[%900] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %890, %901 : i32, !llvm.ptr
%902 = llvm.load %837 : !llvm.ptr -> i32
%903 = arith.constant 1 : i32
%904 = arith.addi %902, %903 : i32
llvm.store %904, %837 : i32, !llvm.ptr
cf.br ^bb149
^bb148:
cf.br ^bb149
^bb149:
cf.br ^bb135
^bb137:
%905 = llvm.load %837 : !llvm.ptr -> i32
%906 = llvm.mlir.addressof @g_counts : !llvm.ptr
%907 = llvm.load %906 : !llvm.ptr -> !llvm.ptr
%908 = llvm.mlir.addressof @g_num_problems : !llvm.ptr
%909 = llvm.load %908 : !llvm.ptr -> i32
%910 = arith.extsi %909 : i32 to i64
%911 = llvm.getelementptr %907[%910] : (!llvm.ptr, i64) -> !llvm.ptr, i32
llvm.store %905, %911 : i32, !llvm.ptr
%912 = llvm.mlir.addressof @g_num_problems : !llvm.ptr
%913 = llvm.load %912 : !llvm.ptr -> i32
%914 = arith.constant 1 : i32
%915 = arith.addi %913, %914 : i32
%916 = llvm.mlir.addressof @g_num_problems : !llvm.ptr
llvm.store %915, %916 : i32, !llvm.ptr
cf.br ^bb150
^bb150:
%917 = llvm.load %789 : !llvm.ptr -> i32
%918 = arith.constant 0 : i32
%919 = arith.cmpi sge, %917, %918 : i32
%920 = scf.if %919 -> (i1) {
%921 = llvm.load %789 : !llvm.ptr -> i32
%922 = arith.constant 10 : i32
%923 = arith.cmpi ne, %921, %922 : i32
scf.yield %923 : i1
} else {
%924 = arith.constant false
scf.yield %924 : i1
}
cf.cond_br %920, ^bb151, ^bb152
^bb151:
%925 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
llvm.store %925, %789 : i32, !llvm.ptr
cf.br ^bb150
^bb152:
%926 = llvm.load %789 : !llvm.ptr -> i32
%927 = arith.constant 10 : i32
%928 = arith.cmpi eq, %926, %927 : i32
cf.cond_br %928, ^bb153, ^bb154
^bb153:
%929 = func.call @fgetc(%781) : (!llvm.ptr) -> i32
llvm.store %929, %789 : i32, !llvm.ptr
cf.br ^bb155
^bb154:
cf.br ^bb155
^bb155:
cf.br ^bb120
^bb122:
%930 = func.call @fclose(%781) : (!llvm.ptr) -> i32
func.return
}
func.func @main() -> i32 {
func.call @cache_reset() : () -> ()
%933 = llvm.mlir.addressof @str_1 : !llvm.ptr
func.call @read_data(%933) : (!llvm.ptr) -> ()
%934 = arith.constant 0 : i32
%935 = arith.extsi %934 : i32 to i64
%936 = llvm.mlir.constant(1 : i64) : i64
%937 = llvm.alloca %936 x i64 : (i64) -> !llvm.ptr
llvm.store %935, %937 : i64, !llvm.ptr
%938 = arith.constant 3 : i32
%939 = arith.extsi %938 : i32 to i64
%940 = llvm.mlir.constant(1 : i64) : i64
%941 = llvm.alloca %940 x i64 : (i64) -> !llvm.ptr
llvm.store %939, %941 : i64, !llvm.ptr
%942 = arith.constant 0 : i32
%943 = llvm.mlir.constant(1 : i64) : i64
%944 = llvm.alloca %943 x i32 : (i64) -> !llvm.ptr
llvm.store %942, %944 : i32, !llvm.ptr
cf.br ^bb156
^bb156:
%945 = llvm.load %944 : !llvm.ptr -> i32
%946 = llvm.mlir.addressof @g_num_problems : !llvm.ptr
%947 = llvm.load %946 : !llvm.ptr -> i32
%948 = arith.cmpi slt, %945, %947 : i32
cf.cond_br %948, ^bb157, ^bb158
^bb157:
%950 = llvm.mlir.addressof @g_targets : !llvm.ptr
%951 = llvm.load %950 : !llvm.ptr -> !llvm.ptr
%952 = llvm.load %944 : !llvm.ptr -> i32
%953 = arith.extsi %952 : i32 to i64
%954 = llvm.getelementptr %951[%953] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%949 = llvm.load %954 : !llvm.ptr -> i32
%956 = llvm.mlir.addressof @g_counts : !llvm.ptr
%957 = llvm.load %956 : !llvm.ptr -> !llvm.ptr
%958 = llvm.load %944 : !llvm.ptr -> i32
%959 = arith.extsi %958 : i32 to i64
%960 = llvm.getelementptr %957[%959] : (!llvm.ptr, i64) -> !llvm.ptr, i32
%955 = llvm.load %960 : !llvm.ptr -> i32
%962 = llvm.mlir.addressof @g_nums : !llvm.ptr
%963 = llvm.load %962 : !llvm.ptr -> !llvm.ptr
%964 = llvm.load %944 : !llvm.ptr -> i32
%965 = llvm.mlir.addressof @MAX_NUMS : !llvm.ptr
%966 = llvm.load %965 : !llvm.ptr -> i32
%967 = arith.muli %964, %966 : i32
%961 = func.call @min_score(%949, %963, %967, %955) : (i32, !llvm.ptr, i32, i32) -> i32
%968 = llvm.load %937 : !llvm.ptr -> i64
%969 = llvm.load %941 : !llvm.ptr -> i64
%970 = arith.extsi %961 : i32 to i64
%971 = arith.muli %969, %970 : i64
%972 = arith.addi %968, %971 : i64
%973 = llvm.mlir.addressof @MOD : !llvm.ptr
%974 = llvm.load %973 : !llvm.ptr -> i64
%975 = arith.remsi %972, %974 : i64
llvm.store %975, %937 : i64, !llvm.ptr
%976 = llvm.load %941 : !llvm.ptr -> i64
%977 = arith.constant 3 : i32
%979 = arith.extsi %977 : i32 to i64
%978 = arith.muli %976, %979 : i64
%980 = llvm.mlir.addressof @MOD : !llvm.ptr
%981 = llvm.load %980 : !llvm.ptr -> i64
%982 = arith.remsi %978, %981 : i64
llvm.store %982, %941 : i64, !llvm.ptr
%983 = llvm.load %944 : !llvm.ptr -> i32
%984 = arith.constant 1 : i32
%985 = arith.addi %983, %984 : i32
llvm.store %985, %944 : i32, !llvm.ptr
cf.br ^bb156
^bb158:
%987 = llvm.mlir.addressof @g_targets : !llvm.ptr
%988 = llvm.load %987 : !llvm.ptr -> !llvm.ptr
func.call @free(%988) : (!llvm.ptr) -> ()
%990 = llvm.mlir.addressof @g_counts : !llvm.ptr
%991 = llvm.load %990 : !llvm.ptr -> !llvm.ptr
func.call @free(%991) : (!llvm.ptr) -> ()
%993 = llvm.mlir.addressof @g_nums : !llvm.ptr
%994 = llvm.load %993 : !llvm.ptr -> !llvm.ptr
func.call @free(%994) : (!llvm.ptr) -> ()
%996 = llvm.mlir.addressof @g_cache : !llvm.ptr
%997 = llvm.load %996 : !llvm.ptr -> !llvm.ptr
func.call @free(%997) : (!llvm.ptr) -> ()
%998 = llvm.mlir.addressof @str_2 : !llvm.ptr
%999 = llvm.load %937 : !llvm.ptr -> i64
%1000 = llvm.call @printf(%998, %999) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
%1001 = arith.constant 0 : i32
func.return %1001 : i32
}
}