Carlo Di Celico

lua-users home
wiki

I'm a software engineer currently working as a .NET developer. I'm new to Lua, but I love it! It's extremely flexible and blazing fast, both in terms of productivity and performance. What can I say, I'm hooked!

You can see some other stuff I do here[1].

Fun with tables

A small (only 13 lines!) program that tells whether a number from 1 to 100 is divisible by 3, 5, neither, or both. Using Lua's tables, it's possible to create something like a Ruby range and iterate over everything, accomplishing the task in just 13 lines, a testament to Lua's expressiveness.

n, m = {}, {}; for x=1,100 do n[x] = x end
for i,v in ipairs(n) do
  if v % 3 == 0 and v % 5 == 0 then
    m[i] = v .. " is divisible by both 3 and 5!\n"
  elseif v % 3 ~= 0 and v % 5 ~= 0 then
    m[i] = v .. " is not divisible by either 3 or 5!\n"
  elseif v % 3 == 0 then
    m[i] = v .. " is divisible by 3 only!\n"
  elseif v % 5 == 0 then
    m[i] = v .. " is divisible by 5 only!\n"
  end
end
for i,v in ipairs(m) do	print(m[i]) end

I'm working on making it even leaner, I'll keep you posted!

--CarloDiCelico

This is really not a good programming sample, even if you were to make the following fixes...

--JohnBelmonte

I didn't even know "for x=1,100 do" was possible! That definitely makes a difference. I was working on how to keep the program from recalculating those values and essentially came up with the same solution, storing them in local variables. I'm learning Lua as I go, so forgive me for not coding as eloquently as I could in some other language! Besides, the whole point was to do it using tables, not to do it without tables. I just wanted to play with the tables, hence the name of the page.

--CarloDiCelico

"for x=1,100 do" is in the very first line of your code... Anyway there is nothing wrong with learning the ropes, but this seems more appropriate as a local file on your computer rather than a public wiki page.

Half-baked content might also be temporarily placed on one's personal page (e.g. CarloDiCelico) and possibly later migrated to some more permanent place on the wiki once it's more clear where it should go. Below is another way to write that. --DavidManura

local text = {
  [false] = {
    [false] = "%d is not divisible by either %d or %d!",
    [true]  = "%d is not divisible by %d but is divisible by %d!",
  },
  [true] = {
    [false] = "%d is divisible by %d but not by %d!",
    [true]  = "%d is divisible by both %d and %d!"
  }
}
for x=1,100 do
  print(string.format(text[x % 3 == 0][x % 5 == 0], x, 3, 5))
end

Here are two more variants. --ShmuelZeigerman

-- common to both variants
local a, b, c, d  =
  " is not divisible by either 3 or 5",
  " is divisible by 3 but not by 5",
  " is divisible by 5 but not by 3",
  " is divisible by both 3 and 5"

-- variant #1 --
local t = { a,b,c,d }
for x=1,100 do
  print(x .. t[(x%3==0 and 1 or 0) + (x%5==0 and 2 or 0) + 1])
end

-- variant #2 --
for x=1,100 do
  print(x .. (x%3==0 and (x%5==0 and d or b) or (x%5==0 and c or a)))
end

I would argue that the discussion my poor code has provoked is more than reason enough to leave it up here! This is great and the positive remarks and code samples are useful to newcomers who are trying to learn Lua and get a feel for Lua's community.

-- CarloDiCelico

Unsolicited Perl version:

print join("\n", map { $_.": ".("3 & 5","5","3","neither")[($_ % 3 && 1)+2*($_ % 5 && 1)] } (1..100) );
-- JAPH :)

I say this would be a simpler method than the original post. This method would mean tables aren't needed, which they aren't, for this particular instance.

for a=1,100 do
  if(a%3==0)and(a%5==0)then
    print(a.." is divisible by both 3 and 5!\n")
  elseif(a%3==0)then
    print(a.." is divisible by 3 only!\n")
  elseif(a%5==0)then
    print(a.." is divisible by 5 only!\n")
  else
    print(a.." is not divisible by either 3 or 5!\n")
  end
end
Though, if you wanted to use tables, I suppose you could do this?
myTable={" is divisible by both 3 and 5!\n"," is divisible by 3 only!\n"," is divisible by 5 only!\n"," is not divisible by either 3 or 5!\n"}
for a=1,100 do
  if(a%3==0)and(a%5==0)then
    print(a..myTable[1])
  elseif(a%3==0)then
    print(a..myTable[2])
  elseif(a%5==0)then
    print(a..myTable[3])
  else
    print(a..myTable[4])
  end
end
Lastly, now that I've learned that you can create an argument with the words and and or, I would use this method:
myTable={" is divisible by both 3 and 5!\n"," is divisible by 3 only!\n"," is divisible by 5 only!\n"," is not divisible by either 3 or 5!\n"}
for a=1,10 do
print(a..myTable[(a%3==0 and -2 or 0)+(a%5==0 and -1 or 0)+4])
end
Thanks to CarloDiCelico's example, I learned to do this concept. :) -- Rob
RecentChanges · preferences
edit · history
Last edited February 5, 2012 8:17 am GMT (diff)