This commit is contained in:
Daniel Flanagan 2024-12-01 16:21:43 -06:00
parent a24d3134c0
commit a13b049276
2 changed files with 54 additions and 100 deletions

View file

@ -1,3 +1,5 @@
use std::{collections::HashMap, iter::zip, num::ParseIntError, str::FromStr};
use crate::prelude::*; use crate::prelude::*;
mod prelude; mod prelude;
@ -8,108 +10,57 @@ fn main() {
struct Day1 {} struct Day1 {}
impl Day1 { impl Day1 {
fn calibration_value(line: &str) -> i128 { fn smallests_distances(input: &str) -> i64 {
println!("{line}"); let mut lefts = Vec::<i64>::new();
let bytes = line.as_bytes(); let mut rights = Vec::<i64>::new();
let mut first_digit: Option<u8> = None; for l in input.lines() {
let mut last_digit: Option<u8> = None; let mut tokens = l.split(" ");
for i in 0..bytes.len() { lefts.push(tokens.next().unwrap().parse().unwrap());
let n = bytes.len() - 1 - i; rights.push(tokens.next().unwrap().parse().unwrap());
println!("{n} {i}");
if first_digit.is_none() && (0x30..=0x39).contains(&bytes[i]) {
first_digit = Some(bytes[i] - 0x30);
println!("found first {first_digit:?}");
}
if last_digit.is_none() && (0x30..=0x39).contains(&bytes[n]) {
last_digit = Some(bytes[n] - 0x30);
println!("found last {last_digit:?}");
}
if first_digit.is_some() && last_digit.is_some() {
break;
}
} }
println!("{:?} {:?}", first_digit, last_digit); lefts.sort();
Into::<i128>::into(first_digit.or(last_digit).unwrap() * 10) rights.sort();
+ Into::<i128>::into(last_digit.or(first_digit).unwrap()) let mut sum = 0;
for (l, r) in zip(&lefts, &rights) {
sum += (l - r).abs();
}
sum
} }
fn num_name(s: &[u8]) -> Option<u8> { fn similarity_score(input: &str) -> i64 {
for (i, w) in [ let mut lefts = Vec::<i64>::new();
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", let mut rights: HashMap<i64, i64> = HashMap::new();
] for l in input.lines() {
.map(|s| s.as_bytes()) let mut tokens = l.split(" ");
.iter() lefts.push(tokens.next().unwrap().parse().unwrap());
.enumerate() let right: i64 = tokens.next().unwrap().parse().unwrap();
{ match rights.get_mut(&right) {
if s.starts_with(w) { None => {
return Some(i as u8); rights.insert(right, 1);
}
}
return None;
}
fn num_name_end(s: &[u8]) -> Option<u8> {
for (i, w) in [
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
]
.map(|s| s.as_bytes())
.iter()
.enumerate()
{
if s.ends_with(w) {
return Some(i as u8);
}
}
return None;
}
fn calibration_value_words(line: &str) -> i128 {
println!("{line}");
let bytes = line.as_bytes();
let mut first_digit: Option<u8> = None;
let mut last_digit: Option<u8> = None;
for i in 0..bytes.len() {
let n = bytes.len() - 1 - i;
println!("NI: {n} {i}");
if first_digit.is_none() {
if (0x30..=0x39).contains(&bytes[i]) {
first_digit = Some(bytes[i] - 0x30);
println!("found first {first_digit:?}");
} else if let Some(n) = Self::num_name(&bytes[i..]) {
first_digit = Some(n);
println!("found first text {first_digit:?}");
} }
} Some(n) => {
if last_digit.is_none() { *n += 1;
println!("{:?}", &bytes[..=n]);
if (0x30..=0x39).contains(&bytes[n]) {
last_digit = Some(bytes[n] - 0x30);
println!("found last {last_digit:?}");
} else if let Some(n) = Self::num_name_end(&bytes[..=n]) {
last_digit = Some(n);
println!("found last text {last_digit:?}");
} }
} };
if first_digit.is_some() && last_digit.is_some() {
break;
}
} }
println!("{:?} {:?}", first_digit, last_digit); let mut sum = 0;
Into::<i128>::into(first_digit.or(last_digit).unwrap() * 10) for l in &lefts {
+ Into::<i128>::into(last_digit.or(first_digit).unwrap()) sum += (rights.get(l).unwrap_or(&0) * l)
}
sum
} }
} }
impl AoCSolution for Day1 { impl AoCSolution for Day1 {
type Input = String; type Input = String;
type Solution = i128; type Solution = i64;
fn part1(input: Self::Input) -> Self::Solution { fn part1(input: Self::Input) -> Self::Solution {
input.lines().map(Self::calibration_value).sum() Day1::smallests_distances(&input)
} }
fn part2(input: Self::Input) -> Self::Solution { fn part2(input: Self::Input) -> Self::Solution {
input.lines().map(Self::calibration_value_words).sum() Day1::similarity_score(&input)
} }
} }
@ -121,26 +72,27 @@ mod tests {
fn test() { fn test() {
assert_eq!( assert_eq!(
Day1::part1( Day1::part1(
r#"1abc2 r#"3 4
pqr3stu8vwx 4 3
a1b2c3d4e5f 2 5
treb7uchet"# 1 3
3 9
3 3"#
.into() .into()
), ),
142 11
); );
assert_eq!( assert_eq!(
Day1::part2( Day1::part2(
r#"two1nine r#"3 4
eightwothree 4 3
abcone2threexyz 2 5
xtwone3four 1 3
4nineeightseven2 3 9
zoneight234 3 3"#
7pqrstsixteen"#
.into() .into()
), ),
281 31
); );
} }
} }

View file

@ -6,8 +6,10 @@ use std::{env, io};
#[derive(Debug)] #[derive(Debug)]
enum InputFileError { enum InputFileError {
#![allow(dead_code)] #[allow(dead_code)]
EnvVar(env::VarError), EnvVar(env::VarError),
#[allow(dead_code)]
Io(io::Error), Io(io::Error),
} }