NEWTON

NEWTON


Popular tags

    How can I use dynamic allocation in Cairo?

    Asked

    4 months ago

    98

    views


    1

    Hello! This is day 6 of the 17 days of the Cairo Challenge. And I have no idea how to solve the playground exercise “Dynamic allocation”. Perhaps you can help me?

    // Dynamic allocation in Cairo is done using the `alloc` function,
    // which itself is implemented in Cairo using the
    // [segments](https://www.cairo-lang.org/docs/how_cairo_works/segments.html) mechanism.
    // Thanks to this mechanism, `alloc` allocates an array of an arbitrary size,
    // which does not need to be specified in the call.
    //
    // The function `sqr_array` should compute and return an array
    // of the square values of a given array.
    // Write the body of `sqr_array` using the given helper function
    // `_inner_sqr_array` and check that the program output
    // is 1, 4, 9, 16.
    // `sqr_array` should allocate the new array it returns.
    
    // Use the output builtin.
    %builtins output
    
    from starkware.cairo.common.alloc import alloc
    from starkware.cairo.common.serialize import serialize_word
    
    // Fills `new_array` with the squares of the first `length` elements in `array`.
    func _inner_sqr_array(array: felt*, new_array: felt*, length: felt) {
        if (length == 0) {
            return ();
        }
    
        assert [new_array] = [array] * [array];
    
        _inner_sqr_array(array=array + 1, new_array=new_array + 1, length=length - 1);
        return ();
    }
    
    func sqr_array(array: felt*, length: felt) -> (new_array: felt*) {
        // Write your code here.
    }
    
    func main{output_ptr: felt*}() {
        alloc_locals;
        // Allocate a new array.
        let (local array) = alloc();
        // Fill the new array with field elements.
        assert [array] = 1;
        assert [array + 1] = 2;
        assert [array + 2] = 3;
        assert [array + 3] = 4;
    
        let (new_array) = sqr_array(array=array, length=4);
        serialize_word([new_array]);
        serialize_word([new_array + 1]);
        serialize_word([new_array + 2]);
        serialize_word([new_array + 3]);
    
        return ();
    }
    

    Answers to this question are a part of the ✨ 17 days of Cairo Lang with Playground & Newton. ✨

    Vote for your favorite answer - the best answer will win a $10 award. A new day – a new reward! During the next 17 days, our goal is to attract more developers to the Cairo language and to systematize the knowledge of Cairo lang. Read rules

      #17daysOfCairocairo-beginnerscairoplayground

    Newton

    asked

    4 months ago


    2 answers

    3

    Accepted answer

    This is the solution I got to when trying to solve this challenge :)

    
    from starkware.cairo.common.alloc import alloc
    from starkware.cairo.common.serialize import serialize_word
    
    // Fills `new_array` with the squares of the first `length` elements in `array`.
    func _inner_sqr_array(array: felt*, new_array: felt*, length: felt) {
        if (length == 0) {
            return ();
        }
    
        assert [new_array] = [array] * [array];
    
        _inner_sqr_array(array=array + 1, new_array=new_array + 1, length=length - 1);
        return ();
    }
    
    func sqr_array(array: felt*, length: felt) -> (new_array: felt*) {
        alloc_locals;
        let (local new_array) = alloc();
        _inner_sqr_array(array=array, new_array=new_array, length=length);
        
        return (new_array = new_array);
    }
    
    func main{output_ptr: felt*}() {
        alloc_locals;
        // Allocate a new array.
        let (local array) = alloc();
        // Fill the new array with field elements.
        assert [array] = 1;
        assert [array + 1] = 2;
        assert [array + 2] = 3;
        assert [array + 3] = 4;
    
        let (new_array) = sqr_array(array=array, length=4);
        serialize_word([new_array]);
        serialize_word([new_array + 1]);
        serialize_word([new_array + 2]);
        serialize_word([new_array + 3]);
    
        return ();
    }
    

    answered

    3 months ago

    0

    Here is my solution ``

    // Use the output builtin.
    %builtins output
    
    from starkware.cairo.common.alloc import alloc
    from starkware.cairo.common.serialize import serialize_word
    
    
    // Fills `new_array` with the squares of the first `length` elements in `array`.
    func _inner_sqr_array(array: felt*, new_array: felt*, length: felt) {
        if (length == 0) {
            return ();
        }
    
        assert [new_array] = [array] * [array];
    
        _inner_sqr_array(array=array + 1, new_array=new_array + 1, length=length - 1);
        return ();
    }
    
    func sqr_array(array: felt*, length: felt) -> (new_array: felt*) {
        // Write your code here.
        alloc_locals;
        let (local new_array) = alloc();
         _inner_sqr_array(array=array, new_array=new_array, length=length);
         return(new_array=new_array);
    }
    
    func main{output_ptr: felt*}() {
        alloc_locals;
        // Allocate a new array.
        let (local array) = alloc();
        // Fill the new array with field elements.
        assert [array] = 1;
        assert [array + 1] = 2;
        assert [array + 2] = 3;
        assert [array + 3] = 4;
    
        let (new_array) = sqr_array(array=array, length=4);
        serialize_word([new_array]);
        serialize_word([new_array + 1]);
        serialize_word([new_array + 2]);
        serialize_word([new_array + 3]);
    
        return ();
    }
    

    Prashant Banchhor

    answered

    3 months ago

    Your answer

    NEWTON

    NEWTON