summaryrefslogtreecommitdiff
path: root/stats.lua
diff options
context:
space:
mode:
Diffstat (limited to 'stats.lua')
-rw-r--r--stats.lua68
1 files changed, 68 insertions, 0 deletions
diff --git a/stats.lua b/stats.lua
new file mode 100644
index 0000000..1cb485d
--- /dev/null
+++ b/stats.lua
@@ -0,0 +1,68 @@
+local format = require "format"
+local stats = {}
+local mt = {__index=stats}
+
+
+local function new (name_or_obj, parent)
+ if type(name_or_obj) == "string" then
+ name_or_obj = {
+ name = name_or_obj,
+ parent = parent,
+ letters = 0,
+ length = 0,
+ counts = {},
+ children = {},
+ }
+ end
+ return setmetatable(name_or_obj, mt)
+end
+
+
+function stats:add (value)
+ local current = self.counts[value] or 0
+ if current == 0 then
+ self.letters = self.letters + 1
+ end
+ self.length = self.length + 1
+ self.counts[value] = current + 1
+ if self.parent then
+ self.parent:add(value)
+ end
+end
+
+
+function stats:sub (name)
+ local child = new(name, self)
+ table.insert(self.children, child)
+ return child
+end
+
+
+function stats:ioc (letters)
+ letters = letters or self.letters
+ local subtotal = 0
+ for _, count in pairs(self.counts) do
+ subtotal = subtotal + count * (count - 1)
+ end
+ return subtotal / (self.length * (self.length - 1) / letters)
+end
+
+
+function stats:dump ()
+ local function dump (stat)
+ local letters = (stat.parent or {}).letters
+ io.write(stat.name, "\t", stat.length, "\t", stat.letters, "\t", format.float(stat:ioc(letters)))
+ if letters then
+ io.write("\t", format.float(stat:ioc()))
+ end
+ print()
+ end
+
+ dump(self)
+ for _, child in ipairs(self.children) do
+ dump(child)
+ end
+end
+
+
+return new