Four is Magic function

function FourIsMagic(Number)
	local function NumberToWord(Number1)
		local OnesList = {[0] = "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"}
		local TeenList = {[0] = "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}
		local TensList = {[0] = "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}
		local LionList = {[0] = "", "Thousand", "Million", "Billion", "Trillion", "Quadrillion", "Quintillion", "Sextillion", "Septillion", "Octillion", "Nonillion"}
		local DecimalList = {[0] = "", "Tenth", "Hundredths", "Thousandths", "Ten-Thousandths", "Hundred-Thousandths", "millionths", "Ten-Millionths", "Hundred-Millionths", "Billionths", "Ten-Billionths", "Hundred-Billionths", "Trillionths", "Ten-Trillionths", "Hundred-Trillionths"}
		local Numbers = Number1 % 1 ~= 0 and string.split(tostring(Number1), ".") or {Number1}
		local DecimalPlaces = Number1 % 1 ~= 0 and string.len(Numbers[2]) or 0
		local Results = {"", ""}
		if Number1 == 0 then
			return "Zero"
		end
		local function AddSpaceOrHyphen(String, Add)
			return String == "" and String or Add..String
		end
		local function AddToResult(Number2, ResultNumber)
			local Lion = 0
			while Number2 > 0 do
				local Word = ""
				local Ones = Number2 % 10
				local Tens = math.floor(Number2 / 10) % 10
				local Hundreds = math.floor(Number2 / 100) % 10
				Word = Tens == 0 and OnesList[Ones] or Tens == 0 and TeenList[Ones] or TensList[Tens]..AddSpaceOrHyphen(OnesList[Ones], "-")
				Word = Hundreds > 0 and OnesList[Hundreds].." Hundred"..AddSpaceOrHyphen(Word, " ") or Word
				Results[ResultNumber] = Word ~= "" and Word..AddSpaceOrHyphen(LionList[Lion], " ")..AddSpaceOrHyphen(Results[ResultNumber], " ") or Results[ResultNumber]
				Number2 = math.floor(Number2 / 1000)
				Lion += 1
			end
		end
		for i, v in ipairs(Numbers) do
			if i == 1 and v == 0 then
				continue
			end
			Results[1] ..= i == 2 and Numbers[1] ~= "0" and " and " or ""
			AddToResult(tonumber(v), i)
			Results[2] ..= i == 2 and AddSpaceOrHyphen(DecimalList[DecimalPlaces], " ") or ""
		end
		return table.concat(Results)
	end
	if type(Number) ~= "number" then
		return "Can't be converted"
	end
	local Table = {}
	local AbsoluteNumber = math.abs(Number)
	if AbsoluteNumber > 4 * 10^30 or AbsoluteNumber ~= tonumber(tostring(AbsoluteNumber)) then
		return "Can't be converted"
	end
	local Negative = AbsoluteNumber ~= Number and "Negative " or ""
	local NumberText = NumberToWord(AbsoluteNumber)
	local NumberLengthText = NumberToWord(string.len(Negative..NumberText))
	if NumberText == "Four" and Negative == "" then
		return {"Four is Magic"}
	end
	while true do
		table.insert(Table, Negative..NumberText.." is "..NumberLengthText)
		if NumberLengthText == "Magic" then
			break
		end
		Negative = ""
		NumberText = NumberLengthText
		NumberLengthText = NumberText == "Four" and "Magic" or NumberToWord(string.len(NumberText))
	end
	return Table
end

print(FourIsMagic(221))
print(FourIsMagic(0.42))
print(FourIsMagic(221.42))

I attempted to make try out this challenge on Four is magic - Rosetta Code
now yes lua is already on there but I decided to make it by myself
I ended up taking the number to word conversion function from the lua answer, but I changed it to make it my own

I want to know if this can be improved at all, I had fun making this
oh and this will return “Can’t be converted” if the number is greater than or equal to 4 nonillion or if the number is a fraction

thanks for looking at this if you did :smiley:

2 Likes

This is really cool! I haven’t ever heard about this coding challenge before. I’ll be giving this a shot next time I have the chance.

1 Like

I have added functionality for fractions!
you can go all the way past Hundred-Trillionths place now or in simple terms, 14 decimal places
any more decimal places after that will be return “Can’t be converted”, oh and it will also return “Can’t be converted” if you don’t enter a number
EXAMPLE: print(FourIsMagic("221")) -- "Can't be converted"

hope you enjoy the edit!

I have improved my readability skills since I made this post

I might update it if people want me to