DEV Community

Cover image for Advent of Code 2023 - DAY 1
Antonio Perrone
Antonio Perrone

Posted on • Edited on

Advent of Code 2023 - DAY 1

It's Christmas time and time for Advent of Code 2023 edition.
Starting from today I will try to solve puzzles in Rust and publish a post a day in which I tell my solution.
My goal is not to climb the leaderboard but to use the problems to practice writing Rust code and improve my language knowledge. Copilot yes or Copilot not? It's for learning so Copilot definitely not.
The solutions will be available at the following git repository, as I don't have much time to write a template from scratch, I will use the starter template available here.

Problem Day 1: Trebuchet?!

Here the day 1 problem statement: https://adventofcode.com/2023/day/1

Solution Part 1

pub fn part_one(input: &str) -> Option<u32> {
    let lines = input.split('\n').collect::<Vec<&str>>();
    let mut sum_calibration = 0;

    for line in lines {
        if line.is_empty() {
            continue;
        }
        let mut first = false;
        let mut calibration: Vec<String> = vec!["0".to_string(), "0".to_string()];
        for c in line.chars() {
            if c.is_numeric() {
                if !first {
                    first = true;
                    calibration[0] = c.to_string();
                }
                calibration[1] = c.to_string();
            }
        }
        let calibration_num: String = calibration.join("");

        let calib: i32 = calibration_num.parse().unwrap();
        sum_calibration += calib;
    }

    Some(sum_calibration as u32)
}
Enter fullscreen mode Exit fullscreen mode

The solution is quite simple and easy to understand: input variable contains all the file rows, we split the input line by line and loop over each line char by char finding the first and the last digit.
At the end of each line loop we join the digits, cast them to number and sum on a counter variable.

Solution Part 2

pub fn part_two(input: &str) -> Option<u32> {
    const NUM: [&str; 9] = [
        "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
    ];

    let lines = input.split('\n').collect::<Vec<&str>>();
    let mut sum_calibration = 0;

    for line in lines {
        if line.is_empty() {
            continue;
        }
        let mut first = false;
        let mut calibration: Vec<String> = vec!["0".to_string(), "0".to_string()];
        for (i, c) in line.chars().enumerate() {
            if c.is_numeric() {
                if !first {
                    first = true;
                    calibration[0] = c.to_string();
                }
                calibration[1] = c.to_string();
            }

            for (x, elem) in NUM.iter().enumerate() {
                if line[i..].starts_with(elem) {
                    if !first {
                        first = true;
                        calibration[0] = (x + 1).to_string();
                    }
                    calibration[1] = (x + 1).to_string();
                }
            }
        }
        let calibration_num: String = calibration.join("");

        let calib: i32 = calibration_num.parse().unwrap();
        sum_calibration += calib;
    }

    Some(sum_calibration as u32)
}
Enter fullscreen mode Exit fullscreen mode

The solution evolves as part 1 with only one addition: when we check if each line char is a digit, we also check if the char is the beginning of a digit spelled out with letters. If so, we get it numeric representation.

Top comments (0)