Cobra_Tomtrein-temp-

huffman

Jul 23rd, 2017
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.84 KB | None | 0 0
  1. --BASE FUNCTIONS
  2. local huffman = _G.huffman or {}
  3.  
  4. function dequeue(buff)
  5. local val = buff[1]
  6. if #buff <= 1 then
  7. buff[1] = nil
  8. return val
  9. else
  10. for i=2,#buff do
  11. buff[i-1] = buff[i]
  12. buff[i] = nil
  13. end
  14. end
  15. return val
  16. end
  17.  
  18. function enqueue(tab,data,ind)
  19. if ind then
  20. for i=#tab,ind,-1 do
  21. tab[i+1] = tab[i]
  22. end
  23. else
  24. ind = #tab+1
  25. end
  26. tab[ind] = data
  27. end
  28.  
  29. function insertOrder(data,tab,valueFunc)
  30. local n_val = valueFunc(data)
  31. for i2=1,#tab do
  32. local val = valueFunc(tab[i2])
  33. if n_val <= val then
  34. enqueue(tab,data,i2)
  35. return
  36. end
  37. end
  38. enqueue(tab,data)
  39. end
  40.  
  41. function sort(tab,valueFunc)
  42. local tab2 = {}
  43. for i,v in pairs(tab) do
  44. tab2[i] = v
  45. end
  46. for i=1,#tab do
  47. tab[i] = nil
  48. end
  49. for i=1,#tab2 do
  50. local data = tab2[i]
  51. insertOrder(data,tab,valueFunc)
  52. end
  53. end
  54.  
  55.  
  56. function makeLeaf(freq,char)
  57. local leaf = {}
  58. leaf.freq = freq
  59. leaf.char = char
  60. return leaf
  61. end
  62.  
  63. function isLeaf(leaf)
  64. return leaf.char ~= nil
  65. end
  66.  
  67. function makeNode(n_l1,n_l2)
  68. local node = {}
  69. node.freq = n_l1.freq + n_l2.freq
  70. node.left = n_l1
  71. node.right = n_l2
  72. print("Node made")
  73. return node
  74. end
  75.  
  76. function getFreq(node)
  77. return node.freq
  78. end
  79.  
  80. function makeCharBitTable_node(node,tbl,base)
  81. if isLeaf(node) then
  82. tbl[node.char] = base
  83. return
  84. end
  85. local m_base1 = {}
  86. local m_base2 = {}
  87. for i=1,#base do
  88. m_base1[i] = base[i]
  89. m_base2[i] = base[i]
  90. end
  91. m_base1[#base+1] = 0
  92. m_base2[#base+1] = 1
  93.  
  94. makeCharBitTable_node(node.left,tbl,m_base1)
  95.  
  96. makeCharBitTable_node(node.right,tbl,m_base2)
  97. end
  98.  
  99. function makeCharBitTable(node_tree)
  100. print(node_tree)
  101. local tbl = {}
  102. makeCharBitTable_node(node_tree.left,tbl,{0})
  103. makeCharBitTable_node(node_tree.right,tbl,{1})
  104. return tbl
  105. end
  106.  
  107. huffman.checkNodeTable = makeCharBitTable
  108.  
  109.  
  110.  
  111. function make_table(txt)
  112. local tab = {}
  113. for chr in txt:gmatch(".") do
  114. tab[chr] = (tab[chr] or 0) + 1
  115. end
  116. return tab
  117. end
  118.  
  119. function sort_huffman_table(tab)
  120. while #tab > 1 do
  121. sort(tab,getFreq)
  122. --print(textutils.serialize(tab))
  123. local n1 = dequeue(tab)
  124. --print("node1: "..textutils.serialize(n1))
  125. local n2 = dequeue(tab)
  126. --print("node2: "..textutils.serialize(n2))
  127. --print(#tab)
  128. local n3 = makeNode(n1,n2)
  129. --print("Node3: "..textutils.serialise(n3))
  130. --print(textutils.serialise(tab))
  131. insertOrder(n3,tab,getFreq)
  132. end
  133. return tab
  134. end
  135.  
  136. function make_huffman_table(txt)
  137. local tab = make_table(txt)
  138. --print(#tab)
  139. local nodeTable = {}
  140. for chr,freq in pairs(tab) do
  141. nodeTable[#nodeTable+1] = makeLeaf(freq,chr)
  142. end
  143. --print(textutils.serialize(nodeTable))
  144. sort_huffman_table(nodeTable)
  145. return nodeTable[1]
  146. end
  147.  
  148. function decode_node(node_base,bits)
  149. --print("NodeBase: "..textutils.serialize(node_base or {}))
  150. local m_bit = dequeue(bits)
  151. --print("Bit: "..m_bit)
  152. local m_node = nil
  153. if m_bit == 0 then
  154. m_node = node_base.left
  155. --print("Node: "..textutils.serialize(m_node))
  156. else
  157. m_node = node_base.right
  158. end
  159. if isLeaf(m_node) then
  160. --print("IS a leaf")
  161. return m_node.char
  162. else
  163. return decode_node(m_node,bits)
  164. end
  165. end
  166.  
  167. function decode(node_tree,bits_str,has_table)
  168. local bits_appended = {}
  169. for chr in bits_str:gmatch(".") do
  170. local chr_bits = bit.table(string.byte(chr))
  171. for i=1,8 do
  172. bits_appended[#bits_appended+1] = chr_bits[i]
  173. end
  174. end
  175.  
  176. print("DEPEND")
  177. local bits = huffman.depend(bits_appended)
  178. print("DEPENDED")
  179. if has_table then
  180. node_tree = huffman.unserializeTree(bits)
  181. end
  182.  
  183. local txt = ""
  184. while #bits > 0 do
  185. txt = txt..decode_node(node_tree,bits)
  186. end
  187. return txt
  188. end
  189.  
  190. function encode(node_tree,txt,addTree)
  191. local chartbl = {}
  192. local nodeCharTable = makeCharBitTable(node_tree,chartbl)
  193. for i,v in pairs(nodeCharTable) do
  194. write(i)
  195. print(unpack(v))
  196. end
  197. for chr in string.gmatch(txt,".") do
  198. chartbl[#chartbl+1] = nodeCharTable[chr]
  199. end
  200. local end_table = {}
  201.  
  202. local function m_unpack(tbl)
  203. for i=1,#tbl do
  204. end_table[#end_table+1] = tbl[i]
  205. end
  206. end
  207. if addTree == true then
  208. huffman.serializeTree(node_tree,end_table)
  209. end
  210. for i=1,#chartbl do
  211. m_unpack(chartbl[i])
  212. end
  213.  
  214. local tbl = huffman.append(end_table)
  215.  
  216. local enc_str = ""
  217.  
  218. for i=1,(#tbl/8) do
  219. local byte_bits = {}
  220. for i2=1,8 do
  221. byte_bits[i2] = tbl[(8*(i-1))+i2]
  222. end
  223. enc_str = enc_str..string.char(bit.untable(byte_bits))
  224. end
  225.  
  226. print("Returned")
  227. return tbl,enc_str
  228. end
  229.  
  230.  
  231. huffman.decode = decode
  232. huffman.makeTable = make_huffman_table
  233. huffman.encode = encode
  234.  
  235. --api.makeTable("hi")
  236. local tab = {1,2}
  237. dequeue(tab)
  238. --
  239.  
  240. local m_text = read()
  241. local hutab = api.makeTable(m_text)
  242.  
  243. local tbl,str = encode(hutab,m_text)
  244. print(str)
  245. print(tbl)
  246. print(decode(hutab,str))
  247. read()
  248.  
  249.  
  250. --FUNCTIONS For bit Resizing
  251.  
  252. function huffman.append(bit_tbl)
  253. local needed = 8 - (#bit_tbl%8)
  254. if needed == 8 then
  255. needed = 0
  256. else
  257. for i=1,needed do
  258. bit_tbl[#bit_tbl+1] = 0
  259. end
  260. end
  261. local num_tbl = bit.table(needed)
  262. for i=1,#num_tbl do
  263. bit_tbl[#bit_tbl+1] = num_tbl[i]
  264. end
  265. return bit_tbl
  266. end
  267.  
  268. function huffman.depend(bit_tbl)
  269. print("Bit table"..tostring(bit_tbl))
  270. local needed_bits = {}
  271. for i=0,7 do
  272. needed_bits[8-i] = bit_tbl[#bit_tbl]
  273. bit_tbl[#bit_tbl] = nil
  274. end
  275. local needed = bit.untable(needed_bits)
  276. if needed ~= 0 then
  277. for i=1,needed do
  278. bit_tbl[#bit_tbl] = nil
  279. end
  280. end
  281. return bit_tbl
  282. end
  283. function bitPrint(bitTbl)
  284. for i=1,#bitTbl do
  285. write(bitTbl[i].."\t")
  286. end
  287. print()
  288. end
  289.  
  290. huffman.printBit = bitPrint
  291.  
  292.  
  293.  
  294. --FUNCTIONS For bit manipulation
  295. function bit_table(num)
  296. local tab = {}
  297. for i=1,8 do
  298. if (num % 2) == 1 then
  299. tab[9-i] = 1
  300. num = num - 1
  301. else
  302. tab[9-i] = 0
  303. end
  304. num = num / 2
  305. end
  306. return tab
  307. end
  308.  
  309. function bit_untable(tab)
  310. local num = 0
  311. for i=1,8 do
  312. num = num * 2
  313. num = num + tab[i]
  314. end
  315. return num
  316. end
  317.  
  318.  
  319. _G.bit.table = bit_table
  320. _G.bit.untable = bit_untable
  321.  
  322. --FUNCTIONS For tree serialization
  323. function add(buff,val)
  324. buff[#buff+1] = val
  325. end
  326.  
  327. function addLeaf(leaf,buff)
  328. local chr = leaf.char
  329. add(buff,1)
  330. for i,v in pairs(bit.table(string.byte(chr))) do
  331. add(buff,v)
  332. end
  333. end
  334.  
  335.  
  336. function addNode(node,buff)
  337. add(buff,0)
  338. if isLeaf(node.left) then
  339. addLeaf(node.left,buff)
  340. else
  341. addNode(node.left,buff)
  342. end
  343. if isLeaf(node.right) then
  344. addLeaf(node.right,buff)
  345. else
  346. addNode(node.right,buff)
  347. end
  348. end
  349.  
  350. function huffman.serializeTree(tree,buff)
  351. buff = buff or {}
  352. addNode(tree,buff)
  353. return buff
  354. end
  355.  
  356.  
  357. function unserializeLeaf(buff)
  358. local leaf = {}
  359. local chr_bits = {}
  360. for i=1,8 do
  361. chr_bits[i] = dequeue(buff)
  362. end
  363. leaf.char = string.char(bit.untable(chr_bits))
  364. return leaf
  365. end
  366.  
  367. function unserializeNode(buff)
  368. local node = {}
  369. local n_bit = dequeue(buff)
  370. if n_bit == 1 then
  371. node.left = unserializeLeaf(buff)
  372. else
  373. node.left = unserializeNode(buff)
  374. end
  375. n_bit = dequeue(buff)
  376. if n_bit == 1 then
  377. node.right = unserializeLeaf(buff)
  378. else
  379. node.right = unserializeNode(buff)
  380. end
  381. return node
  382. end
  383.  
  384. function huffman.unserializeTree(buff)
  385. dequeue(buff)
  386. return unserializeNode(buff)
  387. end
  388.  
  389. _G.huffman = huffman
Advertisement
Add Comment
Please, Sign In to add comment