mem :: import "@std/mem" TaskList :: struct { ids ?[]mut i32 priorities ?[]mut i32 durations ?[]mut i32 len usize capacity usize allocator mem.Allocator } task_list_init func(allocator mem.Allocator) TaskList { return TaskList { ids = none, priorities = none, durations = none, len = 0, capacity = 0, allocator = allocator, } } alloc_i32s func(allocator mem.Allocator, count usize) ?[]mut i32 { raw ?*mut u8 = mem.alloc(allocator, count * size_of(i32), align_of(i32)) if raw |bytes| { values *mut i32 = ptr_cast(i32, bytes) return values[..count] } return none } free_i32s func(allocator mem.Allocator, values ?[]mut i32) void { if values |slice| { mem.free(allocator, ptr_cast(u8, slice.ptr), slice.len * size_of(i32), align_of(i32)) } } task_list_reserve func(list @mut TaskList, capacity usize) bool { if capacity <= list.capacity { return true } new_ids ?[]mut i32 = alloc_i32s(list.allocator, capacity) new_priorities ?[]mut i32 = alloc_i32s(list.allocator, capacity) new_durations ?[]mut i32 = alloc_i32s(list.allocator, capacity) if (new_ids and new_priorities and new_durations) |ids, priorities, durations| { if list.len > 0 { if (list.ids and list.priorities and list.durations) |old_ids, old_priorities, old_durations| { i usize = 0 while i < list.len : i += 1 { ids[i] = old_ids[i] priorities[i] = old_priorities[i] durations[i] = old_durations[i] } } else { free_i32s(list.allocator, new_ids) free_i32s(list.allocator, new_priorities) free_i32s(list.allocator, new_durations) return false } } free_i32s(list.allocator, list.ids) free_i32s(list.allocator, list.priorities) free_i32s(list.allocator, list.durations) list.ids = new_ids list.priorities = new_priorities list.durations = new_durations list.capacity = capacity return true } free_i32s(list.allocator, new_ids) free_i32s(list.allocator, new_priorities) free_i32s(list.allocator, new_durations) return false } task_list_push func(list @mut TaskList, id i32, priority i32, duration i32) bool { if list.len == list.capacity { new_capacity usize = 2 if list.capacity != 0 { new_capacity = list.capacity * 2 } if task_list_reserve(list, new_capacity) == false { return false } } if (list.ids and list.priorities and list.durations) |ids, priorities, durations| { index usize = list.len ids[index] = id priorities[index] = priority durations[index] = duration list.len += 1 return true } return false } task_score func(priority i32, duration i32) i32 { return priority * 10 - duration } task_list_best_id func(list @mut TaskList) i32 { if list.len == 0 { return -1 } if (list.ids and list.priorities and list.durations) |ids, priorities, durations| { best_index usize = 0 best_score i32 = task_score(priorities[0], durations[0]) i usize = 1 while i < list.len : i += 1 { score i32 = task_score(priorities[i], durations[i]) if score > best_score { best_score = score best_index = i } } return ids[best_index] } return -1 } task_list_total_duration func(list @mut TaskList) i32 { total i32 = 0 if list.durations |durations| { i usize = 0 while i < list.len : i += 1 { total += durations[i] } } return total } task_list_deinit func(list @mut TaskList) void { free_i32s(list.allocator, list.ids) free_i32s(list.allocator, list.priorities) free_i32s(list.allocator, list.durations) list.ids = none list.priorities = none list.durations = none list.len = 0 list.capacity = 0 } main func() i32 { zero_alignment ?*mut u8 = mem.alloc(mem.c_allocator, 8, 0) if zero_alignment |memory| { mem.free(mem.c_allocator, memory, 8, 0) return 1 } bad_alignment ?*mut u8 = mem.alloc(mem.c_allocator, 8, 24) if bad_alignment |memory| { mem.free(mem.c_allocator, memory, 8, 24) return 2 } aligned ?*mut u8 = mem.alloc(mem.c_allocator, 64, 32) defer mem.free(mem.c_allocator, aligned, 64, 32) if aligned |bytes| { bytes[0] = 1 bytes[63] = 2 if bytes[0] + bytes[63] != 3 { return 4 } } else { return 3 } tasks TaskList = task_list_init(mem.c_allocator) defer task_list_deinit(&tasks) if task_list_push(&tasks, 101, 3, 5) == false { return 5 } if tasks.capacity != 2 { return 6 } if task_list_push(&tasks, 202, 1, 4) == false { return 7 } if tasks.capacity != 2 { return 8 } if task_list_push(&tasks, 303, 4, 8) == false { return 9 } if tasks.capacity != 4 { return 10 } if tasks.len != 3 { return 11 } if task_list_best_id(&tasks) != 303 { return 12 } if task_list_total_duration(&tasks) != 17 { return 13 } return 0 }