My (hacky) solution to 2020 Advent of Code Challenge in Rust
use std::io::{self, Read};

type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

fn main() -> Result<()> {
    let mut input = String::new();
    io::stdin().read_to_string(&mut input)?;
    let replaced_input = input.replace("-", " ").replace(":", "");

    part1(&replaced_input)?;
    part2(&replaced_input)?;
    Ok(())
}

fn part1(input: &str) -> Result<()> {
    let mut valid = 0;

    for line in input.lines() {
        let splited: Vec<&str> = line.split_whitespace().collect();
        let lower_limit: u32 = splited[0].parse().expect("This must be a number");
        let upper_limit: u32 = splited[1].parse().expect("This must be a number");
        let alphabet: char = splited[2].parse().expect("This must be a char");
        let count: u32 = splited[3].chars().filter(|&char| char == alphabet).count() as u32;

        if count >= lower_limit && count <= upper_limit {
            valid += 1;
        }
    }

    println!("{}", valid);
    Ok(())
}

fn part2(input: &str) -> Result<()> {
    let mut valid = 0;

    for line in input.lines() {
        let splited: Vec<&str> = line.split_whitespace().collect();
        let lower_limit: u32 = splited[0].parse().expect("This must be a number");
        let upper_limit: u32 = splited[1].parse().expect("This must be a number");
        let alphabet: char = splited[2].parse().expect("This must be a char");

        let password: Vec<char> = splited[3].chars().collect();
        let char_at_lower: char = password[(lower_limit - 1) as usize];
        let char_at_upper: char = password[(upper_limit - 1) as usize];

        if (char_at_lower == alphabet) ^ (char_at_upper == alphabet) {
            valid += 1;
        }
    }

    println!("{}", valid);
    Ok(())
}