Skip to content

Commit a497ff5

Browse files
committed
[rs] 2023:01: Re-write part1; also solve part2
1 parent bc5633a commit a497ff5

File tree

2 files changed

+95
-57
lines changed

2 files changed

+95
-57
lines changed

2023/day01/day01.rs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use std::fs;
2+
use std::convert::TryInto;
3+
use std::str::Chars;
4+
use std::iter::Rev;
5+
6+
enum CharIter<'a> {
7+
Forward(Chars<'a>),
8+
Backward(Rev<Chars<'a>>)
9+
}
10+
11+
impl<'a> Iterator for CharIter<'a> {
12+
type Item = char;
13+
fn next(&mut self) -> Option<Self::Item> {
14+
match self {
15+
CharIter::Forward(itr) => itr.next(),
16+
CharIter::Backward(itr) => itr.next(),
17+
}
18+
}
19+
}
20+
21+
const TEXT_DIGITS: [(&str, u8); 10] = [
22+
("zero", 0), ("one", 1), ("two", 2), ("three", 3), ("four", 4),
23+
("five", 5), ("six", 6), ("seven", 7), ("eight", 8), ("nine", 9)
24+
];
25+
26+
fn read_input(filename: &str) -> Vec<String> {
27+
if let Ok(input_text) = fs::read_to_string(filename) {
28+
input_text
29+
.trim()
30+
.split("\n")
31+
.map(|line| line.trim().to_owned())
32+
.collect()
33+
} else {
34+
panic!("Unable to read input from file: {}", filename);
35+
}
36+
}
37+
38+
fn get_text_digit(text: &str) -> Option<u8> {
39+
for text_digit in TEXT_DIGITS {
40+
if text.ends_with(text_digit.0) || text.starts_with(text_digit.0) {
41+
return Some(text_digit.1);
42+
}
43+
}
44+
None
45+
}
46+
47+
fn _get_first_digit(chars: CharIter, convert_text: bool, reversed: bool) -> u8 {
48+
let mut charbuf: String = String::new();
49+
50+
for char in chars {
51+
if let Some(digit) = char.to_digit(10) {
52+
return digit.try_into().unwrap();
53+
}
54+
55+
if reversed { charbuf.insert(0, char); }
56+
else { charbuf.push(char); }
57+
if convert_text {
58+
if let Some(text_digit) = get_text_digit(&charbuf) {
59+
return text_digit;
60+
}
61+
}
62+
}
63+
panic!("Line does not have a digit!");
64+
}
65+
66+
fn get_first_digit(line: &str, convert_text: bool) -> u8 {
67+
_get_first_digit(CharIter::Forward(line.chars()), convert_text, false)
68+
}
69+
70+
fn get_last_digit(line: &str, convert_text: bool) -> u8 {
71+
_get_first_digit(CharIter::Backward(line.chars().rev()).into_iter(), convert_text, true)
72+
}
73+
74+
fn get_digits(line: &str, convert_text: bool) -> (u8, u8) {
75+
(get_first_digit(line, convert_text), get_last_digit(line, convert_text))
76+
}
77+
78+
fn get_calibration_value((digit1, digit2): (u8, u8)) -> u8 {
79+
format!("{digit1}{digit2}").parse().unwrap()
80+
}
81+
82+
fn find_solution(lines: Vec<String>, convert_text: bool) -> usize {
83+
lines.iter()
84+
.map(|line| get_digits(line, convert_text))
85+
.map(get_calibration_value)
86+
.fold(0, |acc, calibration_value| {
87+
acc + usize::from(calibration_value)
88+
})
89+
}
90+
91+
pub fn main() {
92+
let input_lines: Vec<String> = read_input("input");
93+
println!("Part 1: {}", find_solution(input_lines.clone(), false));
94+
println!("Part 2: {}", find_solution(input_lines, true));
95+
}

2023/day01/part1.rs

-57
This file was deleted.

0 commit comments

Comments
 (0)