Reduce allocations and refactoring

This commit is contained in:
2022-10-16 15:37:13 +02:00
parent 653a5cb17a
commit 7c0439ea30

View File

@@ -9,37 +9,30 @@ https://projecteuler.net/problem=17 =#
using BenchmarkTools using BenchmarkTools
function num2letters(num) function num2letters(num, nums)
nums = Dict(
0 => "", 1 => "one", 2 => "two", 3 => "three", 4 => "four", 5 => "five",
6 => "six", 7 => "seven", 8 => "eight", 9 => "nine", 10 => "ten",
11 => "eleven", 12 => "twelve", 13 => "thirteen", 14 => "fourteen",
15 => "fifteen", 16 => "sixteen", 17 => "seventeen", 18 => "eighteen",
19 => "nineteen", 20 => "twenty", 30 => "thirty", 40 => "forty",
50 => "fifty", 60 => "sixty", 70 => "seventy", 80 => "eighty",
90 => "ninety", 100 => "hundred", 1000 => "thousand"
)
if num <= 20 if num <= 20
return length(nums[num]) return nums[num]
elseif num < 100 elseif num < 100
tens, units = divrem(num, 10) tens, units = divrem(num, 10)
return (length(nums[Int(tens) * 10]) + num2letters(units)) return (nums[tens*10] + num2letters(units, nums))
elseif num < 1000 elseif num < 1000
hundreds, rest = divrem(num, 100) hundreds, rest = divrem(num, 100)
if rest != 0 if rest != 0
return (num2letters(hundreds) + length(nums[100]) return (
+ length("and") + num2letters(rest)) num2letters(hundreds, nums) +
nums[100] +
length("and") +
num2letters(rest, nums)
)
else else
return (num2letters(hundreds) + length(nums[100])) return (num2letters(hundreds, nums) + nums[100])
end end
else else
thousands, rest = divrem(num, 1000) thousands, rest = divrem(num, 1000)
return (num2letters(thousands) + length(nums[1000])) return (num2letters(thousands, nums) + nums[1000])
end end
end end
function Problem17() function Problem17()
#= #=
If the numbers 1 to 5 are written out in words: one, two, three, four, If the numbers 1 to 5 are written out in words: one, two, three, four,
@@ -53,11 +46,44 @@ function Problem17()
20 letters. The use of "and" when writing out numbers is in compliance 20 letters. The use of "and" when writing out numbers is in compliance
with British usage. =# with British usage. =#
nums = Dict(
0 => 0,
1 => 3,
2 => 3,
3 => 5,
4 => 4,
5 => 4,
6 => 3,
7 => 5,
8 => 5,
9 => 4,
10 => 3,
11 => 6,
12 => 6,
13 => 8,
14 => 8,
15 => 7,
16 => 7,
17 => 9,
18 => 8,
19 => 8,
20 => 6,
30 => 6,
40 => 5,
50 => 5,
60 => 5,
70 => 7,
80 => 6,
90 => 6,
100 => 7,
1000 => 8,
)
n = 1000 n = 1000
letters = 0 letters = 0
for num in 1:n for num = 1:n
letters += num2letters(num) letters += num2letters(num, nums)
end end
return letters return letters
end end