[Rust] Triple VecDeque
Intuition\nI know how to do this. I don\'t want to do this. I know how to do this. I don\'t want to do this.\n\n# Explaining my atrocious code\nOur VecDeques ar
# Intuition\nI know how to do this. I don\'t want to do this. I know how to do this. I don\'t want to do this.\n\n# Explaining my atrocious code\nOur VecDeques are used to maintain a sliding window, `included_left` and `included_right` include the nearest `k - max_changes` ones our window. Why `k - max_changes`? Because aside from the elements directly left/right of whats-his-face\'s index, and whatever is on his index, it\'ll always be cheapest to just use `max_changes` to spawn in ones until we have `k` ones or we run out of changes. \n\nWe also keep track of the sum of the distances from our chosen index (starting at 0) to all of the ones within our sliding windows. As we\'ll iterate from left to right, whenever we move up our index, we add one to our distance for every element in `included_left` and we subtract one for everything in `included_right`. \n\n# A seemingly simple calculation\nSo for each index, we can calculate the moves required as follows:\n\n- Decrement `k` if we start on a one.\n- Decrement `k` and add a move for each adjacent one (unless `k == 0` beforehand)\n- Let x be the number of tiles we will transform next to us, represented by `min(max_changes, k)`. Decrement `k` by `x`, and these each require two moves so increment moves by `2*x`.\n- If we still don\'t have enough ones, add the sum of the distances in our sliding window to the movecount. Make sure not to include the adjacent tiles in this.\n\nOkay, simple enough. Actually, if you understand this, most of the code is just implementing this logic, making sure to keep an accurate track of the left/right tiles, and sliding our window over when the distance between our new index and the leftmost tile of our window is greater than the would-be distance between our new index and the next one to include in our window (contained within `excluded`). Best read through the code now. Please please PLEASE leave suggestions on how to improve this if you have them, I am desperate, also leave any questions (about the algorithm or code) and I will do my best to answer.\n\n# Code\n```\nuse std::collections::VecDeque;\n\nimpl Solution {\n    pub fn minimum_moves(nums: Vec<i32>, k: i32, max_changes: i32) -> i64 {\n        let mut included_left = VecDeque::new();\n        let mut included_right = VecDeque::new();\n        let mut excluded = VecDeque::new();\n        let mut distances = 0;\n        for i in 1..nums.len() {\n            if nums[i] == 0 { continue; }\n            if included_right.len() as i32 + nums[0] < k - max_changes {\n                included_right.push_back(i as i64);\n                distances += i as i64;\n            } else {\n                excluded.push_back(i as i64);\n            }\n        }\n        \n        let mut best = i64::MAX;\n        for i in 0..nums.len() {\n            let mut moves = 0;\n            // Starting on 1: k -= 1\n            let mut k = k - nums[i];\n            // If either adjcaent cell is 1: moves -= 1 (per)\n            if k > 0 { if let Some(1) = nums.get(i-1) { moves += 1; k -= 1; } }\n            if k > 0 { if let Some(1) = nums.get(i+1) { moves += 1; k -= 1; } }\n            let initial_moves = moves;\n            let x = std::cmp::min(k, max_changes) as i64;\n            k -= x as i32;\n            moves += x*2;\n            // Remaining numbers is sum of distances to nearest numbers\n            if k > 0 { moves += (distances as i64) - initial_moves; }\n            // update best count\n            best = std::cmp::min(best, moves);\n            // always keep track of distances to k-max_changes nearest numbers\n            let next = i as i64 + 1;\n            distances -= included_right.len() as i64;\n            if nums[i] == 1 { included_left.push_back(i as i64); }\n            distances += included_left.len() as i64;\n            if included_left.len() > 0 && excluded.len() > 0 {\n                let leftmost = *included_left.front().unwrap();\n                let rightmost = *excluded.front().unwrap();\n                if next - leftmost > rightmost - next {\n                    included_left.pop_front();\n                    included_right.push_back(rightmost);\n                    excluded.pop_front();\n                    distances -= next - leftmost;\n                    distances += rightmost - next;\n                }\n            }\n            if let Some(&idx) = included_right.front() {\n                if idx == next { included_right.pop_front(); }\n            }\n        }\n        best\n        \n    }\n}\n```
['Rust']