You are given a string `s`

consisting of `n`

characters which are either `'X'`

or `'O'`

.

A **move** is defined as selecting **three** **consecutive characters** of `s`

and converting them to `'O'`

. Note that if a move is applied to the character `'O'`

, it will stay the **same**.

Return *the minimum number of moves required so that all the characters of *

`s`

`'O'`

.

**Example 1:**

Input:s = "XXX"Output:1Explanation:XXX-> OOO We select all the 3 characters and convert them in one move.

**Example 2:**

Input:s = "XXOX"Output:2Explanation:XXOX -> OOOX-> OOOO We select the first 3 characters in the first move, and convert them to`'O'`

. Then we select the last 3 characters and convert them so that the final string contains all`'O'`

s.

**Example 3:**

Input:s = "OOOO"Output:0Explanation:There are no`'X's`

in`s`

to convert.

**Constraints:**

`3 <= s.length <= 1000`

`s[i]`

is either`'X'`

or`'O'`

.

```
struct Solution;
impl Solution {
fn minimum_moves(s: String) -> i32 {
let mut s: Vec<char> = s.chars().collect();
let n = s.len();
let mut res = 0;
for i in 0..n {
if s[i] == 'X' {
res += 1;
s[i] = 'O';
if i + 1 < n {
s[i + 1] = 'O';
}
if i + 2 < n {
s[i + 2] = 'O';
}
}
}
res
}
}
#[test]
fn test() {
let s = "XXX".to_string();
let res = 1;
assert_eq!(Solution::minimum_moves(s), res);
let s = "XXOX".to_string();
let res = 2;
assert_eq!(Solution::minimum_moves(s), res);
let s = "OOOO".to_string();
let res = 0;
assert_eq!(Solution::minimum_moves(s), res);
}
```