第15回オフラインリアルタイムどう書くをLuaで


- 上段と下段のビットを同じ桁でつなげる
- ビット数の多い文字から順にマッチングを試す
- 上段、下段ともにビット 0 の場合は、その二つのビット 0 をスキップする

```lua:Lua
-- http://qiita.com/Nabetani/items/cba03c96d1ea55f6e861
-- http://nabetani.sakura.ne.jp/hena/ord15elebubo/

tab = {
   ['1101'] = 'L',
   ['1110'] = 'R',
   ['0111'] = 'J',   
   ['101110'] = 'T',
   ['110111'] = 'U',
   ['111011'] = 'N',
   ['011110'] = 'S',
   ['101101'] = 'Z',
}

function bin(n)
   local t = ''
   for i = 0, 32-1 do
      if bit32.band(n, bit32.lshift(1, i)) > 0 then
         t = '1' .. t
      else
         t = '0' .. t
      end
   end
   return t
end

function calc(s)
   local a = bin(tonumber(s:sub(1, 8), 16))
   local b = bin(tonumber(s:sub(10), 16))
   local t = ''
   for i = 1, 32 do
      t = t .. a:sub(i, i) .. b:sub(i, i)
   end

   local keys = {}
   for k, v in pairs(tab) do keys[#keys+1] = k end
   -- キーの長さでソート
   table.sort(keys, function(a, b) return a:len() > b:len() end)

   local ans = ''
   while t:len() > 0 do
      local found = false
      for i = 1, #keys do
         local k = keys[i]
         local v = tab[k]
         if k == t:sub(1, k:len()) then
            ans = ans .. v
            t = t:sub(k:len()+1)
            found = true
            break
         end
      end

      if not found then
         t = t:sub(3)
      end
   end
   
   return ans
end

function test(input, expected)
   if calc(input) == expected then
      print('OK')
   else
      print('failed', input, expected)
   end
end

function main()
   test( "2ed8aeed/34b0ea5b", "LTRSUNTSJ" );    
   test( "00000200/00000300", "L" );    
   test( "00018000/00010000", "R" );    
   test( "00002000/00006000", "J" );    
   test( "00000700/00000200", "T" );    
   test( "01400000/01c00000", "U" );    
   test( "00003800/00002800", "N" );    
   test( "000c0000/00180000", "S" );    
   test( "00003000/00001800", "Z" );    
   test( "132eae6c/1a64eac6", "LRJTUNSZ" );    
   test( "637572d0/36572698", "ZSNUTJRL" );    
   test( "baddb607/d66b6c05", "LTJZTSSSN" );    
   test( "db74cd75/6dac6b57", "ZZZTJZRJNU" );    
   test( "3606c2e8/1b0d8358", "ZZSSLTJ" );    
   test( "ad98c306/e6cc6183", "UZZZZZZ" );    
   test( "4a4aaee3/db6eeaa6", "JJLLUUNNS" );    
   test( "ecd9bbb6/598cd124", "TSSZZTTRR" );    
   test( "e0000002/40000003", "TL" );    
   test( "a0000007/e0000005", "UN" );    
   test( "c0000003/80000006", "RS" );    
   test( "40000006/c0000003", "JZ" );    
   test( "01da94db/00b3b6b2", "TSUJLRSR" );    
   test( "76eeaaea/24aaeeae", "TRNNUUNU" );    
   test( "1dacaeee/1566e444", "NRJZUTTT" );    
   test( "26c9ac60/6c6d66c0", "JSZLRJZS" );    
   test( "6c977620/36da5360", "ZZLLTNZJ" );    
   test( "069aeae6/0db34eac", "SJSLTUNS" );    
   test( "06d53724/049da56c", "RRULRNJJ" );    
   test( "069b58b0/04d66da0", "RLRSLZJR" );    
   test( "1b6eced4/11b46a9c", "RZZTZNRU" );    
   test( "522e8b80/db6ad900", "JLLJNLJT" );    
   test( "6546cdd0/376c6898", "ZULSZRTL" );    
   test( "4e6d5b70/6ad9d620", "LNSSURST" );    
   test( "37367772/65635256", "SNSZNTNJ" );    
   test( "25535d58/377669cc", "LUUSLTUZ" );    
   test( "0ae6a55d/0eacedcb", "UNSUJUTJ" );    
   test( "76762edc/23536a88", "TZNZJNRT" );   
end

main()
```