Day 1
This commit is contained in:
commit
83cb093d0a
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "advent_of_code_2023"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "advent_of_code_2023"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,63 @@
|
||||||
|
|
||||||
|
pub enum PART {
|
||||||
|
ONE,
|
||||||
|
TWO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn line_to_calibration_part1(line: &str) -> (Option<u32>, Option<u32>) {
|
||||||
|
let a = line.chars().find(|c| c.is_ascii_digit()).expect("Could not find a valid number from the left").to_digit(10);
|
||||||
|
let b = line.chars().rev().find(|c| c.is_ascii_digit()).expect("Could not find a valid number from the right").to_digit(10);
|
||||||
|
|
||||||
|
(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn line_to_calibration_part2(line: &str) -> (Option<u32>, Option<u32>) {
|
||||||
|
|
||||||
|
let digits_words = &["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
|
||||||
|
|
||||||
|
let mut a: Option<u32> = None;
|
||||||
|
let mut b: Option<u32> = None;
|
||||||
|
|
||||||
|
|
||||||
|
'search: for i in 0..line.len() {
|
||||||
|
let (_, remaining_line) = line.split_at(i);
|
||||||
|
for (j, word) in digits_words.iter().enumerate() {
|
||||||
|
if remaining_line.starts_with(word) {
|
||||||
|
a = Some(j as u32 + 1);
|
||||||
|
break 'search;
|
||||||
|
}else if let Some(char) = remaining_line.chars().next() && char.is_numeric() {
|
||||||
|
a = char.to_digit(10);
|
||||||
|
break 'search;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
'search: for i in 0..line.len() {
|
||||||
|
let (remaining_line, _) = line.split_at(line.len() - i);
|
||||||
|
for (j, word) in digits_words.iter().enumerate() {
|
||||||
|
if remaining_line.ends_with(word) {
|
||||||
|
b = Some(j as u32 + 1);
|
||||||
|
break 'search;
|
||||||
|
}else if let Some(char) = remaining_line.chars().last() && char.is_numeric() {
|
||||||
|
b = char.to_digit(10);
|
||||||
|
break 'search;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(a,b)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn solve(lines: Vec<String>, part: self::PART) -> u32 {
|
||||||
|
let mut sum = 0;
|
||||||
|
for line in lines.iter() {
|
||||||
|
let (a, b) = match part {
|
||||||
|
PART::ONE => line_to_calibration_part1(line),
|
||||||
|
PART::TWO => line_to_calibration_part2(line)
|
||||||
|
};
|
||||||
|
if let (Some(a), Some(b)) = (a, b) {
|
||||||
|
sum += a * 10 + b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#![feature(let_chains)]
|
||||||
|
|
||||||
|
mod day1;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let day1_data_path = "./datasets/adventofcode.com_2023_day_1_input.txt";
|
||||||
|
let day1_result_part1 = day1::solve(utils::lines_from_file(day1_data_path).expect("Could not load the dataset for day 1"), day1::PART::ONE);
|
||||||
|
let day1_result_part2 = day1::solve(utils::lines_from_file(day1_data_path).expect("Could not load the dataset for day 1"), day1::PART::TWO);
|
||||||
|
|
||||||
|
println!("Day 1 (part 1) result is {}", day1_result_part1);
|
||||||
|
println!("Day 1 (part 2) result is {}", day1_result_part2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn day1() {
|
||||||
|
let day1_data_path = "./datasets/adventofcode.com_2023_day_1_input.txt";
|
||||||
|
let day1_result_part1 = day1::solve(utils::lines_from_file(day1_data_path).expect("Could not load the dataset for day 1"), day1::PART::ONE);
|
||||||
|
let day1_result_part2 = day1::solve(utils::lines_from_file(day1_data_path).expect("Could not load the dataset for day 1"), day1::PART::TWO);
|
||||||
|
|
||||||
|
assert_eq!(day1_result_part1, 54338);
|
||||||
|
assert_eq!(day1_result_part2, 53389);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{prelude::*, BufReader,Result},
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn lines_from_file(filename: impl AsRef<Path>) -> Result<Vec<String>> {
|
||||||
|
let file = File::open(filename)?;
|
||||||
|
|
||||||
|
let buf = BufReader::new(file);
|
||||||
|
buf.lines().collect()
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue