Guest User

Lua

a guest
Dec 2nd, 2021
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.40 KB | None | 0 0
  1.  
  2. local string = require "string"
  3. local table = require "table"
  4.  
  5. local byte = string.byte
  6. local char = string.char
  7. local unpack = table.unpack
  8.  
  9. pt = os.clock()
  10. print('prepare')
  11.  
  12. -- somewhere from stackoverflow.com
  13.  
  14. function trim_spaces (str)
  15.   if str == '' then
  16.     return str
  17.   else  
  18.     local startPos = 1
  19.     local endPos   = #str
  20.  
  21.     while (startPos < endPos and str:byte(startPos) <= 32) do
  22.       startPos = startPos + 1
  23.     end
  24.  
  25.     if startPos >= endPos then
  26.       return ''
  27.     else
  28.       while (endPos > 0 and str:byte(endPos) <= 32) do
  29.         endPos = endPos - 1
  30.       end
  31.  
  32.       return str:sub(startPos, endPos)
  33.     end
  34.   end
  35. end -- .function trim
  36.  
  37. -- from https://github.com/nmap/nmap/blob/master/nselib/unicode.lua
  38.  
  39. function utf8_enc(cp)
  40.   local bytes = {}
  41.   local n, mask
  42.  
  43.   if cp % 1.0 ~= 0.0 or cp < 0 then
  44.     -- Only defined for nonnegative integers.
  45.     return nil
  46.   elseif cp <= 0x7F then
  47.     -- Special case of one-byte encoding.
  48.     return char(cp)
  49.   elseif cp <= 0x7FF then
  50.     n = 2
  51.     mask = 0xC0
  52.   elseif cp <= 0xFFFF then
  53.     n = 3
  54.     mask = 0xE0
  55.   elseif cp <= 0x10FFFF then
  56.     n = 4
  57.     mask = 0xF0
  58.   else
  59.     return nil
  60.   end
  61.  
  62.   while n > 1 do
  63.     bytes[n] = char(0x80 + (cp & 0x3F))
  64.     cp = cp >> 6
  65.     n = n - 1
  66.   end
  67.   bytes[1] = char(mask + cp)
  68.  
  69.   return table.concat(bytes)
  70. end
  71.  
  72. function utf8_dec(buf, pos)
  73.   pos = pos or 1
  74.   local n, mask
  75.   local bv = byte(buf, pos)
  76.   if bv <= 0x7F then
  77.     return pos+1, bv
  78.   elseif bv <= 0xDF then
  79.     --110xxxxx 10xxxxxx
  80.     n = 1
  81.     mask = 0xC0
  82.   elseif bv <= 0xEF then
  83.     --1110xxxx 10xxxxxx 10xxxxxx
  84.     n = 2
  85.     mask = 0xE0
  86.   elseif bv <= 0xF7 then
  87.     --11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  88.     n = 3
  89.     mask = 0xF0
  90.   else
  91.     return nil, string.format("Invalid UTF-8 byte at %d", pos)
  92.   end
  93.  
  94.   local cp = bv - mask
  95.  
  96.   if pos + n > #buf then
  97.     return nil, string.format("Incomplete UTF-8 sequence at %d", pos)
  98.   end
  99.   for i = 1, n do
  100.     bv = byte(buf, pos + i)
  101.     if bv < 0x80 or bv > 0xBF then
  102.       return nil, string.format("Invalid UTF-8 sequence at %d", pos + i)
  103.     end
  104.     cp = (cp << 6) + (bv & 0x3F)
  105.   end
  106.  
  107.   return pos + 1 + n, cp
  108. end
  109.  
  110. function decode(buf, decoder, bigendian)
  111.   local cp = {}
  112.   local pos = 1
  113.   while pos <= #buf do
  114.     pos, cp[#cp+1] = decoder(buf, pos, bigendian)
  115.   end
  116.   return cp
  117. end
  118.  
  119. function encode(list, encoder, bigendian)
  120.   local buf = {}
  121.   for i, cp in ipairs(list) do
  122.     buf[i] = encoder(cp, bigendian)
  123.   end
  124.   return table.concat(buf, "")
  125. end
  126.  
  127. -- somewhere from stackoverflow.com
  128.  
  129. -- see if the file exists
  130. function file_exists(file)
  131.   local f = io.open(file, "rb")
  132.   if f then f:close() end
  133.   return f ~= nil
  134. end
  135.  
  136. -- get all lines from a file, returns an empty
  137. -- list/table if the file does not exist
  138. function lines_from(file)
  139.   if not file_exists(file) then return {} end
  140.   lines = {}
  141.   for line in io.lines(file) do
  142.     lines[#lines + 1] = decode(trim_spaces(line), utf8_dec)
  143.   end
  144.   return lines
  145. end
  146.  
  147. -- tests the functions above
  148. local file = '../../russian_nouns.txt'
  149. local lines = lines_from(file)
  150.  
  151. -- -- print all line numbers and their contents
  152. -- for k,v in pairs(lines) do
  153. --   print('line[' .. k .. ']', v)
  154. -- end
  155.  
  156. -- own
  157.  
  158. local found = ''
  159. local fln = 1
  160. local hti = ''
  161. local xln = 1
  162.  
  163. function ps(x)
  164.   return encode(x, utf8_enc)
  165. end
  166.  
  167. function get_intersection(ar, br, fln)
  168.  
  169.   local i = 1
  170.  
  171.   for j = 2, #ar do
  172.  
  173.     if i == #br then
  174.       break
  175.     end
  176.  
  177.     local r = ar[j]
  178.  
  179.     if br[i] == r then
  180.         i = i + 1
  181.     else
  182.         i = 1
  183.     end
  184.  
  185.   end
  186.  
  187.   if (i <= fln) or (i >= #ar) or (i >= #br) then
  188.     return '', 1
  189.   end
  190.  
  191.   -- print('[8] I ' .. i)
  192.   return ps({ unpack(ar, 1, #ar - i + 1) }) ..
  193.      '[' ..
  194.      ps({ unpack(ar, #ar - i + 2, #ar) }) ..
  195.      ']' ..
  196.      ps({ unpack(br, i, #br) }), i
  197. end
  198.  
  199. print('prepared after ' .. os.clock() - pt .. 's')
  200. print()
  201. print('start')
  202. sp = os.clock()
  203.  
  204. for i, f in pairs(lines) do
  205.   for j, x in pairs(lines) do
  206.     if i == j then
  207.         goto continue -- skip the same
  208.     end
  209.  
  210.     if fln > 1 and ((#f <= (fln+2)) or (#x <= (fln+2))) then
  211.         goto continue -- looking for a longer
  212.     end
  213.  
  214.         hti, xln = get_intersection(f, x, fln)
  215.         if xln > 1 then
  216.            found, fln = hti, xln
  217.            print(fln-1, found)
  218.         end
  219.  
  220.     ::continue::
  221.   end
  222. end
  223.  
  224. print()
  225. print(fln-1, found, 'after ' .. os.clock() - sp .. 's')
  226.  
Advertisement
Add Comment
Please, Sign In to add comment