mirror of
https://bitbucket.org/Mattrixwv/projecteulerlua.git
synced 2025-12-06 09:33:58 -05:00
187 lines
6.0 KiB
Lua
187 lines
6.0 KiB
Lua
--ProjectEuler/lua/Problem17.lua
|
|
--Matthew Ellison
|
|
-- Created: 02-07-19
|
|
--Modified: 06-19-20
|
|
--If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
|
|
--All of my requires, unless otherwise listed, can be found at https://bitbucket.org/Mattrixwv/luaClasses
|
|
--[[
|
|
Copyright (C) 2020 Matthew Ellison
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
]]
|
|
|
|
|
|
require "Stopwatch"
|
|
|
|
|
|
local timer = Stopwatch:create();
|
|
timer:start();
|
|
|
|
--This function takes a number and returns it as a string in english
|
|
--This function only works for numbers -1,000,000 < num < 1,000,000
|
|
local function getStringFromNum(number)
|
|
local numberString = "";
|
|
--Starting with the largest digit create a string based on the number passed in
|
|
--Check for negative
|
|
if(number < 0) then
|
|
numberString = numberString .. "negative ";
|
|
--Check if the number is zero
|
|
elseif(number == 0) then
|
|
numberString = numberString .. "zero";
|
|
end
|
|
|
|
--Start with the thousands place
|
|
if((number / 1000) >= 1) then
|
|
numberString = numberString .. getStringFromNum(math.floor(number / 1000));
|
|
numberString = numberString .. " thousand";
|
|
number = number - (math.floor(number / 1000) * 1000);
|
|
end
|
|
|
|
--Check for hundreds place
|
|
if((number / 100) >= 1) then
|
|
numberString = numberString .. getStringFromNum(math.floor(number / 100));
|
|
numberString = numberString .. " hundred";
|
|
number = number - (math.floor(number / 100) * 100);
|
|
end
|
|
|
|
--Insert an and if there is need
|
|
if((numberString ~= "") and (number > 0)) then
|
|
numberString = numberString .. " and ";
|
|
end
|
|
|
|
--Check for tens place
|
|
if((number / 10) >= 2) then
|
|
--For the tens you need to do something special
|
|
local tensPlace = math.floor(number / 10);
|
|
if(tensPlace == 9) then
|
|
numberString = numberString .. "ninety";
|
|
elseif(tensPlace == 8) then
|
|
numberString = numberString .. "eighty";
|
|
elseif(tensPlace == 7) then
|
|
numberString = numberString .. "seventy";
|
|
elseif(tensPlace == 6) then
|
|
numberString = numberString .. "sixty";
|
|
elseif(tensPlace == 5) then
|
|
numberString = numberString .. "fifty";
|
|
elseif(tensPlace == 4) then
|
|
numberString = numberString .. "forty";
|
|
elseif(tensPlace == 3) then
|
|
numberString = numberString .. "thrity";
|
|
elseif(tensPlace == 2) then
|
|
numberString = numberString .. "twenty";
|
|
end
|
|
number = number - (tensPlace * 10);
|
|
--If there is something left in the number you will need a space to separate it
|
|
if(number > 0) then
|
|
numberString = numberString .. ' ';
|
|
end
|
|
--Check for teens
|
|
elseif((number / 10) >= 1) then
|
|
local onesPlace = (number % 10);
|
|
if(onesPlace == 9) then
|
|
numberString = numberString .. "nineteen";
|
|
elseif(onesPlace == 8) then
|
|
numberString = numberString .. "eighteen";
|
|
elseif(onesPlace == 7) then
|
|
numberString = numberString .. "seventeen";
|
|
elseif(onesPlace == 6) then
|
|
numberString = numberString .. "sixteen";
|
|
elseif(onesPlace == 5) then
|
|
numberString = numberString .. "fifteen";
|
|
elseif(onesPlace == 4) then
|
|
numberString = numberString .. "fourteen";
|
|
elseif(onesPlace == 3) then
|
|
numberString = numberString .. "thirteen";
|
|
elseif(onesPlace == 2) then
|
|
numberString = numberString .. "twelve";
|
|
elseif(onesPlace == 1) then
|
|
numberString = numberString .. "eleven";
|
|
elseif(onesPlace == 0) then
|
|
numberString = numberString .. "ten";
|
|
end
|
|
--If this if was hit number was used up
|
|
number = 0;
|
|
end
|
|
|
|
--Check for ones place
|
|
if(number >= 1) then
|
|
if(number == 9) then
|
|
numberString = numberString .. "nine";
|
|
elseif(number == 8) then
|
|
numberString = numberString .. "eight";
|
|
elseif(number == 7) then
|
|
numberString = numberString .. "seven";
|
|
elseif(number == 6) then
|
|
numberString = numberString .. "six";
|
|
elseif(number == 5) then
|
|
numberString = numberString .. "five";
|
|
elseif(number == 4) then
|
|
numberString = numberString .. "four";
|
|
elseif(number == 3) then
|
|
numberString = numberString .. "three";
|
|
elseif(number == 2) then
|
|
numberString = numberString .. "two";
|
|
elseif(number == 1) then
|
|
numberString = numberString .. "one";
|
|
end
|
|
--If this if was hit number was used up
|
|
number = 0;
|
|
end
|
|
|
|
--Return the string
|
|
return numberString;
|
|
end
|
|
|
|
--This function returns the number of letters in a string, ignoring punctuation, whitespace, and numbers
|
|
local function getNumberChars(number)
|
|
local sumOfLetters = 0;
|
|
--Start at location 1 and count the number of letters, ignoring punctuation and whitespace
|
|
for location=1,string.len(number) do
|
|
local tempString = string.sub(number, location, location);
|
|
if(string.match(tempString, "%w")) then
|
|
sumOfLetters = sumOfLetters + 1;
|
|
end
|
|
end
|
|
|
|
--Return the number of letters
|
|
return sumOfLetters;
|
|
end
|
|
|
|
|
|
timer = Stopwatch:create();
|
|
timer:start();
|
|
|
|
START_NUM = 1;
|
|
STOP_NUM = 1000;
|
|
|
|
local sumOfLetters = 0;
|
|
--Start with 1 and increment
|
|
for num=START_NUM,STOP_NUM do
|
|
--Pass the number to a function that will create a string for the number
|
|
local currentNumString = getStringFromNum(num);
|
|
--Pass the string to a function that will count the number of letters in a string, ignoring whitespace, punctuation, and numbers and add the amount tot he running tally
|
|
sumOfLetters = sumOfLetters + getNumberChars(currentNumString);
|
|
end
|
|
|
|
timer:stop();
|
|
|
|
--Print the results
|
|
print("The sum of all the letters in all the numbers " .. START_NUM .. '-' .. STOP_NUM .. " is " .. sumOfLetters);
|
|
print("It took " .. timer:getMilliseconds() .. " milliseconds to run this algorithm");
|
|
|
|
--[[Results:
|
|
The sum of all the letters in all the numbers 1-1000 is 21124
|
|
It took 4.0 milliseconds to run this algorithm
|
|
]]
|