Sha256: fbd2ff52cfd4145e3e92b1bcb04eb6e0cf369ff0209025cf0873fa30f89786df

Contents?: true

Size: 2 KB

Versions: 395

Compression:

Stored size: 2 KB

Contents

use std::collections::HashMap;

pub struct Brackets {
    raw_brackets: Vec<char>,
    pairs: MatchingBrackets,
}

impl<'a> From<&'a str> for Brackets {
    fn from(i: &str) -> Self {
        Brackets::new(String::from(i), None)
    }
}

impl Brackets {
    pub fn new(s: String, pairs: Option<Vec<(char, char)>>) -> Self {
        let p = match pairs {
            Some(x) => MatchingBrackets::from(x),
            None => MatchingBrackets::from(vec![('[', ']'), ('{', '}'), ('(', ')')]),
        };

        Brackets {
            raw_brackets: s.chars().filter(|c| p.contains(&c)).collect::<Vec<char>>(),
            pairs: p,
        }
    }

    pub fn are_balanced(&self) -> bool {
        let mut unclosed: Vec<char> = Vec::new();

        for &bracket in self.raw_brackets.iter() {
            if let Some(last_unclosed) = unclosed.pop() {
                unclosed.extend(self.pairs.unmatched(last_unclosed, bracket));
            } else {
                unclosed.push(bracket);
            }
        }

        unclosed.is_empty()
    }
}

pub struct MatchingBrackets {
    collection: HashMap<char, char>,
}

impl From<Vec<(char, char)>> for MatchingBrackets {
    fn from(v: Vec<(char, char)>) -> Self {
        MatchingBrackets { collection: v.into_iter().collect::<HashMap<char, char>>() }
    }
}

impl MatchingBrackets {
    fn contains(&self, other: &char) -> bool {
        let known = self.collection.keys().chain(self.collection.values()).collect::<Vec<_>>();
        known.contains(&other)
    }

    fn closer_for(&self, k: &char) -> Option<&char> {
        self.collection.get(k)
    }

    fn closed_by(&self, l: char, r: char) -> bool {
        match self.closer_for(&l) {
            Some(&x) => r == x,
            None => false,
        }
    }

    fn unmatched(&self, open: char, potential_close: char) -> Vec<char> {
        let mut ret: Vec<char> = Vec::new();

        if !self.closed_by(open, potential_close) {
            ret.push(open);
            ret.push(potential_close);
        }

        ret
    }
}

Version data entries

395 entries across 395 versions & 1 rubygems

Version Path
trackler-2.2.1.179 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.178 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.177 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.176 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.175 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.174 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.173 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.172 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.171 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.170 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.169 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.167 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.166 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.165 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.164 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.163 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.162 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.161 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.160 tracks/rust/exercises/bracket-push/example.rs
trackler-2.2.1.159 tracks/rust/exercises/bracket-push/example.rs