Value moved here, in previous iteration of loop - rust

This is what I wrote for LeetCode: Add Two Numbers
//2. Add Two Numbers
// Definition for singly-linked list.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode { next: None, val }
}
}
struct Solution;
impl Solution {
pub fn list_to_num(ls: &Option<Box<ListNode>>) -> i64 {
let mut vec = vec![];
let mut head = ls;
while let Some(node) = head {
vec.push(node.val);
head = &node.next;
}
vec.reverse();
let mut num = 0i64;
for x in vec {
num *= 10;
num += x as i64;
}
num
}
pub fn num_to_list(num: i64) -> Option<Box<ListNode>> {
let num_str = num.to_string();
let vec = num_str
.chars()
.map(|x| x.to_digit(10).unwrap() as i32)
.collect::<Vec<_>>();
let mut res = None;
for x in vec {
let mut one = ListNode::new(x);
one.next = res;
res = Some(Box::new(one));
}
res
}
pub fn add_two_numbers(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut vec = vec![] as Vec<i32>;
let mut step = 0;
let mut left = l1;
let mut right = l2;
loop {
match (left, right) {
(None, None) => {
if step != 0 {
vec.push(step);
}
break;
}
(Some(leftN), None) => {
let curr = leftN.val + step;
if curr >= 10 {
vec.push(curr - 10);
step = 1
} else {
vec.push(curr);
step = 0
}
left = leftN.next
}
(None, Some(rightN)) => {
let curr = rightN.val + step;
if curr >= 10 {
vec.push(curr - 10);
step = 1
} else {
vec.push(curr);
step = 0
}
right = rightN.next
}
(Some(leftN), Some(rightN)) => {
let curr = leftN.val + rightN.val + step;
if curr >= 10 {
vec.push(curr - 10);
step = 1
} else {
vec.push(curr);
step = 0
}
right = rightN.next;
left = leftN.next
}
}
}
vec.reverse();
let mut res = None;
for x in vec {
let mut next = ListNode::new(x);
next.next = res;
res = Some(Box::new(next));
}
res
}
}
fn main() {
let list1 = Solution::num_to_list(9);
let list2 = Solution::num_to_list(991);
println!("list1 {:?}", list1);
println!("list2 {:?}", list2);
let res = Solution::add_two_numbers(list1, list2);
println!("summed {:#?}", res);
}
I get a compile error
error[E0382]: use of moved value: `left`
--> src/main.rs:66:20
|
63 | let mut left = l1;
| -------- move occurs because `left` has type `std::option::Option<std::boxed::Box<ListNode>>`, which does not implement the `Copy` trait
...
66 | match (left, right) {
| ^^^^ value moved here, in previous iteration of loop
error[E0382]: use of moved value: `right`
--> src/main.rs:66:26
|
64 | let mut right = l2;
| --------- move occurs because `right` has type `std::option::Option<std::boxed::Box<ListNode>>`, which does not implement the `Copy` trait
65 | loop {
66 | match (left, right) {
| ^^^^^ value moved here, in previous iteration of loop
I think each iteration is independent, and if the value is borrowed by a previous iteration, it should be returned in "this" iteration.
If I replace match (left, right) { with match (left.clone(), right.clone()) {, the code compiles, but it might consume more memory than necessary. What is the better way to make it compile and be memory economical?

You're not borrowing the nodes, you're moving them.
In order to use references, you should replace
let mut left = l1;
let mut right = l2;
with
let mut left = &l1;
let mut right = &l2;
and then later
right = rightN.next;
with
right = &rightN.next;
etc.
playground

Related

How to fix "borrowed value does not live long enough" issue in rust

I have been writing a brainf*ck interpreter in rust, and was stupid enough to not use a lexer.
I use recursion to tackle loops.
let mut ret = exec(i, file, tape, ptr);
i = &(ret.0);
file = &mut (ret.1);
tape = &mut (ret.2);
ptr = &(ret.3);
...
return (nw_i, (*file).to_owned(), (*tape).to_owned(), nw_ptr);
This is the function declaration:
pub fn exec(mut i: &usize, mut file: &mut Vec<u8>, mut tape: &mut Vec<i32>, mut ptr: &usize) -> (usize, Vec<u8>, Vec<i32>, usize) {
I get this error:
error[E0597]: `ret.0` does not live long enough
--> src/lib.rs:19:10
|
4 | pub fn exec(mut i: &usize, mut file: &mut Vec<u8>, tape: &mut Vec<i32>, mut ptr: &usize) -> (usize, Vec<u8>, Vec<i32>, usize) {
| - let's call the lifetime of this reference `'1`
...
19 | i = &(ret.0);
| ----^^^^^^^^
| | |
| | borrowed value does not live long enough
| assignment requires that `ret.0` is borrowed for `'1`
...
23 | }
|
How do i make the borrowed value live long enough for me to copy it.
Full code:
pub fn exec(
mut i: &usize,
mut file: &mut Vec<u8>,
mut tape: &mut Vec<i32>,
mut ptr: &usize,
) -> (usize, Vec<u8>, Vec<i32>, usize) {
let char = file[*i];
let mut nw_ptr: usize = *ptr;
let mut nw_i: usize = *i;
if char == ("[".as_bytes()[0]) {
let mut j = 1;
let mut lcl_char = file[*i];
while tape[*ptr] != 0 {
while j <= 0 {
if lcl_char == ("]".as_bytes()[0]) {
j = j - 1;
} else if lcl_char == ("]".as_bytes()[0]) {
j = j + 1;
}
let mut ret = exec(i, file, tape, ptr);
i = &(ret.0);
file = &mut (ret.1);
tape = &mut (ret.2);
ptr = &(ret.3);
}
}
} else if char == (">".as_bytes()[0]) {
nw_ptr = ptr + 1;
if ptr > &(tape.len() - 1) {
tape.push(0);
}
} else if char == ("<".as_bytes()[0]) {
nw_ptr = ptr - 1;
} else if char == (".".as_bytes()[0]) {
let crnt = tape[*ptr];
let out = ascii_converter::decimals_to_string(&vec![crnt.try_into().unwrap()]).unwrap();
println!("{}", out);
} else if char == ("+".as_bytes()[0]) {
tape[*ptr] += 1;
} else if char == ("-".as_bytes()[0]) {
tape[*ptr] = tape[*ptr] - 1;
}
nw_i = i + 1;
(nw_i, (*file).to_owned(), (*tape).to_owned(), nw_ptr)
}
I already tried dereferencing it as i saw people online using it:
let mut *ret = exec(i, file, tape, ptr);
i = &(ret.0);
file = &mut (ret.1);
tape = &mut (ret.2);
ptr = &(ret.3);
But this gave this error:
error: expected identifier, found `*`
--> src/lib.rs:18:13
|
18 | let mut *ret = exec(i, file, tape, ptr);
| ^ expected identifier

SHA3-512 NIST FIPS PUB 202 in rust

I'm attempting to implement SHA3-512 the way it is done by NIST in FIPS PUB 202:
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf.
It works whenever I plug in the test vector's bit values + "01"(look for HERE in code), and for the blank value test case.
Example working test vector:
https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA3-512_Msg5.pdf
For some reason, whenever string values such as "abc" are plugged in, the hash function fails to work. Despite the conversion from string to binary string being fine, I believe the issue is with the padding function but I cant see where I messed up.
/* Keccak */
struct Keccak<'a> {
b: usize,
d: usize,
r: usize,
l: usize,
w: usize,
delim: &'a str,
}
impl Keccak<'_> {
pub fn new(digest: usize, bits: usize, delim: &str) -> Keccak {
Keccak {
b: bits,
d: digest,
r: (bits - digest * 2),
w: bits / 25,
l: (((bits / 25) as f32).log2()) as usize,
delim,
}
}
pub fn hash(&mut self, msg: &mut String) {
self.sponge(msg);
}
// SPONGE the provided string of binary m
fn sponge(&mut self, msg: &mut String) {
// Pad the message using pad10*1
// HERE: let mut msg = &mut String::from("01");
let len = msg.len() as isize;
self.pad101(msg, self.r as isize, len);
// Let n be size of P
let n = msg.len() / self.r;
// Create vector s of size b/8, each value is a byte
let mut s: Vec<String> = vec!["0".repeat(8); self.b / 8];
// Xor s and p for every p in P
let c = self.b - self.r;
for i in 0..n {
// let p be the message of len(r) + 0^c of size b
let p = format!("{}{}", &msg[i * self.r..(i + 1) * self.r], "0".repeat(c));
// Xor s and p in byte sized intervals, then do a round of keccakf
s = self.keccackf(
&(0..p.len())
.step_by(8)
.map(|x| {
format!(
"{:08?}",
p[x..x + 8].parse::<u32>().unwrap() ^ s[x / 8].parse::<u32>().unwrap()
)
})
.collect::<Vec<String>>()
.join(""),
);
let mut z = String::new();
while z.len() <= self.d {
let mut str = s.join("");
str.truncate(self.r);
z += &str;
s = self.keccackf(&(s.join("")));
}
z.truncate(self.d);
self.from_bin_string(&z);
}
}
// Convert string m to state array
fn to_state(&self, msg: &str) -> Vec<Vec<Vec<u8>>> {
let mut s: Vec<Vec<Vec<u8>>> = Vec::new();
for x in 0..5 {
let mut row = Vec::new();
for y in 0..5 {
let mut column = Vec::new();
for z in 0..self.w {
let i = self.w * (5 * y + x) + z;
column.push(msg[i..i + 1].parse::<u8>().unwrap());
}
row.push(column)
}
s.push(row);
}
s
}
// Convert state array to vector of string
fn from_state(&self, state: Vec<Vec<Vec<u8>>>) -> Vec<String> {
let mut result: Vec<String> = Vec::new();
let mut temp = String::new();
for i in 0..5 {
for j in 0..5 {
for w in 0..self.w {
temp += &format!("{}", state[j][i][w]);
if (temp.len() == 8) {
result.push(temp.clone());
temp = String::new();
}
}
}
}
result
}
fn theta(&self, state: &mut Vec<Vec<Vec<u8>>>) {
// C NIST
fn c(x: usize, z: usize, state: &Vec<Vec<Vec<u8>>>) -> u8 {
state[x][0][z] ^ state[x][1][z] ^ state[x][2][z] ^ state[x][3][z] ^ state[x][4][z]
}
// D NIST
fn d(x: usize, z: usize, state: &Vec<Vec<Vec<u8>>>, w: isize) -> u8 {
c(((x as isize) - 1).rem_euclid(5) as usize, z, state)
^ c(
(x + 1).rem_euclid(5),
((z as isize) - 1).rem_euclid(w) as usize,
state,
)
}
// Let s be a'
let mut s = vec![vec![vec![0; self.w]; 5]; 5];
// Save xor'd values into a'
for x in 0..5 {
for y in 0..5 {
for z in 0..self.w {
s[x][y][z] = state[x][y][z] ^ d(x, z, &state, self.w as isize);
}
}
}
s.clone_into(state);
}
fn rho(&self, state: &mut Vec<Vec<Vec<u8>>>) {
// Let s be a'
let mut s = vec![vec![vec![0; self.w]; 5]; 5];
// Set all z values of a' = a
state[0][0].clone_into(&mut s[0][0]);
// Let coords represent (x, y)
let mut coords = [1, 0];
for t in 0..24 {
for z in 0..self.w {
s[coords[0]][coords[1]][z] = state[coords[0]][coords[1]]
[((z as isize) - (t + 1) * (t + 2) / 2).rem_euclid(self.w as isize) as usize];
}
coords = [coords[1], (2 * coords[0] + 3 * coords[1]).rem_euclid(5)];
}
s.clone_into(state);
}
fn pi(&self, state: &mut Vec<Vec<Vec<u8>>>) {
let mut s: Vec<Vec<Vec<u8>>> = Vec::new();
for x in 0..5 {
let mut row = Vec::new();
for y in 0..5 {
let mut column = Vec::new();
for z in 0..self.w {
column.push(state[((x as usize) + 3 * y).rem_euclid(5)][x][z]);
}
row.push(column)
}
s.push(row);
}
s.clone_into(state)
}
fn chi(&self, state: &mut Vec<Vec<Vec<u8>>>) {
let mut s: Vec<Vec<Vec<u8>>> = Vec::new();
for x in 0..5 {
let mut row = Vec::new();
for y in 0..5 {
let mut column = Vec::new();
for z in 0..self.w {
column.push(
state[x][y][z]
^ ((state[(x + 1).rem_euclid(5)][y][z] ^ 1)
* state[(x + 2).rem_euclid(5)][y][z]),
);
}
row.push(column)
}
s.push(row);
}
s.clone_into(state)
}
fn rc(&self, t: usize) -> u8 {
if t.rem_euclid(255) == 0 {
return 1;
}
let mut r = std::collections::VecDeque::new();
r.extend(
"10000000"
.chars()
.map(|x| x.to_string().parse::<u8>().unwrap()),
);
for _ in 0..t.rem_euclid(255) {
r.push_front(0);
r[0] ^= r[8];
r[4] ^= r[8];
r[5] ^= r[8];
r[6] ^= r[8];
r.truncate(8);
}
return r[0];
}
fn iota(&self, state: &mut Vec<Vec<Vec<u8>>>, round: usize) {
let mut r: Vec<u8> = vec![0; self.w];
for j in 0..=self.l {
r[((2 as isize).pow(j as u32) - 1) as usize] = self.rc(j + 7 * round);
}
for z in 0..self.w {
state[0][0][z] ^= r[z];
}
}
fn keccackf(&self, msg: &str) -> Vec<String> {
let mut state = self.to_state(msg);
// Go through all the rounds
for r in 0..(12 + 2 * self.l) {
self.theta(&mut state);
self.rho(&mut state);
self.pi(&mut state);
self.chi(&mut state);
self.iota(&mut state, r);
}
let res = self.from_state(state);
res
}
// Pad10*1
fn pad101(&mut self, msg: &mut String, x: isize, m: isize) {
let j = (-m - 2).rem_euclid(x);
msg.push_str("1");
msg.push_str(&"0".repeat(j as usize));
msg.push('1');
}
// For nist test vectors
fn from_bin_string(&self, str: &str) {
let z = (0..str.len())
.step_by(8)
.map(|i| (&str[i..i + 8]).chars().rev().collect::<String>())
.collect::<Vec<String>>();
for i in 0..z.len() {
print!("{:02x}", u32::from_str_radix(&z[i], 2).unwrap());
}
}
}
/* Sha3 */
pub struct SHA3<'a> {
kec: Option<Keccak<'a>>,
}
impl SHA3<'_> {
// Creates new hash variable with default hash function, currently SHA512
pub fn new() -> SHA3<'static> {
SHA3 { kec: None }
}
// Sha512
fn SHA512(&mut self, mut msg: String) {
match self.kec.as_mut() {
// Provided kec hash msg
Some(kec) => kec.hash(&mut msg),
// Otherwise create new kec and call function again
None => {
// Creating new keccack struct, l & w & state are defined in NIST
self.kec = Some(Keccak::new(512, 1600, "0110"));
self.SHA512(msg)
}
}
}
// Return hashed vector
pub fn hash(&mut self, m: &str) {
self.SHA512(self.to_bin_string(m) + "01");
}
// Return hexdigest output
pub fn hexdigest(&self, m: &str) {}
// Convert string slice to binary string
fn to_bin_string(&self, str: &str) -> String {
String::from(str)
.as_bytes()
.into_iter()
.map(|x| format!("{:08b}", x))
.collect::<Vec<String>>()
.join("")
}
}

Mutable borrow occurs here [E0502]

How can I correct this behavior ?
P.S Now I am trying to implement a search for the number of page_faults when using the FIFO algorithm
fn page_fault(capacity: i32, n: i32, pages: &[i32]) -> i32 {
let mut s: HashSet<i32> = HashSet::new();
let mut indexes: VecDeque<i32> = VecDeque::new();
let mut page_faults: i32 = 0;
for i in 0..n {
if (s.len() as i32) < capacity {
if s.contains(&pages[(i) as usize]) {
s.insert(pages[(i) as usize]);
page_faults += 1;
indexes.insert(i as usize, pages[(i) as usize])
}
}
else {
if s.contains(&pages[(i) as usize]) {
let val = indexes.front();
indexes.pop_front();
s.remove(&val.unwrap());
s.insert(pages[(i) as usize]);
indexes.push_back(pages[(i) as usize]);
page_faults += 1;
}
}
}
return page_faults;
}
Terminal:
let val = indexes.front();
--------------- immutable borrow occurs here
indexes.pop_front();
^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
s.remove(&val.unwrap());
--- immutable borrow later used here
Calling indexes.front() seems redundant to me. You can simply use the result of indexes.pop_front() and assign it to a variable. So you can replace these two lines:
let val = indexes.front();
indexes.pop_front();
With this line:
let val = indexes.pop_front();
When calling indexes.front you are keeping a reference to it (&self), it can be easily solved by unwraping inmediatly and dereferencing it so the i32 is copied. Then the reference is freed.
use std::collections::VecDeque;
use std::collections::HashSet;
fn page_fault(capacity: i32, n: i32, pages: &[i32]) -> i32 {
let mut s: HashSet<i32> = HashSet::new();
let mut indexes: VecDeque<i32> = VecDeque::new();
let mut page_faults: i32 = 0;
for i in 0..n {
if (s.len() as i32) < capacity {
if s.contains(&pages[(i) as usize]) {
s.insert(pages[(i) as usize]);
page_faults += 1;
indexes.insert(i as usize, pages[(i) as usize])
}
}
else {
if s.contains(&pages[(i) as usize]) {
let val = *indexes.front().unwrap();
indexes.pop_front();
s.remove(&val);
s.insert(pages[(i) as usize]);
indexes.push_back(pages[(i) as usize]);
page_faults += 1;
}
}
}
return page_faults;
}
Playground

Is it possible to create a mutable value of a mutable reference in a pattern?

When pattern-matching, you can specify that you'd like to get a mutable reference to the contained value by using ref mut:
let mut score = Some(42);
if let Some(ref mut s) = score {
&mut s;
}
However, the inner value is not mutable:
error[E0596]: cannot borrow immutable local variable `s` as mutable
--> src/main.rs:4:14
|
4 | &mut s;
| ^
| |
| cannot reborrow mutably
| try removing `&mut` here
I tried to add in another mut, but that was not valid:
if let Some(mut ref mut s) = score {
&mut s;
}
error: the order of `mut` and `ref` is incorrect
--> src/main.rs:3:17
|
3 | if let Some(mut ref mut s) = score {
| ^^^^^^^ help: try switching the order: `ref mut`
error: expected identifier, found keyword `mut`
--> src/main.rs:3:25
|
3 | if let Some(mut ref mut s) = score {
| ^^^ expected identifier, found keyword
error: expected one of `)`, `,`, or `#`, found `s`
--> src/main.rs:3:29
|
3 | if let Some(mut ref mut s) = score {
| ^ expected one of `)`, `,`, or `#` here
Not a direct answer, but possible workarounds
Create an intermediate variable
if let Some(ref mut s) = score {
let mut s = s;
&mut s;
}
#[derive(Debug)]
struct X;
enum Foo<T> {
Bar(T),
_Baz,
}
fn main() {
let mut score = Foo::Bar(X);
if let Foo::Bar(ref mut s) = score {
//let x = s;
//println!("{:?}", **x); ! not possible
let x = &mut &mut *s; // &mut &mut X
println!("{:?}", **x);
}
}
For Option specifically
if let Some(ref mut s) = score.as_mut() {
s; //:&mut &mut i32
}
if let Some(mut s) = score.as_mut() {
&mut s;
}
Below code may give an idea for the possible solution to the problem. It's just a sample & testable code to provide a tiny example that aimed at the issue. Of course it may not cover the whole intents and purposes.
fn main() {
let mut score = Some(42i32);
let res = if let Some(41) = score {
println!("41 is matched");
1i32
} else if let Some(ref mut s) = score { //&mut score {
//let mut s2 = s;
//println!("s: {:#?}", s);
test(&mut &mut *s); // This part may be like this for borrowing
//println!("s: {:#?}", s);
1i32
} else {
0i32
};
//println!("Result: {:#?}", score);
assert_eq!(res, 1i32);
}
fn test(ref mut s: &mut &mut i32) -> i32 {
//let mut s2 = s;
return test2(&mut *s);
}
fn test2(n: &mut i32) -> i32 {
*n += 1;
//println!("Value: {}", *(*n));
return *n;
}
Live Version: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7c3e7e1ee712a31f74b201149365035f
Gist Link: https://gist.github.com/7c3e7e1ee712a31f74b201149365035f

error: non-scalar cast: `core::option::Option<i32>` as `usize`

I am new to Rust. My code is given below:
use std::*;
fn DFS(A: i32, grid: &mut [[i32; 500]; 500], visited: &mut [i32; 500]) -> (usize, usize) {
let mut s = Vec::new();
s.push(A);
visited[A as usize] = 1;
let mut flag;
let mut max_height = 0;
let mut ans_vertex: usize = A as usize;
let mut x;
'outer: while let Some(top) = s.pop() {
s.push(top);
x = top as usize;
flag = 0;
'inner: for i in 1..500 {
if visited[grid[x][i] as usize] == 0 && grid[x][i] != 0 {
flag = 1;
s.push(grid[x][i]);
visited[grid[x][i] as usize] = 1;
break 'outer;
}
}
if s.len() > max_height {
max_height = s.len();
ans_vertex = s.pop() as usize;
}
if flag != 0 {
s.pop();
}
}
println!("{}, {}", ans_vertex, max_height);
return (ans_vertex, max_height);
}
fn fc(grid: &mut [[i32; 500]; 500]) {
for i in 1..500 {
for j in 1..500 {
grid[i][j] = 0;
}
}
grid[1][2] = 1;
grid[2][1] = 1;
grid[2][3] = 1;
grid[3][2] = 1;
grid[3][4] = 1;
grid[4][3] = 1;
}
fn main() {
let mut visited: [i32; 500] = [0; 500];
let mut grid: [[i32; 500]; 500] = [[0; 500]; 500];
fc(&mut grid);
let B = DFS(1, &mut grid, &mut visited);
println!("{}", B.0);
}
I already tried changing usize to u32 and other types, but I'm not getting any results. When I run rustc newdia.rs, it shows:
newdia.rs:26:17: 26:33 error: non-scalar cast: `core::option::Option<i32>` as `usize`
newdia.rs:26 ans_vertex = s.pop() as usize;
^~~~~~~~~~~~~~~~
error: aborting due to previous error
Vec::pop() returns an Option<T> because if the Vec is empty, there's no value present to pop. If you're sure your Vec contains atleast 1 value before you call Vec::pop(), you can use Option::unwrap(), which will convert your Option<i32> to i32 (and panic if Vec::pop returned None because the Vec was empty).
ans_vertex = s.pop().unwrap() as usize;
You can also choose to handle the cases differently using match or if let:
if let Some(popped) = s.pop() {
// Successfully popped `popped`. `popped` here is an i32.
} else {
// `s` was empty.
}

Resources