Stark/Cairo Tutorial 4-Array_product
Array product on even numbers is given as an exercise. This is probably one of the annoying things about the documentation.. it's written like a university tutorial. In the end I ended up just searching the cairo-lang github directly and inferring the language from the code egs. Super annoying. I guess all available coders are too busy on actual revenue producing activities and no one has time to write proper tutorials. Nuts.
Let's try to start with the bones from array_sum and go from there.
%builtins output range_check
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.serialize import serialize_word
from starkware.cairo.common.math_cmp import is_nn
from starkware.cairo.common.math import assert_nn_le, unsigned_div_rem
# Computes the product of the memory elements at even addresses:
# arr + 0, arr + 2, ..., arr + (size - 1).
# assumes length of array is even
func array_product{range_check_ptr}(arr : felt*, size) -> (product):
if size == 0:
return (product=1)
end
# if size is even, then array sequence is odd and just multiply the next product by 1
# if size is odd, then array sequence is even and multiply next product
# If this div goes out of range, then not divisible
# if size is not divisible by 2, then off, the array sequence is even and product should be include
let (q, r) = unsigned_div_rem(size, 2)
%{
# Debug
print(
f'Size: {ids.size}; r: {ids.r} '
)
%}
if r != 0:
let (product_of_rest) = array_product(arr=arr + 1, size=size - 1)
return (product=[arr] * product_of_rest)
else:
let (product_of_rest) = array_product(arr=arr + 1, size=size - 1)
return (product=1 * product_of_rest)
end
end
func main{output_ptr : felt*, range_check_ptr}():
const ARRAY_SIZE = 4
# Allocate an array
let (ptr) = alloc()
# Populate some values in the array
assert [ptr] = 9
assert [ptr + 1] = 16
assert [ptr + 2] = 25
assert [ptr + 3] = 10
# Call array_sum to compute the sum of the elements.
let (sum) = array_product(arr=ptr, size=ARRAY_SIZE)
# Write the sum to the program output.
serialize_word(sum)
return ()
end
Some notes:
- The range_check builtin has to be declared and the pointer has to be passed in order for math functions to work properly
- Math from stark common libraries has to be used for almost every division.