#!/home/kragen/devel/luajit-2.0/src/luajit -- One million bottles of beer on the wall. local numbers = {} function smallnumber(n) if numbers[n] then return numbers[n] end if n < 20 then return ({[0] = "zero", [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" })[n] elseif n < 100 then local tens_place = {[20] = "twenty", [30] = "thirty", [40] = "forty", [50] = "fifty", [60] = "sixty", [70] = "seventy", [80] = "eighty", [90] = "ninety"} local tens = 10 * math.floor(n / 10) local ones, ones_digit = n % 10, "" if ones ~= 0 then ones_digit = "-"..number(ones) end return tens_place[tens] .. ones_digit elseif n < 1000 then local hundreds = math.floor(n / 100) local ones, ones_digits = n % 100, "" if ones ~= 0 then ones_digits = " "..number(ones) end return number(hundreds).." hundred"..ones_digits end end function number(n) if n < 1000 then numbers[n] = smallnumber(n) return numbers[n] elseif n < 1000*1000 then local thousands = math.floor(n / 1000) local ones, ones_digits = n % 1000, "" if ones ~= 0 then ones_digits = ", "..number(ones) end return number(thousands).." thousand"..ones_digits elseif n == 1000*1000 then return "one million" else error("number too big; only numbers up to one million supported: "..tostring(n)) end end assert(number(0) == "zero") assert(number(1) == "one") assert(number(2) == "two") assert(number(10) == "ten") assert(number(19) == "nineteen") assert(number(20) == "twenty") assert(number(21) == "twenty-one") assert(number(39) == "thirty-nine") assert(number(94) == "ninety-four") assert(number(100) == "one hundred") assert(number(101) == "one hundred one") assert(number(256) == "two hundred fifty-six") assert(number(989) == "nine hundred eighty-nine") assert(number(1000) == "one thousand") assert(number(320856) == "three hundred twenty thousand, eight hundred fifty-six") assert(number(16336) == "sixteen thousand, three hundred thirty-six") function capitalize(s) return string.upper(string.sub(s, 1, 1))..string.sub(s, 2) end function pluralize(n, s) if n == 1 then return s else return s.."s" end end function beer(n) while n > 0 do local text = capitalize(number(n)) local bottles = pluralize(n, "bottle") print(text.." "..bottles.." of beer on the wall,") print(text.." "..bottles.." of beer;") print("Take one down, pass it around,") n = n - 1 text = capitalize(number(n)) if n == 0 then text = "No" end print(text.." "..pluralize(n, "bottle").." of beer on the wall!") print("") end end beer(1000*1000) -- Local Variables: -- compile-command: "./beer.lua" -- End: