Compare commits

...

1 commit

Author SHA1 Message Date
969d6d3977
WIP 2023-12-01 04:06:53 -06:00

View file

@ -1,115 +1,102 @@
use crate::prelude::*;
use std::cell::OnceCell;
mod prelude;
const DIGITS = OnceCell::new();
fn main() {
Day1::show(day_input(1), day_input(1))
}
const ASCII_ZERO: u8 = 0x30;
const ASCII_NINE: u8 = 0x39;
let value: &String = digits.get_or_init(|| {
[
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
]
.map(str::as_bytes)});
assert_eq!(value, "Hello, World!");
assert!(cell.get().is_some());
const DIGITS: [&[u8]; 10] = ;
const DIGITS_REV: [&[u8]; 10] = [
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
]
.map(|s| s.chars().rev().collect::<String>().as_bytes());
type Solution = i64;
struct Day1 {}
impl Day1 {
fn calibration_value(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!("{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);
Into::<i128>::into(first_digit.or(last_digit).unwrap() * 10)
+ Into::<i128>::into(last_digit.or(first_digit).unwrap())
fn is_digit(b: &u8) -> bool {
(ASCII_ZERO..=ASCII_NINE).contains(b)
}
fn num_name(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.starts_with(w) {
return Some(i as u8);
}
}
return None;
fn to_digit(b: &u8) -> Solution {
i64::from(b - ASCII_ZERO)
}
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(line_bytes: &[u8]) -> i64 {
let i1 = line_bytes.iter().position(Self::is_digit).unwrap();
let i2 = line_bytes[i1..]
.iter()
.rev()
.position(Self::is_digit)
.unwrap_or(i1);
Self::to_digit(&line_bytes[i1]) * 10 + Self::to_digit(&line_bytes[i2])
}
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:?}");
// part 2
fn num_name(s: &[u8], digits: &[&[u8]]) -> Option<i64> {
digits
.iter()
.position(|d| s.starts_with(d))
.map(|n| n as i64)
}
fn num_or_digit(s: &[u8], digits: &[&[u8]]) -> Option<Solution> {
if Self::is_digit(&s[0]) {
Some(Self::to_digit(&s[0]))
} else {
Self::num_name(s, digits)
}
}
fn calibration_value_words(line_bytes: &[u8]) -> i64 {
for i in 0..line_bytes.len() {
if let Some(first_digit) = Self::num_or_digit(&line_bytes[i..], &DIGITS) {
for j in (i..line_bytes.len()).rev() {
if let Some(last_digit) = Self::num_or_digit(&line_bytes[i..j], &DIGITS_REV) {
return first_digit * 10 + last_digit;
}
}
}
if last_digit.is_none() {
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;
return first_digit * 10 + first_digit;
}
}
println!("{:?} {:?}", first_digit, last_digit);
Into::<i128>::into(first_digit.or(last_digit).unwrap() * 10)
+ Into::<i128>::into(last_digit.or(first_digit).unwrap())
return 0;
}
}
impl AoCSolution for Day1 {
type Input = String;
type Solution = i128;
type Solution = i64;
fn part1(input: Self::Input) -> Self::Solution {
input.lines().map(Self::calibration_value).sum()
input
.lines()
.map(|l| Self::calibration_value(l.as_bytes()))
.sum()
}
fn part2(input: Self::Input) -> Self::Solution {
input.lines().map(Self::calibration_value_words).sum()
input
.lines()
.map(|l| Self::calibration_value_words(l.as_bytes()))
.sum()
}
}