Day1
This commit is contained in:
+116
@@ -0,0 +1,116 @@
|
||||
use log::debug;
|
||||
|
||||
fn first_and_last(line: &str) -> i32 {
|
||||
let first = line.chars().find_map(|c| c.to_digit(10)).unwrap();
|
||||
let last = line.chars().rev().find_map(|c| c.to_digit(10)).unwrap();
|
||||
|
||||
let number: String = format!("{}{}", first, last);
|
||||
|
||||
debug!("Number: {}", number);
|
||||
|
||||
number.parse::<i32>().unwrap()
|
||||
}
|
||||
|
||||
fn search_and_replace(line: &str) -> String {
|
||||
let number_mapping = [
|
||||
("one", "1"),
|
||||
("two", "2"),
|
||||
("three", "3"),
|
||||
("four", "4"),
|
||||
("five", "5"),
|
||||
("six", "6"),
|
||||
("seven", "7"),
|
||||
("eight", "8"),
|
||||
("nine", "9"),
|
||||
];
|
||||
|
||||
let mut replacements: Vec<(usize, usize, &str, &str)> = Vec::new();
|
||||
|
||||
for (search, replace) in number_mapping {
|
||||
let mut start = 0;
|
||||
let mut last_pos = None;
|
||||
while let Some(pos) = line[start..].find(search) {
|
||||
let abs_pos = start + pos;
|
||||
last_pos = Some(abs_pos + search.len());
|
||||
start = abs_pos + search.len();
|
||||
}
|
||||
|
||||
if let Some(last) = last_pos {
|
||||
replacements.push((last - search.len(), last, search, replace));
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by position in ascending order, excluding the last occurrences
|
||||
replacements.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
let mut modified_line = line.to_string();
|
||||
|
||||
for (_, _, search, replace) in replacements {
|
||||
modified_line = modified_line.replace(search, replace);
|
||||
}
|
||||
|
||||
modified_line
|
||||
}
|
||||
|
||||
pub fn day1(input: String) {
|
||||
let result1: i32 = input
|
||||
.lines()
|
||||
.map(|line| -> i32 { first_and_last(line) })
|
||||
.sum();
|
||||
|
||||
let result2: i32 = input
|
||||
.lines()
|
||||
.map(|line: &str| -> i32 {
|
||||
let modified_line = search_and_replace(line);
|
||||
first_and_last(&modified_line)
|
||||
})
|
||||
.sum();
|
||||
|
||||
println!("Result day 1: [{}] [{}]", result1, result2);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_day1 {
|
||||
use crate::day1::{first_and_last, search_and_replace};
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let input = "two1nine
|
||||
eightwothree
|
||||
abcone2threexyz
|
||||
xtwone3four
|
||||
4nineeightseven2
|
||||
zoneight234
|
||||
7pqrstsixteen";
|
||||
|
||||
let mut lines: std::str::Lines<'_> = input.lines();
|
||||
assert_eq!(
|
||||
29,
|
||||
first_and_last(&search_and_replace(lines.next().unwrap()))
|
||||
);
|
||||
assert_eq!(
|
||||
83,
|
||||
first_and_last(&search_and_replace(lines.next().unwrap()))
|
||||
);
|
||||
assert_eq!(
|
||||
13,
|
||||
first_and_last(&search_and_replace(lines.next().unwrap()))
|
||||
);
|
||||
assert_eq!(
|
||||
24,
|
||||
first_and_last(&search_and_replace(lines.next().unwrap()))
|
||||
);
|
||||
assert_eq!(
|
||||
42,
|
||||
first_and_last(&search_and_replace(lines.next().unwrap()))
|
||||
);
|
||||
assert_eq!(
|
||||
14,
|
||||
first_and_last(&search_and_replace(lines.next().unwrap()))
|
||||
);
|
||||
assert_eq!(
|
||||
76,
|
||||
first_and_last(&search_and_replace(lines.next().unwrap()))
|
||||
);
|
||||
}
|
||||
}
|
||||
+21
-1
@@ -1,3 +1,23 @@
|
||||
use std::{env, fs::read_to_string};
|
||||
|
||||
use day1::day1;
|
||||
use log::LevelFilter;
|
||||
|
||||
pub mod day1;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
env_logger::Builder::from_default_env()
|
||||
.filter_level(LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
let mut day: &String = &"all".to_string();
|
||||
if args.len() > 1 {
|
||||
day = &args[1];
|
||||
}
|
||||
|
||||
if day == &"day1".to_string() || day == &"all".to_string() {
|
||||
day1(read_to_string("assets/day1.txt").unwrap().to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user