Get the index of second element matching condition in a rust vec - rust

Lets say I have something like
let v: Vec<bool> = [false, true, false, true, false, false];
I want to get the position of the second "true" (So in this case get_second_index(v) should return Some(3)) Currently I'm doing the following which I think is pretty ugly:
fn get_second_index(v: Vec<bool>) -> Option<u32> {
let mut num_matching = 0;
let mut second_index = 0;
for (i, b) in v.iter().enumerate() {
if *b {
num_matching += 1;
}
if num_matching == 2 {
second_index = i;
}
}
if second_index == 0 {
return None;
}
second_index
}
Is there any more elegant, more idiomatically rust way to do this? Thanks!

You can simply .enumerate() an Iterator over the Vec to get the indices, then use .filter_map() on the enumerated iterator to get all true-values, and use .nth() on the filtered iterator to get the second match:
fn second(inp: &[bool]) -> Option<usize> {
inp.iter()
.enumerate()
.filter_map(|(idx, b)| (*b).then(|| idx))
.nth(1)
}
fn main() {
let v: Vec<bool> = vec![false, true, false, true, false, false];
assert_eq!(second(&v), Some(3));
}
Notice that this will return a Option<usize>, not an Option<u32>, as all indices are usize...

Try this
fn get_second_index(v: Vec<bool>) -> Option<usize> {
let mut matched = false;
v.iter().position(|x| {
if matched {
*x
} else {
matched = *x;
false
}
})
}

Related

Returning struct with vector

I just began learning Rust and doing some exercises.
Here I'm trying to return the next permutation. But at the end of the next() method it seems to return the wrong vector in the struct.
pub struct Permutation {
p : Vec<u8>,
}
impl Permutation{
pub fn new(length: u8) -> Permutation {
let mut p :Vec<u8> = Vec::new();
for i in 1..length+1 {
p.push(i as u8);
}
Permutation { p }
}
pub fn create(this: Vec<u8>) -> Permutation {
Permutation { p:this }
}
pub fn next(&mut self) -> Option<Permutation> {
let mut pivot :usize = self.p.len() + 1;
for i in (1..self.p.len()).rev() {
if self.p[i-1] < self.p[i] {
pivot = i-1;
break;
}
}
if pivot == self.p.len() + 1 {
return None;
}
let mut swap :usize = pivot + 1;
for i in pivot+1..self.p.len() {
if self.p[i] > self.p[pivot] && self.p[i] < self.p[swap] {
swap = i;
}
}
let temp = self.p[swap];
self.p[swap] = self.p[pivot];
self.p[pivot] = temp;
pivot += 1;
let mut new_perm :Vec<u8> = Vec::new();
for i in 0..pivot {
new_perm.push(self.p[i]);
}
for i in (pivot..self.p.len()).rev() {
new_perm.push(self.p[i]);
}
// Debug
// for e in &new_perm {
// println!("{}", e);
//}
return Some(Permutation{ p: new_perm })
}
}
If I uncomment the println I can see that the new_perm vector is correct, but I seem to be getting the self.p vector returned.
What am I doing wrong here?

Iterate through a singly linked list of Option<Rc<RefCell<Node>>> without increasing strongcount

Don't ask why I'm learning Rust using linked lists. I want to mutably iterate down a recursive structure of Option<Rc<RefCell<Node>>> while keeping the ability to swap out nodes and unwrap them. I have a singly-linked list type with a tail pointer to the last node.
pub struct List<T> {
maybe_head: Option<Rc<RefCell<Node<T>>>>,
maybe_tail: Option<Rc<RefCell<Node<T>>>>,
length: usize,
}
struct Node<T> {
value: T,
maybe_next: Option<Rc<RefCell<Node<T>>>>,
}
Let's say we have a constructor and an append function:
impl<T> List<T> {
pub fn new() -> Self {
List {
maybe_head: None,
maybe_tail: None,
length: 0,
}
}
pub fn put_first(&mut self, t: T) -> &mut Self {
let new_node_rc = Rc::new(RefCell::new(Node {
value: t,
maybe_next: mem::replace(&mut self.maybe_head, None),
}));
match self.length == 0 {
true => {
let new_node_rc_clone = new_node_rc.clone();
self.maybe_head = Some(new_node_rc);
self.maybe_tail = Some(new_node_rc_clone);
},
false => {
self.maybe_head = Some(new_node_rc);
},
}
self.length += 1;
self
}
}
I want to remove and return the final node by moving the tail pointer to its predecessor, then returning the old tail. After iterating down the list using RefCell::borrow() and Rc::clone(), the first version of remove_last() below panics when trying to unwrap the tail's Rc. How do I iterate down this recursive structure without incrementing each node's strongcount?
PANICKING VERSION
pub fn remove_last(&mut self) -> Option<T> {
let mut opt: Option<Rc<RefCell<Node<T>>>>;
if let Some(rc) = &self.maybe_head {
opt = Some(Rc::clone(rc))
} else {
return None;
};
let mut rc: Rc<RefCell<Node<T>>>;
let mut countdown_to_penultimate: i32 = self.length as i32 - 2;
loop {
rc = match opt {
None => panic!(),
Some(ref wrapped_rc) => Rc::clone(wrapped_rc),
};
match RefCell::borrow(&rc).maybe_next {
Some(ref next_rc) => {
if countdown_to_penultimate == 0 {
self.maybe_tail = Some(Rc::clone(x));
}
opt = Some(Rc::clone(next_rc));
countdown_to_penultimate -= 1;
},
None => {
let grab_tail = match Rc::try_unwrap(opt.take().unwrap()) {
Ok(something) => {
return Some(something.into_inner().value);
}
Err(_) => panic!(),
};
},
}
}
If all I do during iteration is move the tail pointer and enclose the iteration code in a {...} block to drop cloned references, I can then safely swap out and return the old tail, but this is obviously unsatisfying.
UNSATISFYING WORKING VERSION
pub fn remove_last(&mut self) -> Option<T> {
{let mut opt: Option<Rc<RefCell<Node<T>>>>;
if let Some(rc) = &self.maybe_head {
opt = Some(Rc::clone(rc))
} else {
return None;
};
let mut rc: Rc<RefCell<Node<T>>>;
let mut countdown_to_penultimate: i32 = self.length as i32 - 2;
loop {
rc = match opt {
None => panic!(),
Some(ref wrapped_rc) => Rc::clone(wrapped_rc),
};
match RefCell::borrow(&rc).maybe_next {
Some(ref next_rc) => {
if countdown_to_penultimate == 0 {
self.maybe_tail = Some(Rc::clone(&rc));
}
opt = Some(Rc::clone(next_rc));
countdown_to_penultimate -= 1;
},
None => {
break;
},
}
}}
match self.maybe_tail {
None => panic!(),
Some(ref rc) => {
let tail = mem::replace(&mut RefCell::borrow_mut(rc).maybe_next, None);
return Some(Rc::try_unwrap(tail.unwrap()).ok().unwrap().into_inner().value);
}
};
}
I wrote a List::remove_last() that I can live with, although I'd still like to know what more idiomatic Rust code here might look like. I find that this traversal idiom also extends naturally into things like removing the n-th node or removing the first node that matches some predicate.
fn remove_last(&mut self) -> Option<T> {
let mut opt: Option<Rc<RefCell<Node<T>>>>;
let mut rc: Rc<RefCell<Node<T>>>;
#[allow(unused_must_use)]
match self.length {
0 => {
return None;
}
1 => {
let head = mem::replace(&mut self.maybe_head, None);
mem::replace(&mut self.maybe_tail, None);
self.length -= 1;
return Some(
Rc::try_unwrap(head.unwrap())
.ok()
.unwrap()
.into_inner()
.value,
);
}
_ => {
opt = Some(Rc::clone(self.maybe_head.as_ref().unwrap()));
}
}
loop {
rc = match opt {
None => unreachable!(),
Some(ref wrapped_rc) => Rc::clone(wrapped_rc),
};
let mut borrowed_node = RefCell::borrow_mut(&rc);
let maybe_next = &mut borrowed_node.maybe_next;
match maybe_next {
None => unreachable!(),
Some(_)
if std::ptr::eq(
maybe_next.as_ref().unwrap().as_ptr(),
self.maybe_tail.as_ref().unwrap().as_ptr(),
) =>
{
borrowed_node.maybe_next = None;
let old_tail = self.maybe_tail.replace(Rc::clone(&rc));
self.length -= 1;
return Some(
Rc::try_unwrap(old_tail.unwrap())
.ok()
.unwrap()
.into_inner()
.value,
);
}
Some(ref next_rc) => {
opt = Some(Rc::clone(next_rc));
}
}
}
}

Tic Tac Toe - Minimax

I'm trying to build a tic-tac-toe game using minimax algorithm with rust. And I'm stuck. I tried to write a rust code based on the psudeo code on the wikipedia page. https://en.wikipedia.org/wiki/Minimax. However, it didn't work. Ai always makes the first possible move. I would be glad if you could help me.
In main.rs
fn main() {
let mut g = Game::new();
while g.game_state() == Game_State::Continuous {
g.print();
println!("{}", minimax(&g));
if g.turn == Player::Cross {
g.take_input();
}
else {
g = best_move(&g);
}
}
g.print();
if let Game_State::Win(Player::None) = g.game_state() {
println!("Draw");
}
else {
g.print_winner();
}
}
In ai.rs
pub fn child_nodes(game: &Game) -> Vec<Game> {
let mut children: Vec<Game> = Vec::new();
for r in 0..3 {
for c in 0..3 {
if game.grid[r][c] == Player::None {
let mut child = game.clone();
child.grid[r][c] = game.turn;
child.turn = reverse_player(child.turn);
children.push(child);
}
}
}
return children;
}
pub fn minimax(game: &Game) -> isize {
match game.game_state() {
Game_State::Win(winner) => to_scor(winner),
Game_State::Continuous => {
use std::cmp::{min, max};
let children_vec = child_nodes(&game);
let mut score: isize;
if game.turn == Player::Cross {
score = -2;
for i in &children_vec {
score = max(score, minimax(i));
}
}
else {
score = 2;
for i in &children_vec {
score = min(score, minimax(i));
}
}
return score;
}
}
}
pub fn best_move(game: &Game) -> Game {
let children = child_nodes(game);
let mut values: Vec<isize> = Vec::new();
for i in 0..children.len() {
values.push(minimax(&children[i]));
}
let mut index: usize = 0;
let iter = values.iter().enumerate();
if game.turn == Player::Cross {
if let Option::Some(t) = iter.max() {
index = t.0;
}
}
else if game.turn == Player::Circle {
if let Option::Some(t) = iter.min() {
index = t.0;
}
}
let best_pos = children[index];
best_pos
}
pub fn to_scor(x: Player) -> isize {
match x {
Player::Cross => 1,
Player::Circle => -1,
Player::None => 0
}
}
.enumerate() returns an iterator over tuples, and .max() and .min() on an iterator of tuples will compare the tuples - that is, (1, x) is always considered to be less than (2, y) for any values of x and y. This can be demonstrated with this snippet:
fn main() {
let v = vec![3, 1, 2, 5, 3, 6, 7, 2];
println!("{:?}", v.iter().enumerate().min());
println!("{:?}", v.iter().enumerate().max());
}
which prints:
Some((0, 3))
Some((7, 2))
which are just the first and last elements of the list (and not the minimum or maximum elements).
However, as shown here, you can use max_by to use your own function to compare the tuples.

How to lazily deserialize from a JSON array?

Problem description
Using serde_json to deserialize a very long array of objects into a Vec<T> can take a long time, because the entire array must be read into memory up front. I'd like to iterate over the items in the array instead to avoid the up-front processing and memory requirements.
My approach so far
StreamDeserializer cannot be used directly, because it can only iterate over self-delimiting types placed back-to-back. So what I've done so far is to write a custom struct to implement Read, wrapping another Read but omitting the starting and ending square brackets, as well as any commas.
For example, the reader will transform the JSON [{"name": "foo"}, {"name": "bar"}, {"name": "baz"}] into {"name": "foo"} {"name": "bar"} {"name": "baz"} so it can be used with StreamDeserializer.
Here is the code in its entirety:
use std::io;
/// An implementation of `Read` that transforms JSON input where the outermost
/// structure is an array. The enclosing brackets and commas are removed,
/// causing the items to be adjacent to one another. This works with
/// [`serde_json::StreamDeserializer`].
pub(crate) struct ArrayStreamReader<T> {
inner: T,
depth: Option<usize>,
inside_string: bool,
escape_next: bool,
}
impl<T: io::Read> ArrayStreamReader<T> {
pub(crate) fn new_buffered(inner: T) -> io::BufReader<Self> {
io::BufReader::new(ArrayStreamReader {
inner,
depth: None,
inside_string: false,
escape_next: false,
})
}
}
#[inline]
fn do_copy(dst: &mut [u8], src: &[u8], len: usize) {
if len == 1 {
dst[0] = src[0]; // Avoids memcpy call.
} else {
dst[..len].copy_from_slice(&src[..len]);
}
}
impl<T: io::Read> io::Read for ArrayStreamReader<T> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if buf.is_empty() {
return Ok(0);
}
let mut tmp = vec![0u8; buf.len()];
// The outer loop is here in case every byte was skipped, which can happen
// easily if `buf.len()` is 1. In this situation, the operation is retried
// until either no bytes are read from the inner stream, or at least 1 byte
// is written to `buf`.
loop {
let byte_count = self.inner.read(&mut tmp)?;
if byte_count == 0 {
return if self.depth.is_some() {
Err(io::ErrorKind::UnexpectedEof.into())
} else {
Ok(0)
};
}
let mut tmp_pos = 0;
let mut buf_pos = 0;
for (i, b) in tmp.iter().cloned().enumerate() {
if self.depth.is_none() {
match b {
b'[' => {
tmp_pos = i + 1;
self.depth = Some(0);
},
b if b.is_ascii_whitespace() => {},
b'\0' => break,
_ => return Err(io::ErrorKind::InvalidData.into()),
}
continue;
}
if self.inside_string {
match b {
_ if self.escape_next => self.escape_next = false,
b'\\' => self.escape_next = true,
b'"' if !self.escape_next => self.inside_string = false,
_ => {},
}
continue;
}
let depth = self.depth.unwrap();
match b {
b'[' | b'{' => self.depth = Some(depth + 1),
b']' | b'}' if depth > 0 => self.depth = Some(depth - 1),
b'"' => self.inside_string = true,
b'}' if depth == 0 => return Err(io::ErrorKind::InvalidData.into()),
b',' | b']' if depth == 0 => {
let len = i - tmp_pos;
do_copy(&mut buf[buf_pos..], &tmp[tmp_pos..], len);
tmp_pos = i + 1;
buf_pos += len;
// Then write a space to separate items.
buf[buf_pos] = b' ';
buf_pos += 1;
if b == b']' {
// Reached the end of outer array. If another array
// follows, the stream will continue.
self.depth = None;
}
},
_ => {},
}
}
if tmp_pos < byte_count {
let len = byte_count - tmp_pos;
do_copy(&mut buf[buf_pos..], &tmp[tmp_pos..], len);
buf_pos += len;
}
if buf_pos > 0 {
// If at least some data was read, return with the amount. Otherwise, the outer
// loop will try again.
return Ok(buf_pos);
}
}
}
}
It is used like so:
use std::io;
use serde::Deserialize;
#[derive(Deserialize)]
struct Item {
name: String,
}
fn main() -> io::Result<()> {
let json = br#"[{"name": "foo"}, {"name": "bar"}]"#;
let wrapped = ArrayStreamReader::new_buffered(&json[..]);
let first_item: Item = serde_json::Deserializer::from_reader(wrapped)
.into_iter()
.next()
.unwrap()?;
assert_eq!(first_item.name, "foo");
Ok(())
}
At last, a question
There must be a better way to do this, right?

It is possible to mutate the values of a for loop using pointers [duplicate]

I have a vector of structs, and I'm comparing every element in the vector against every other element, and in certain cases mutating the current element.
My issue is that you can't have both a mutable and immutable borrow happening at the same time, but I'm not sure how to reframe my problem to get around this without cloning either the current element or the entire vector, which seems like a waste since I'm only ever mutating the current element, and it doesn't need to be compared to itself (I skip that case).
I'm sure there's an idiomatic way to do this in Rust.
struct MyStruct {
a: i32,
}
fn main() {
let mut v = vec![MyStruct { a: 1 }, MyStruct { a: 2 }, MyStruct { a: 3 }];
for elem in v.iter_mut() {
for other_elem in v.iter() {
if other_elem.a > elem.a {
elem.a += 1;
}
}
}
}
The simplest way is to just use indices, which don't involve any long-lived borrows:
for i in 0..v.len() {
for j in 0..v.len() {
if i == j { continue; }
if v[j].a > v[i].a {
v[i].a += 1;
}
}
}
If you really, really want to use iterators, you can do it by dividing up the Vec into disjoint slices:
fn process(elem: &mut MyStruct, other: &MyStruct) {
if other.a > elem.a {
elem.a += 1;
}
}
for i in 0..v.len() {
let (left, mid_right) = v.split_at_mut(i);
let (mid, right) = mid_right.split_at_mut(1);
let elem = &mut mid[0];
for other in left {
process(elem, other);
}
for other in right {
process(elem, other);
}
}
If you can modify type type of v, and the elements of v are Copy, you can wrap MyStruct in Cell.
#[derive(Copy, Clone)]
struct MyStruct {
a: i32,
}
fn main() {
use std::cell::Cell;
let v = vec![
Cell::new(MyStruct { a: 1 }),
Cell::new(MyStruct { a: 2 }),
Cell::new(MyStruct { a: 3 }),
];
for elem in v.iter() {
for other_elem in v.iter() {
let mut e = elem.get();
if other_elem.get().a > e.a {
e.a += 1;
elem.set(e);
}
}
}
}
If instead you're passed a &mut to a slice (or &mut that can be converted into a slice), use Cell::from_mut and Cell::as_slice_of_cells and use the same trick as above (assuming the elements of the slice are Copy).

Resources