feat: 17 - number letter counts

added phf_map for constant hashmap like structures
This commit is contained in:
newt 2024-10-09 18:10:11 +01:00
parent 2c64ab4657
commit d2e0a5cd91
5 changed files with 161 additions and 5 deletions

45
Cargo.lock generated
View file

@ -253,6 +253,7 @@ dependencies = [
"html-escape",
"num-bigint",
"owo-colors",
"phf 0.11.1",
"regex",
"requestty",
"reqwest",
@ -858,7 +859,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_macros",
"phf_macros 0.8.0",
"phf_shared 0.8.0",
"proc-macro-hack",
]
@ -872,6 +873,16 @@ dependencies = [
"phf_shared 0.10.0",
]
[[package]]
name = "phf"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c"
dependencies = [
"phf_macros 0.11.1",
"phf_shared 0.11.1",
]
[[package]]
name = "phf_codegen"
version = "0.8.0"
@ -912,6 +923,16 @@ dependencies = [
"rand 0.8.5",
]
[[package]]
name = "phf_generator"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf"
dependencies = [
"phf_shared 0.11.1",
"rand 0.8.5",
]
[[package]]
name = "phf_macros"
version = "0.8.0"
@ -926,6 +947,19 @@ dependencies = [
"syn",
]
[[package]]
name = "phf_macros"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66"
dependencies = [
"phf_generator 0.11.1",
"phf_shared 0.11.1",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
@ -944,6 +978,15 @@ dependencies = [
"siphasher",
]
[[package]]
name = "phf_shared"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"

View file

@ -14,6 +14,7 @@ tokio = { version = "1.23", features = ["full"] }
regex = "1"
html-escape = "0.2.13"
num-bigint = "0.4.3"
phf = { version = "0.11.1", features = ["macros"] }
[profile.release]
opt-level = "z"

View file

@ -11,7 +11,7 @@ I originally started the challenge in [the-honk](https://github.com/newtykins/th
## Challenge Completion
### <!-- completed -->20<!-- completed --> out of 100 public challenges completed.
### <!-- completed -->21<!-- completed --> out of 100 public challenges completed.
- [x] 1 - [Multiples of 3 or 5](src/bin/1.rs)
- [x] 2 - [Even Fibonacci numbers](src/bin/2.rs)
@ -29,7 +29,7 @@ I originally started the challenge in [the-honk](https://github.com/newtykins/th
- [x] 14 - [Longest Collatz sequence](src/bin/14.rs)
- [x] 15 - [Lattice paths](src/bin/15.rs)
- [x] 16 - [Power digit sum](src/bin/16.rs)
- [ ] 17 - Number letter counts
- [x] 17 - [Number letter counts](src/bin/17.rs)
- [ ] 18 - Maximum path sum I
- [ ] 19 - Counting Sundays
- [ ] 20 - Factorial digit sum

View file

@ -15,13 +15,17 @@ fn get_digits(number: usize) -> Vec<u32> {
}
fn power_digit_sum(base: usize, power: u32) -> usize {
let answer = BigUint::new(get_digits(base)).pow(power).to_string().chars().collect::<Vec<char>>();
let answer = BigUint::new(get_digits(base))
.pow(power)
.to_string()
.chars()
.collect::<Vec<char>>();
let mut sum = 0;
for i in 0..answer.len() {
let number = answer[i].to_string().parse::<usize>().unwrap();
sum += number;
}

108
src/bin/17.rs Normal file
View file

@ -0,0 +1,108 @@
/*
Problem 17 - Number letter counts
If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
*/
use std::ops::Div;
use phf::phf_map;
const TRANSLATIONS: phf::Map<u16, &'static str> = phf_map! {
0u16 => "",
1u16 => "one",
2u16 => "two",
3u16 => "three",
4u16 => "four",
5u16 => "five",
6u16 => "six",
7u16 => "seven",
8u16 => "eight",
9u16 => "nine",
10u16 => "ten",
11u16 => "eleven",
12u16 => "twelve",
13u16 => "thirteen",
14u16 => "fourteen",
15u16 => "fifteen",
16u16 => "sixteen",
17u16 => "seventeen",
18u16 => "eighteen",
19u16 => "nineteen",
20u16 => "twenty",
30u16 => "thirty",
40u16 => "forty",
50u16 => "fifty",
60u16 => "sixty",
70u16 => "seventy",
80u16 => "eighty",
90u16 => "ninety"
};
fn number_to_words(number: usize) -> String {
let mut n = number.clone();
let mut out = String::new();
// Thousands
let thousands = n.div(1000);
n -= thousands * 1000;
if thousands > 0 {
out = format!("{}thousand", TRANSLATIONS.get(&(thousands as u16)).unwrap());
}
// Hundreds
let hundreds = n.div(100);
n -= hundreds * 100;
if hundreds > 0 {
out = format!("{out}{}hundred", TRANSLATIONS.get(&(hundreds as u16)).unwrap());
}
// Tens
let tens = n.div(10);
n -= tens * 10;
if tens > 0 {
let translation: &str;
let and = if hundreds > 0 {"and"} else {""};
if n % 10 > 0 && tens == 1 {
translation = TRANSLATIONS.get(&((10 + (n % 10)) as u16)).unwrap();
n -= n % 10;
} else {
translation = TRANSLATIONS.get(&(tens as u16 * 10)).unwrap();
}
out = format!("{out}{and}{}", translation);
}
// Remainder
if n > 0 {
let and = if hundreds > 0 && tens <= 0 {"and"} else {""};
out = format!("{out}{and}{}", TRANSLATIONS.get(&(n as u16)).unwrap());
}
out
}
fn letter_count(upper_bound: usize) -> usize {
let mut sum = 0;
for i in 1..(upper_bound + 1) {
println!("{} {}", number_to_words(i), number_to_words(i).len());
sum += number_to_words(i).len();
}
sum
}
fn main() {
let sum = letter_count(1000);
println!("{} letters would be used to write out all of the numbers from 1 to 1000!", sum);
}