aboutsummaryrefslogtreecommitdiff
path: root/challenge-081/tyler-wardhaugh/lua/ch-2.lua
blob: 49b5732fb1867907ac6c7c5848a72bb9937eb452 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env lua

--[[
   An iterator over a table yielding keys (and their corresponding values) in
   sorted order.

   source: ideas from "keysToList" (and others) in:
      http://lua-users.org/wiki/SortedIteration
]]--
function ordered_pairs(tbl, cmp)
  local o = {}
  for k, _ in pairs(tbl) do table.insert(o, k) end
  table.sort(o, cmp)

  local i = 0
  return function()
    i = i + 1
    return o[i], tbl[o[i]]
  end
end

local t2 = {}

do
  local lpeg = require'lpeg'
  lpeg.locale(lpeg)
  local C, Cs, Ct, P, S = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.S

  local strip = (S[[."(),]] + P"'s" + P"--" + P"\n")
  t2.sanitizer = Cs((strip / " " + 1)^0)

  local space = lpeg.space^1
  local word = C((1 - space)^1)
  t2.wordify = Ct(word * (space * word)^0)
end

function t2.frequency_sort(text)
  local sanitized = t2.sanitizer:match(text)
  local words = t2.wordify:match(sanitized)

  local count = {}
  for _, v in ipairs(words) do count[v] = (count[v] or 0) + 1 end

  local invert = {}
  for k, v in pairs(count) do
    if invert[v] then
      table.insert(invert[v], k)
    else
      invert[v] = {k}
    end
  end

  for _, v in pairs(invert) do table.sort(v) end

  return invert
end

function t2.slurp(input)
  local fh = assert(io.open(input, "r"))
  local text = fh:read("*all")
  fh:close()
  return text
end

function t2.run(args)
  local input = args[1]
  local results = t2.frequency_sort(t2.slurp(input))
  for k, v in ordered_pairs(results) do
    print(k, table.concat(v, " "), "\n")
  end
end

return t2