struct Solution {}
impl Solution {
    pub fn bag_of_tokens_score(mut tokens: Vec<i32>, mut power: i32) -> i32 {
        if tokens.is_empty() {
            return 0;
        }

        tokens.sort_unstable();

        let mut i = 0;
        let mut j = tokens.len() - 1;

        let mut score = 0;
        while i <= j {
            if power >= tokens[i] {
                // can trade score for power
                power -= tokens[i];
                score += 1;
                i += 1;
            } else if i < j && score > 0 {
                // can trade power for score
                score -= 1;
                power += tokens[j];
                j -= 1;
            } else {
                // no further action is possible
                break;
            }
        }

        score
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn example_1() {
        assert_eq!(Solution::bag_of_tokens_score(vec![100], 50), 0);
    }

    #[test]
    fn example_2() {
        assert_eq!(Solution::bag_of_tokens_score(vec![200, 100], 150), 1);
    }

    #[test]
    fn example_3() {
        assert_eq!(
            Solution::bag_of_tokens_score(vec![100, 200, 300, 400], 200),
            2
        );
    }
}