Compare commits
1 commit
master
...
2023-day1-
Author | SHA1 | Date | |
---|---|---|---|
Daniel Flanagan | 969d6d3977 |
|
@ -1,115 +1,102 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use std::cell::OnceCell;
|
||||||
|
|
||||||
mod prelude;
|
mod prelude;
|
||||||
|
|
||||||
|
const DIGITS = OnceCell::new();
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
Day1::show(day_input(1), day_input(1))
|
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 {}
|
struct Day1 {}
|
||||||
impl Day1 {
|
impl Day1 {
|
||||||
fn calibration_value(line: &str) -> i128 {
|
fn is_digit(b: &u8) -> bool {
|
||||||
println!("{line}");
|
(ASCII_ZERO..=ASCII_NINE).contains(b)
|
||||||
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 num_name(s: &[u8]) -> Option<u8> {
|
fn to_digit(b: &u8) -> Solution {
|
||||||
for (i, w) in [
|
i64::from(b - ASCII_ZERO)
|
||||||
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
}
|
||||||
]
|
|
||||||
.map(|s| s.as_bytes())
|
fn calibration_value(line_bytes: &[u8]) -> i64 {
|
||||||
|
let i1 = line_bytes.iter().position(Self::is_digit).unwrap();
|
||||||
|
let i2 = line_bytes[i1..]
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.rev()
|
||||||
{
|
.position(Self::is_digit)
|
||||||
if s.starts_with(w) {
|
.unwrap_or(i1);
|
||||||
return Some(i as u8);
|
|
||||||
}
|
Self::to_digit(&line_bytes[i1]) * 10 + Self::to_digit(&line_bytes[i2])
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn num_name_end(s: &[u8]) -> Option<u8> {
|
// part 2
|
||||||
for (i, w) in [
|
|
||||||
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
fn num_name(s: &[u8], digits: &[&[u8]]) -> Option<i64> {
|
||||||
]
|
digits
|
||||||
.map(|s| s.as_bytes())
|
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.position(|d| s.starts_with(d))
|
||||||
{
|
.map(|n| n as i64)
|
||||||
if s.ends_with(w) {
|
|
||||||
return Some(i as u8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calibration_value_words(line: &str) -> i128 {
|
fn num_or_digit(s: &[u8], digits: &[&[u8]]) -> Option<Solution> {
|
||||||
println!("{line}");
|
if Self::is_digit(&s[0]) {
|
||||||
let bytes = line.as_bytes();
|
Some(Self::to_digit(&s[0]))
|
||||||
let mut first_digit: Option<u8> = None;
|
} else {
|
||||||
let mut last_digit: Option<u8> = None;
|
Self::num_name(s, digits)
|
||||||
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:?}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if last_digit.is_none() {
|
|
||||||
println!("{:?}", &bytes[..=n]);
|
fn calibration_value_words(line_bytes: &[u8]) -> i64 {
|
||||||
if (0x30..=0x39).contains(&bytes[n]) {
|
for i in 0..line_bytes.len() {
|
||||||
last_digit = Some(bytes[n] - 0x30);
|
if let Some(first_digit) = Self::num_or_digit(&line_bytes[i..], &DIGITS) {
|
||||||
println!("found last {last_digit:?}");
|
for j in (i..line_bytes.len()).rev() {
|
||||||
} else if let Some(n) = Self::num_name_end(&bytes[..=n]) {
|
if let Some(last_digit) = Self::num_or_digit(&line_bytes[i..j], &DIGITS_REV) {
|
||||||
last_digit = Some(n);
|
return first_digit * 10 + last_digit;
|
||||||
println!("found last text {last_digit:?}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if first_digit.is_some() && last_digit.is_some() {
|
return first_digit * 10 + first_digit;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("{:?} {:?}", first_digit, last_digit);
|
return 0;
|
||||||
Into::<i128>::into(first_digit.or(last_digit).unwrap() * 10)
|
|
||||||
+ Into::<i128>::into(last_digit.or(first_digit).unwrap())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
input
|
||||||
|
.lines()
|
||||||
|
.map(|l| Self::calibration_value(l.as_bytes()))
|
||||||
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(input: Self::Input) -> Self::Solution {
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue