Help with seemingly easy problem [SOLVED]


#1

Problem for reference: https://i.imgur.com/KfV8Kcl.png
My working solution in D is this:

int firstDuplicate(int[] a)  {
    foreach (n; a) {
        if (a[abs(n) - 1] < 0) return abs(n);
        a[abs(n) - 1] = -a[abs(n) - 1];
    }
    return -1;
}

And my rust attempt looks like:

fn firstDuplicate(mut a: Vec<i32>) -> i32 {
    for n in a {
        if a[n.abs() - 1] < 0 { return n.abs(); }
        a[n.abs() - 1] = -a[n.abs() - 1];
    }
    -1
}

But I am not sure how to get around the usize i32 conversion, or the issues with mut and immutable borrows. I have a hashmap solution in Rust that works but I’m trying to do it as
above too.
Thanks


#2

Indexing in Rust only allows usize type currently, so you’ll need a[n as usize].

Vec<i32> argumet passes ownership of the vec, which means the caller won’t be able to use it any more. Alternative would be &mut Vec<i32> which allows you to modify and extend the vector, but not destroy it. Or &mut [i32] which allows you to mutate elements, but not grow or destroy the vector.


#3

The mutable/immutable is because the iterator over the vec borrows it immutably, but then the loop body attempts to borrow mutably to set the value. The fix is to simply use an indexed loop: for i in 0 .. vec.len() { ... }