• 10 Posts
  • 50 Comments
Joined 1 year ago
cake
Cake day: June 21st, 2023

help-circle
  • You know, I wish I could enjoy IRC - or chatrooms in general. But I just struggle with them. Forums and their ilk, I get. I check in on them and see what’s been posted since I last visited, and reply to anything that motivates me to do so. Perhaps I’ll even throw a post up myself once in a while.

    But with IRC, Matrix, Discord, etc, I just feel like I only ever enter in the middle of an existing conversation. It’s fine on very small rooms where it’s almost analagous to a forum because there’s little enough conversation going on that it remains mostly asynchronous. But larger chatrooms are just a wall of flowing conversation that I struggle to keep up with, or find an entry point.

    Anyway - to answer the actual question, I use something called “The Lounge” which I host on my VPS. I like it because it remains online even when I am not, so I can atleast view some of the history of any conversation I do stumble across when I go on IRC. I typically just use the web client that comes with it.



  • Love this. Always interesting to see novel ways of querying data in the terminal, and I agree that jq’s syntax is difficult to remember.

    I actually prefer nu(shell) for this though. On the lobste.rs thread for this blog, a user shared this:

    | get license.key -i
    | uniq --count
    | rename license
    
    This outputs the following:
    
    ╭───┬──────────────┬───────╮
    │ # │    license   │ count │
    ├───┼──────────────┼───────┤
    │ 0 │ bsd-3-clause │    23 │
    │ 1 │ apache-2.0   │     5 │
    │ 2 │              │     2 │
    ╰───┴──────────────┴───────╯
    
    
















  • Care to give a summary on why you think they should be blocked ahead of any bad acting? Yes, there is some concern about Meta attempting EEE, but ultimately they’re a large platform that can bring a lot of users and attention to the Fediverse. There’s nothing preventing large instances from blocking them down the line, and with user level instance blocking coming in 0.19 to Lemmy (not sure if Mastodon et al have something similar), you can block them personally yourself if you wish, rather than having that thrust upon you by your instance admins.


  • I particularly enjoyed a recent company meeting that spent considerable time talking about the importance of flow state. It had an awkward pregnant pause when someone (usually very quiet) unmuted to ask, “is the policy to increase the number of days we must spend in our open-plan office kind of undermining this?”. Literally all of our directors just shifted on their seats hoping another would answer that.

    Eventually, HR director stated “Not at all, that’s what headphones are for!”

    Which was particularly delightful, as our tech director had only 20 minutes before stated how he would like to discourage people sitting in the office in silos with their headphones on.


  • Today’s problems felt really refreshing after yesterday.

    Solution in Rust 🦀

    View formatted code on GitLab

    Code
    use std::{
        collections::HashSet,
        env, fs,
        io::{self, BufRead, BufReader, Read},
    };
    
    fn main() -> io::Result<()> {
        let args: Vec = env::args().collect();
        let filename = &args[1];
        let file1 = fs::File::open(filename)?;
        let file2 = fs::File::open(filename)?;
        let reader1 = BufReader::new(file1);
        let reader2 = BufReader::new(file2);
    
        println!("Part one: {}", process_part_one(reader1));
        println!("Part two: {}", process_part_two(reader2));
        Ok(())
    }
    
    fn parse_data(reader: BufReader) -> Vec> {
        let lines = reader.lines().flatten();
        let data: Vec<_> = lines
            .map(|line| {
                line.split(':')
                    .last()
                    .expect("text after colon")
                    .split_whitespace()
                    .map(|s| s.parse::().expect("numbers"))
                    .collect::>()
            })
            .collect();
        data
    }
    
    fn calculate_ways_to_win(time: u64, dist: u64) -> HashSet {
        let mut wins = HashSet::::new();
        for t in 1..time {
            let d = t * (time - t);
            if d > dist {
                wins.insert(t);
            }
        }
        wins
    }
    
    fn process_part_one(reader: BufReader) -> u64 {
        let data = parse_data(reader);
        let results: Vec<_> = data[0].iter().zip(data[1].iter()).collect();
        let mut win_method_qty: Vec = Vec::new();
        for r in results {
            win_method_qty.push(calculate_ways_to_win(*r.0, *r.1).len() as u64);
        }
        win_method_qty.iter().product()
    }
    
    fn process_part_two(reader: BufReader) -> u64 {
        let data = parse_data(reader);
        let joined_data: Vec<_> = data
            .iter()
            .map(|v| {
                v.iter()
                    .map(|d| d.to_string())
                    .collect::>()
                    .join("")
                    .parse::()
                    .expect("all digits")
            })
            .collect();
    
        calculate_ways_to_win(joined_data[0], joined_data[1]).len() as u64
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
    
        const INPUT: &str = "Time:      7  15   30
    Distance:  9  40  200";
    
        #[test]
        fn test_process_part_one() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(288, process_part_one(BufReader::new(input_bytes)));
        }
    
        #[test]
        fn test_process_part_two() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(71503, process_part_two(BufReader::new(input_bytes)));
        }
    }
    

  • Like many others, I really didn’t enjoy this one. I particularly struggled with part 02, which ended up with me just brute forcing it and checking each seed. On my system it took over 15 minutes to run, which is truly awful. I’m open to pointers on how I could better have solved part two.

    Solution in Rust 🦀

    Formatted Solution on GitLab

    Code
    use std::{
        env, fs,
        io::{self, BufReader, Read},
    };
    
    fn main() -> io::Result<()> {
        let args: Vec = env::args().collect();
        let filename = &args[1];
        let file1 = fs::File::open(filename)?;
        let file2 = fs::File::open(filename)?;
        let mut reader1 = BufReader::new(file1);
        let mut reader2 = BufReader::new(file2);
    
        println!("Part one: {}", process_part_one(&mut reader1));
        println!("Part two: {}", process_part_two(&mut reader2));
        Ok(())
    }
    
    #[derive(Debug)]
    struct Map {
        lines: Vec,
    }
    
    impl Map {
        fn map_to_lines(&self, key: u32) -> u32 {
            for line in &self.lines {
                if line.in_range(key) {
                    return line.map(key);
                }
            }
            key
        }
    }
    
    #[derive(Debug)]
    struct MapLine {
        dest_range: u32,
        source_range: u32,
        range_length: u32,
    }
    
    impl MapLine {
        fn map(&self, key: u32) -> u32 {
            let diff = key - self.source_range;
            if self.dest_range as i64 + diff as i64 > 0 {
                return (self.dest_range as i64 + diff as i64) as u32;
            }
            key
        }
    
        fn in_range(&self, key: u32) -> bool {
            self.source_range <= key
                && (key as i64) < self.source_range as i64 + self.range_length as i64
        }
    }
    
    fn parse_input(reader: &amp;mut BufReader) -> (Vec, Vec<map>) {
        let mut almanac = String::new();
        reader
            .read_to_string(&amp;mut almanac)
            .expect("read successful");
        let parts: Vec&lt;&amp;str> = almanac.split("\n\n").collect();
        let (seeds, others) = parts.split_first().expect("at least one part");
        let seeds: Vec&lt;_> = seeds
            .split(": ")
            .last()
            .expect("at least one")
            .split_whitespace()
            .map(|s| s.to_string())
            .collect();
        let maps: Vec&lt;_> = others
            .iter()
            .map(|item| {
                let lines_iter = item
                    .split(':')
                    .last()
                    .expect("exists")
                    .trim()
                    .split('\n')
                    .map(|nums| {
                        let nums_split = nums.split_whitespace().collect::>();
                        MapLine {
                            dest_range: nums_split[0].parse().expect("is digit"),
                            source_range: nums_split[1].parse().expect("is digit"),
                            range_length: nums_split[2].parse().expect("is digit"),
                        }
                    });
                Map {
                    lines: lines_iter.collect(),
                }
            })
            .collect();
        (seeds, maps)
    }
    
    fn process_part_one(reader: &amp;mut BufReader) -> u32 {
        let (seeds, maps) = parse_input(reader);
        let mut res = u32::MAX;
        for seed in &amp;seeds {
            let mut val = seed.parse::().expect("is digits");
            for map in &amp;maps {
                val = map.map_to_lines(val);
            }
            res = u32::min(res, val);
        }
        res
    }
    
    fn process_part_two(reader: &amp;mut BufReader) -> u32 {
        let (seeds, maps) = parse_input(reader);
        let seed_chunks: Vec&lt;_> = seeds.chunks(2).collect();
        let mut res = u32::MAX;
        for chunk in seed_chunks {
            let range_start: u32 = chunk[0].parse().expect("is digits");
            let range_length: u32 = chunk[1].parse().expect("is digits");
            let range_end: u32 = range_start + range_length;
            for seed in range_start..range_end {
                let mut val = seed;
                for map in &amp;maps {
                    val = map.map_to_lines(val);
                }
                res = u32::min(res, val);
            }
        }
        res
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
    
        const INPUT: &amp;str = "seeds: 79 14 55 13
    
    seed-to-soil map:
    50 98 2
    52 50 48
    
    soil-to-fertilizer map:
    0 15 37
    37 52 2
    39 0 15
    
    fertilizer-to-water map:
    49 53 8
    0 11 42
    42 0 7
    57 7 4
    
    water-to-light map:
    88 18 7
    18 25 70
    
    light-to-temperature map:
    45 77 23
    81 45 19
    68 64 13
    
    temperature-to-humidity map:
    0 69 1
    1 0 69
    
    humidity-to-location map:
    60 56 37
    56 93 4";
    
        #[test]
        fn test_process_part_one() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(35, process_part_one(&amp;mut BufReader::new(input_bytes)));
        }
    
        #[test]
        fn test_process_part_two() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(46, process_part_two(&amp;mut BufReader::new(input_bytes)));
        }
    }
    

    :::</map>



  • Late as always (actually a day late by UK time).

    My solution to this one runs slow, but it gets the job done. I didn’t actually need the CardInfo struct by the time I was done, but couldn’t be bothered to remove it. Previously, it held more than just count.

    Day 04 in Rust 🦀

    View formatted on GitLab

    use std::{
        collections::BTreeMap,
        env, fs,
        io::{self, BufRead, BufReader, Read},
    };
    
    fn main() -> io::Result&lt;()> {
        let args: Vec = env::args().collect();
        let filename = &amp;args[1];
        let file1 = fs::File::open(filename)?;
        let file2 = fs::File::open(filename)?;
        let reader1 = BufReader::new(file1);
        let reader2 = BufReader::new(file2);
    
        println!("Part one: {}", process_part_one(reader1));
        println!("Part two: {}", process_part_two(reader2));
        Ok(())
    }
    
    fn process_part_one(reader: BufReader) -> u32 {
        let mut sum = 0;
        for line in reader.lines().flatten() {
            let card_data: Vec&lt;_> = line.split(": ").collect();
            let all_numbers = card_data[1];
            let number_parts: Vec> = all_numbers
                .split('|')
                .map(|x| {
                    x.replace("  ", " ")
                        .split_whitespace()
                        .map(|val| val.to_string())
                        .collect()
                })
                .collect();
            let (winning_nums, owned_nums) = (&amp;number_parts[0], &amp;number_parts[1]);
            let matches = owned_nums
                .iter()
                .filter(|num| winning_nums.contains(num))
                .count();
            if matches > 0 {
                sum += 2_u32.pow((matches - 1) as u32);
            }
        }
        sum
    }
    
    #[derive(Debug)]
    struct CardInfo {
        count: u32,
    }
    
    fn process_part_two(reader: BufReader) -> u32 {
        let mut cards: BTreeMap = BTreeMap::new();
        for line in reader.lines().flatten() {
            let card_data: Vec&lt;_> = line.split(": ").collect();
            let card_id: u32 = card_data[0]
                .replace("Card", "")
                .trim()
                .parse()
                .expect("is digit");
            let all_numbers = card_data[1];
            let number_parts: Vec> = all_numbers
                .split('|')
                .map(|x| {
                    x.replace("  ", " ")
                        .split_whitespace()
                        .map(|val| val.to_string())
                        .collect()
                })
                .collect();
            let (winning_nums, owned_nums) = (&amp;number_parts[0], &amp;number_parts[1]);
            let matches = owned_nums
                .iter()
                .filter(|num| winning_nums.contains(num))
                .count();
            let card_details = CardInfo { count: 1 };
            if let Some(old_card_info) = cards.insert(card_id, card_details) {
                let card_entry = cards.get_mut(&amp;card_id);
                card_entry.expect("card exists").count += old_card_info.count;
            };
            let current_card = cards.get(&amp;card_id).expect("card exists");
            if matches > 0 {
                for _ in 0..current_card.count {
                    for i in (card_id + 1)..=(matches as u32) + card_id {
                        let new_card_info = CardInfo { count: 1 };
                        if let Some(old_card_info) = cards.insert(i, new_card_info) {
                            let card_entry = cards.get_mut(&amp;i).expect("card exists");
                            card_entry.count += old_card_info.count;
                        }
                    }
                }
            }
        }
        let sum = cards.iter().fold(0, |acc, c| acc + c.1.count);
        sum
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
    
        const INPUT: &amp;str = "Card 1: 41 48 83 86 17 | 83 86  6 31 17  9 48 53
    Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
    Card 3:  1 21 53 59 44 | 69 82 63 72 16 21 14  1
    Card 4: 41 92 73 84 69 | 59 84 76 51 58  5 54 83
    Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
    Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11";
    
        #[test]
        fn test_process_part_one() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(13, process_part_one(BufReader::new(input_bytes)));
        }
    
        #[test]
        fn test_process_part_two() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(30, process_part_two(BufReader::new(input_bytes)));
        }
    }
    
    

  • Edit: Updated now with part 2.

    Managed to have a crack at this a bit earlier today, I’ve only done Part 01 so far. I’ll update with Part 02 later.

    I tackled this with the personal challenge of not loading the entire puzzle input into memory, which would have made this a bit easier.

    Solution in Rust 🦀

    View formatted on GitLab

    use std::{
        env, fs,
        io::{self, BufRead, BufReader, Read},
    };
    
    fn main() -> io::Result&lt;()> {
        let args: Vec = env::args().collect();
        let filename = &amp;args[1];
        let file1 = fs::File::open(filename)?;
        let file2 = fs::File::open(filename)?;
        let reader1 = BufReader::new(file1);
        let reader2 = BufReader::new(file2);
    
        println!("Part one: {}", process_part_one(reader1));
        println!("Part two: {}", process_part_two(reader2));
        Ok(())
    }
    
    fn process_part_one(reader: BufReader) -> u32 {
        let mut lines = reader.lines().peekable();
        let mut prev_line: Option = None;
        let mut sum = 0;
        while let Some(line) = lines.next() {
            let current_line = line.expect("line exists");
            let next_line = match lines.peek() {
                Some(Ok(line)) => Some(line),
                Some(Err(_)) => None,
                None => None,
            };
            match (prev_line, next_line) {
                (None, Some(next)) => {
                    let lines = vec![¤t_line, next];
                    sum += parse_lines(lines, true);
                }
                (Some(prev), Some(next)) => {
                    let lines = vec![&amp;prev, ¤t_line, next];
                    sum += parse_lines(lines, false);
                }
                (Some(prev), None) => {
                    let lines = vec![&amp;prev, ¤t_line];
                    sum += parse_lines(lines, false);
                }
                (None, None) => {}
            }
    
            prev_line = Some(current_line);
        }
        sum
    }
    
    fn process_part_two(reader: BufReader) -> u32 {
        let mut lines = reader.lines().peekable();
        let mut prev_line: Option = None;
        let mut sum = 0;
        while let Some(line) = lines.next() {
            let current_line = line.expect("line exists");
            let next_line = match lines.peek() {
                Some(Ok(line)) => Some(line),
                Some(Err(_)) => None,
                None => None,
            };
            match (prev_line, next_line) {
                (None, Some(next)) => {
                    let lines = vec![¤t_line, next];
                    sum += parse_lines_for_gears(lines, true);
                }
                (Some(prev), Some(next)) => {
                    let lines = vec![&amp;prev, ¤t_line, next];
                    sum += parse_lines_for_gears(lines, false);
                }
                (Some(prev), None) => {
                    let lines = vec![&amp;prev, ¤t_line];
                    sum += parse_lines_for_gears(lines, false);
                }
                (None, None) => {}
            }
    
            prev_line = Some(current_line);
        }
    
        sum
    }
    
    fn parse_lines(lines: Vec&lt;&amp;String>, first_line: bool) -> u32 {
        let mut sum = 0;
        let mut num = 0;
        let mut valid = false;
        let mut char_vec: Vec> = Vec::new();
        for line in lines {
            char_vec.push(line.chars().collect());
        }
        let chars = match first_line {
            true => &amp;char_vec[0],
            false => &amp;char_vec[1],
        };
        for i in 0..chars.len() {
            if chars[i].is_digit(10) {
                // Add the digit to the number
                num = num * 10 + chars[i].to_digit(10).expect("is digit");
    
                // Check the surrounding character for non-period symbols
                for &amp;x in &amp;[-1, 0, 1] {
                    for chars in &amp;char_vec {
                        if (i as isize + x).is_positive() &amp;&amp; ((i as isize + x) as usize) &lt; chars.len() {
                            let index = (i as isize + x) as usize;
                            if !chars[index].is_digit(10) &amp;&amp; chars[index] != '.' {
                                valid = true;
                            }
                        }
                    }
                }
            } else {
                if valid {
                    sum += num;
                }
                valid = false;
                num = 0;
            }
        }
        if valid {
            sum += num;
        }
        sum
    }
    
    fn parse_lines_for_gears(lines: Vec&lt;&amp;String>, first_line: bool) -> u32 {
        let mut sum = 0;
        let mut char_vec: Vec> = Vec::new();
        for line in &amp;lines {
            char_vec.push(line.chars().collect());
        }
        let chars = match first_line {
            true => &amp;char_vec[0],
            false => &amp;char_vec[1],
        };
        for i in 0..chars.len() {
            if chars[i] == '*' {
                let surrounding_nums = get_surrounding_numbers(&amp;lines, i);
                let product = match surrounding_nums.len() {
                    0 | 1 => 0,
                    _ => surrounding_nums.iter().product(),
                };
                sum += product;
            }
        }
        sum
    }
    
    fn get_surrounding_numbers(lines: &amp;Vec&lt;&amp;String>, gear_pos: usize) -> Vec {
        let mut nums: Vec = Vec::new();
        let mut num: u32 = 0;
        let mut valid = false;
        for line in lines {
            for (i, char) in line.chars().enumerate() {
                if char.is_digit(10) {
                    num = num * 10 + char.to_digit(10).expect("is digit");
                    if [gear_pos - 1, gear_pos, gear_pos + 1].contains(&amp;i) {
                        valid = true;
                    }
                } else if num > 0 &amp;&amp; valid {
                    nums.push(num);
                    num = 0;
                    valid = false;
                } else {
                    num = 0;
                    valid = false;
                }
            }
            if num > 0 &amp;&amp; valid {
                nums.push(num);
            }
            num = 0;
            valid = false;
        }
        nums
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
    
        const INPUT: &amp;str = "467..114..
    ...*......
    ..35..633.
    ......#...
    617*......
    .....+.58.
    ..592.....
    ......755.
    ...$.*....
    .664.598..";
    
        #[test]
        fn test_process_part_one() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(4361, process_part_one(BufReader::new(input_bytes)));
        }
    
        #[test]
        fn test_process_part_two() {
            let input_bytes = INPUT.as_bytes();
            assert_eq!(467835, process_part_two(BufReader::new(input_bytes)));
        }
    }
    

  • Late as always, as I’m on UK time and can’t work on these until late evening.

    Part 01 and Part 02 in Rust 🦀 :

    use std::{
        env, fs,
        io::{self, BufRead, BufReader},
    };
    
    #[derive(Debug)]
    struct Sample {
        r: u32,
        g: u32,
        b: u32,
    }
    
    fn split_cube_set(set: &amp;[&amp;str], colour: &amp;str) -> Option {
        match set.iter().find(|x| x.ends_with(colour)) {
            Some(item) => item
                .trim()
                .split(' ')
                .next()
                .expect("Found item is present")
                .parse::()
                .ok(),
            None => None,
        }
    }
    
    fn main() -> io::Result&lt;()> {
        let args: Vec = env::args().collect();
        let filename = &amp;args[1];
        let file = fs::File::open(filename)?;
        let reader = BufReader::new(file);
        let mut valid_game_ids_sum = 0;
        let mut game_power_sum = 0;
        let max_r = 12;
        let max_g = 13;
        let max_b = 14;
        for line_result in reader.lines() {
            let mut valid_game = true;
            let line = line_result.unwrap();
            let line_split: Vec&lt;_> = line.split(':').collect();
            let game_id = line_split[0]
                .split(' ')
                .collect::>()
                .last()
                .expect("item exists")
                .parse::()
                .expect("is a number");
            let rest = line_split[1];
            let cube_sets = rest.split(';');
            let samples: Vec = cube_sets
                .map(|set| {
                    let set_split: Vec&lt;_> = set.split(',').collect();
                    let r = split_cube_set(&amp;set_split, "red").unwrap_or(0);
                    let g = split_cube_set(&amp;set_split, "green").unwrap_or(0);
                    let b = split_cube_set(&amp;set_split, "blue").unwrap_or(0);
                    Sample { r, g, b }
                })
                .collect();
            let mut highest_r = 0;
            let mut highest_g = 0;
            let mut highest_b = 0;
            for sample in &amp;samples {
                if !(sample.r &lt;= max_r &amp;&amp; sample.g &lt;= max_g &amp;&amp; sample.b &lt;= max_b) {
                    valid_game = false;
                }
                highest_r = u32::max(highest_r, sample.r);
                highest_g = u32::max(highest_g, sample.g);
                highest_b = u32::max(highest_b, sample.b);
            }
            if valid_game {
                valid_game_ids_sum += game_id;
            }
            game_power_sum += highest_r * highest_g * highest_b;
        }
        println!("Sum of game ids: {valid_game_ids_sum}");
        println!("Sum of game powers: {game_power_sum}");
        Ok(())
    }
    

  • Part 02 in Rust 🦀 :

    use std::{
        collections::HashMap,
        env, fs,
        io::{self, BufRead, BufReader},
    };
    
    fn main() -> io::Result&lt;()> {
        let args: Vec = env::args().collect();
        let filename = &amp;args[1];
        let file = fs::File::open(filename)?;
        let reader = BufReader::new(file);
    
        let number_map = HashMap::from([
            ("one", "1"),
            ("two", "2"),
            ("three", "3"),
            ("four", "4"),
            ("five", "5"),
            ("six", "6"),
            ("seven", "7"),
            ("eight", "8"),
            ("nine", "9"),
        ]);
    
        let mut total = 0;
        for _line in reader.lines() {
            let digits = get_text_numbers(_line.unwrap(), &amp;number_map);
            if !digits.is_empty() {
                let digit_first = digits.first().unwrap();
                let digit_last = digits.last().unwrap();
                let mut cat = String::new();
                cat.push(*digit_first);
                cat.push(*digit_last);
                let cat: i32 = cat.parse().unwrap();
                total += cat;
            }
        }
        println!("{total}");
        Ok(())
    }
    
    fn get_text_numbers(text: String, number_map: &amp;HashMap&lt;&amp;str, &amp;str>) -> Vec {
        let mut digits: Vec = Vec::new();
        if text.is_empty() {
            return digits;
        }
        let mut sample = String::new();
        let chars: Vec = text.chars().collect();
        let mut ptr1: usize = 0;
        let mut ptr2: usize;
        while ptr1 &lt; chars.len() {
            sample.clear();
            ptr2 = ptr1 + 1;
            if chars[ptr1].is_digit(10) {
                digits.push(chars[ptr1]);
                sample.clear();
                ptr1 += 1;
                continue;
            }
            sample.push(chars[ptr1]);
            while ptr2 &lt; chars.len() {
                if chars[ptr2].is_digit(10) {
                    sample.clear();
                    break;
                }
                sample.push(chars[ptr2]);
                if number_map.contains_key(&amp;sample.as_str()) {
                    let str_digit: char = number_map.get(&amp;sample.as_str()).unwrap().parse().unwrap();
                    digits.push(str_digit);
                    sample.clear();
                    break;
                }
                ptr2 += 1;
            }
            ptr1 += 1;
        }
    
        digits
    }