self descriptive number


See On Github

Data

Contributor

Generic placeholder thumbnail

by Yonaba

in lua

Source Code

-- Self-Descriptive Number
-- See: http://en.wikipedia.org/wiki/Self-descriptive_number

-- Checks if the given number is self-descriptive
-- n       :  a number, in base 10
-- returns : true if the number is self-descriptive, false otherwise
return function (n)
  local str_num = tostring(n)
  local digits = {}
  for i = 0, 9 do digits[i] = 0 end
  
  -- Counts the occurences for each digits in the string 
  for d in str_num:gmatch('%d') do
  local num_d = tonumber(d)  
    digits[num_d] = digits[num_d] + 1
  end
  
  -- Checks if each digit position matches the count for this digit
  -- Use i-1 since Lua's string indices start at 1
  for i = 1, #str_num do
    if tonumber(str_num:sub(i,i)) ~= digits[i-1] then return false end
  end
  
  return true
end
-- Tests for selfdescriptivenumber.lua
local is_self_descriptive = require 'selfdescriptivenumber'

local total, pass = 0, 0

local function dec(str, len)
  return #str < len
     and str .. (('.'):rep(len-#str))
      or str:sub(1,len)
end

local function run(message, f)
  total = total + 1
  local ok, err = pcall(f)
  if ok then pass = pass + 1 end
  local status = ok and 'PASSED' or 'FAILED'
  print(('%02d. %68s: %s'):format(total, dec(message,68), status))
end

run('Self-descriptive numbers', function()
  assert(is_self_descriptive(1210) == true)
  assert(is_self_descriptive(2020) == true)
  assert(is_self_descriptive(21200) == true)
  assert(is_self_descriptive(3211000) == true)
  assert(is_self_descriptive(42101000) == true)
  assert(is_self_descriptive(6210001000) == true)
end)

print(('-'):rep(80))
print(('Total : %02d: Pass: %02d - Failed : %02d - Success: %.2f %%')
  :format(total, pass, total-pass, (pass*100/total)))