diff --git a/2023/rust/day1/example2 b/2023/rust/day1/example2 new file mode 100644 index 0000000..4316a6b --- /dev/null +++ b/2023/rust/day1/example2 @@ -0,0 +1,7 @@ +two1nine +eightwothree +abcone2threexyz +xtwone3four +4nineeightseven2 +zoneight234 +7pqrstsixteen \ No newline at end of file diff --git a/2023/rust/day1/src/main.rs b/2023/rust/day1/src/main.rs index aea4158..2cdb7d2 100644 --- a/2023/rust/day1/src/main.rs +++ b/2023/rust/day1/src/main.rs @@ -1,26 +1,95 @@ use std::fs::read_to_string; -fn part1(str: &String) -> Vec { - let mut num_vec = Vec::new(); - let line : Vec<&str> = str.split('\n').collect(); - for l in line { - let num : Vec = l.as_bytes().iter().filter(|ch| ch.is_ascii_digit()).cloned().collect(); - let mut str_num = String::new(); - if num.len() >= 2 { - str_num.push(num.first().unwrap().clone() as char); - str_num.push(num.last().unwrap().clone() as char); +const DIGITS : [&str; 9] = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]; + +fn contains_digit(txt: &str, actual_index: usize) -> Option { + let mut digit_index: Option = Option::None; + + for i in [3, 4, 5] { + let max_str = if actual_index + i >= txt.len() { + txt.len() } else { - str_num.push(num.first().unwrap().clone() as char); - str_num.push(num.first().unwrap().clone() as char); + actual_index + i + }; + digit_index = DIGITS + .iter() + .position(|&digit| txt[actual_index..max_str].eq(digit)); + if digit_index.is_some() { + break; } - num_vec.push(str_num); + } + digit_index +} + +fn convert_spelled_digit(txt: &str) -> String { + // static variable + let digits_char: Vec = vec!['1', '2', '3', '4', '5', '6', '7', '8', '9']; + // mutable variables + let mut finished = false; + let mut return_string = txt.to_string(); + + while !finished { + let mut temp_string = return_string.clone(); + for (str_index, _) in return_string.as_bytes().iter().enumerate() { + if str_index == return_string.len() - 1 { + finished = true; + } + if let Some(i) = contains_digit(&return_string,str_index) { + // Transforming the string + let (first, last) = return_string.split_at(str_index); + let (_, last) = last.split_at(DIGITS[i].len()); + temp_string = first.to_string() + digits_char[i].to_string().as_str() + last; + break; + } + } + return_string = temp_string; + } + println!("{}",return_string); + return_string +} + +fn part1(str: &String) -> Vec { + let mut num_vec = Vec::new(); + let line: Vec<&str> = str.split('\n').collect(); + for l in line { + num_vec.push(algorithm(l.to_string())); } println!("{:?}", num_vec); num_vec.iter().map(|str| str.parse().unwrap()).collect() } -fn main() { - let str = read_to_string("input").unwrap(); - let part1_result : u32 = part1(&str).iter().sum(); - println!("total part1: {}", part1_result); +fn part2(str: &String) -> Vec { + let mut num_vec = Vec::new(); + let line: Vec<&str> = str.split('\n').collect(); + for l in line { + num_vec.push(algorithm(convert_spelled_digit(l))); + } + println!("{:?}", num_vec); + num_vec.iter().map(|str| str.parse().unwrap()).collect() +} + +fn algorithm(str: String) -> String { + let num: Vec = str + .as_bytes() + .iter() + .filter(|ch| ch.is_ascii_digit()) + .cloned() + .collect(); + let str_num: String; + if num.len() == 0 { + str_num = "00".to_string(); + } else if num.len() >= 2 { + str_num = (num.first().unwrap().clone() as char).to_string() + (num.last().unwrap().clone() as char).to_string().as_str(); + } else { + str_num = (num.first().unwrap().clone() as char).to_string() + (num.first().unwrap().clone() as char).to_string().as_str(); + } + str_num +} + +fn main() { + let str = read_to_string("example2").unwrap(); + let part1_result: u64 = part1(&str).iter().sum(); + println!("part1 result: {}", part1_result); + let part2_result: u64 = part2(&str).iter().sum(); + println!("part2 result: {}", part2_result); }