My solution in rust. I’m sure there’s a lot more clever ways to do it but this is what I came up with.
Code
use std::{io::prelude::*, fs::File, path::Path, io };
fn main()
{
run_solution(false);
println!("\nPress enter to continue");
let mut buffer = String::new();
io::stdin().read_line(&mut buffer).unwrap();
run_solution(true);
}
fn run_solution(check_for_spelled: bool)
{
let data = load_data("data/input");
println!("\nProcessing Data...");
let mut sum: u64 = 0;
for line in data.lines()
{
// Doesn't seem like the to_ascii_lower call is needed but... just in case
let first = get_digit(line.to_ascii_lowercase().as_bytes(), false, check_for_spelled);
let last = get_digit(line.to_ascii_lowercase().as_bytes(), true, check_for_spelled);
let num = (first * 10) + last;
// println!("\nLine: {} -- First: {}, Second: {}, Num: {}", line, first, last, num);
sum += num as u64;
}
println!("\nFinal Sum: {}", sum);
}
fn get_digit(line: &[u8], from_back: bool, check_for_spelled: bool) -> u8
{
let mut range: Vec = (0..line.len()).collect();
if from_back
{
range.reverse();
}
for i in range
{
if is_num(line[i])
{
return (line[i] - 48) as u8;
}
if check_for_spelled
{
if let Some(num) = is_spelled_num(line, i)
{
return num;
}
}
}
return 0;
}
fn is_num(c: u8) -> bool
{
c >= 48 && c <= 57
}
fn is_spelled_num(line: &[u8], start: usize) -> Option
{
let words = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
for word_idx in 0..words.len()
{
let mut i = start;
let mut found = true;
for c in words[word_idx].as_bytes()
{
if i < line.len() && *c != line[i]
{
found = false;
break;
}
i += 1;
}
if found && i <= line.len()
{
return Some(word_idx as u8 + 1);
}
}
return None;
}
fn load_data(file_name: &str) -> String
{
let mut file = match File::open(Path::new(file_name))
{
Ok(file) => file,
Err(why) => panic!("Could not open file {}: {}", Path::new(file_name).display(), why),
};
let mut s = String::new();
let file_contents = match file.read_to_string(&mut s)
{
Err(why) => panic!("couldn't read {}: {}", Path::new(file_name).display(), why),
Ok(_) => s,
};
return file_contents;
}
They’d probably have to make sure it doesn’t use the
unsafe
keyword to guarantee this.