CS153/hw6/llprograms/sp24_hw3/find_duplicate.ll
jmug ee01a8f5b2 Change hw6 to an unsolved version.
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
2025-01-24 23:10:01 -08:00

85 lines
2.7 KiB
LLVM

; Created by Adam & Hassan :)
; Finds a duplicate to the array assuming there is only one duplicate and all items are in range [1, n]
; LeetCode #287
; Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive.
; There is only one repeated number in nums, return this repeated number.
; You must solve the problem without modifying the array nums and uses only constant extra space.
; Uses Floyd's Cycle Detection algo
%arr_t = type [5 x i64]
@input_arr = global %arr_t [ i64 1, i64 2, i64 3, i64 3, i64 4 ]
define i64 @find_dup() {
; initialize my slow and fast pointers
%slow = alloca i64
%fast = alloca i64
; second slow pointer for phase 2
%slow_2 = alloca i64
; set them all to 0
store i64 0, i64* %slow
store i64 0, i64* %fast
store i64 0, i64* %slow_2
; move on
br label %phase_1_loop
phase_1_loop:
; slow = nums[slow]
; aka stepping through slow
%slow_val = load i64, i64* %slow
%slow_val_ptr = getelementptr %arr_t, %arr_t* @input_arr, i64 0, i64 %slow_val
%slow_val_loaded = load i64, i64* %slow_val_ptr
store i64 %slow_val_loaded, i64* %slow
; fast = nums[nums[fast]]
; aka stepping through fast
%fast_val = load i64, i64* %fast
%fast_val_ptr = getelementptr %arr_t, %arr_t* @input_arr, i64 0, i64 %fast_val
%fast_val_loaded = load i64, i64* %fast_val_ptr
%fast_val_ptr_2 = getelementptr %arr_t, %arr_t* @input_arr, i64 0, i64 %fast_val_loaded
%fast_val_loaded2 = load i64, i64* %fast_val_ptr_2
store i64 %fast_val_loaded2, i64* %fast
; if slow == fast, break
; otherwise, continue
%cmp = icmp eq i64 %slow_val_loaded, %fast_val_loaded2
br i1 %cmp, label %phase_2_loop, label %phase_1_loop
phase_2_loop:
; slow = nums[slow]
; aka stepping through slow
%slow_val_p2 = load i64, i64* %slow
%slow_val_ptr_p2 = getelementptr %arr_t, %arr_t* @input_arr, i64 0, i64 %slow_val_p2
%slow_val_p2_2 = load i64, i64* %slow_val_ptr_p2
store i64 %slow_val_p2_2, i64* %slow
; slow = nums[slow_2]
; aka stepping through other slow
%slow2_val = load i64, i64* %slow_2
%slow2_val_ptr_p2 = getelementptr %arr_t, %arr_t* @input_arr, i64 0, i64 %slow2_val
%slow2_val_2 = load i64, i64* %slow2_val_ptr_p2
store i64 %slow2_val_2, i64* %slow_2
; if slow == slow_2, return slow, otherwise loop
%cmp_p2 = icmp eq i64 %slow_val_p2_2, %slow2_val_2
br i1 %cmp, label %return_slow, label %phase_2_loop
return_slow:
ret i64 %slow_val_p2_2
}
; just takes in the global arr - to avoid compile issues
; should return 3L
define i64 @main(i64 %argc, i8** %argv) {
%main_result = call i64 @find_dup()
ret i64 %main_result
}