Skip to content

Instantly share code, notes, and snippets.

@hitsuzen-eth
Last active May 31, 2022 14:43
Show Gist options
  • Save hitsuzen-eth/d989acb7908f27642259a129f34eb43d to your computer and use it in GitHub Desktop.
Save hitsuzen-eth/d989acb7908f27642259a129f34eb43d to your computer and use it in GitHub Desktop.
func _search_index_array{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(
array_len : felt,
array : felt*,
index: felt,
index_match: felt,
match_callback: felt) -> (
index_match: felt):
alloc_locals
# Stop recursion if array_len <= index
let (is_array_len_le_index) = is_le(a = array_len, b = index)
if is_array_len_le_index == TRUE:
return(index_match = index_match)
end
# Push all argument of match_callback
[ap] = range_check_ptr; ap++
[ap] = array_len; ap++
[ap] = array; ap++
[ap] = index; ap++
[ap] = index_match; ap++
# Call the match_callback
call abs match_callback
# Get return from match_callback and update range_check_ptr
local range_check_ptr = [ap - 2]
local is_match = [ap - 1]
if is_match == TRUE:
return _search_index_array(
array_len = array_len,
array = array,
index = (index + 1),
index_match = index,
match_callback = match_callback)
end
return _search_index_array(
array_len = array_len,
array = array,
index = (index + 1),
index_match = index_match,
match_callback = match_callback)
end
# [(3), 2, 1, 4] index=0 index_min=0
# [3, (2), 1, 4] index=1 index_min=1
# [3, 2, (1), 4] index=2 index_min=2
# [3, 2, 1, (4)] index=3 index_min=2
func _match_min_callback{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*}(
range_check_ptr,
array_len : felt,
array : felt*,
index: felt,
index_match: felt) -> (
range_check_ptr,
is_match: felt):
# Pass the range_check_ptr as implicit argument to is_le()
with range_check_ptr:
let (is_match) = is_le(a = (array[index] + 1), b = array[index_match])
end
return (range_check_ptr = range_check_ptr, is_match = is_match)
end
# [(3), 2, 4, 4] index=0 index_max=0
# [3, (2), 4, 4] index=1 index_max=0
# [3, 2, (4), 4] index=2 index_max=2
# [3, 2, 4, (4)] index=3 index_max=2
func _match_max_callback{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*}(
range_check_ptr,
array_len : felt,
array : felt*,
index: felt,
index_match: felt) -> (
range_check_ptr,
is_match: felt):
alloc_locals
# Pass the range_check_ptr as implicit argument to is_le()
with range_check_ptr:
let (local is_match) = is_le(a = array[index], b = array[index_match])
# Return the opposite result
# not (a <= b) is the same as (a > b)
if is_match == TRUE:
local is_match = FALSE
return (range_check_ptr = range_check_ptr, is_match = is_match)
else:
local is_match = TRUE
return (range_check_ptr = range_check_ptr, is_match = is_match)
end
end
end
# Search the first min value and return his index
# [1,2,3,1] => 0
func search_min_index_array{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(
array_len : felt,
array : felt*) -> (
index_min: felt):
# Get the "address" of the callback function
let (match_callback) = get_label_location(label_value = _match_min_callback)
return _search_index_array(
array_len = array_len,
array = array,
index = 0,
index_match = 0,
match_callback = match_callback)
end
# Search the first max value and return his index
# [3,2,1,3] => 0
func search_max_index_array{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(
array_len : felt,
array : felt*) -> (
index_max: felt):
# Get the "address" of the callback function
let (match_callback) = get_label_location(label_value = _match_max_callback)
return _search_index_array(
array_len = array_len,
array = array,
index = 0,
index_match = 0,
match_callback = match_callback)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment