Advertisement
Guest User

Untitled

a guest
Dec 15th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.38 KB | None | 0 0
  1. const fs=require("fs");
  2. var errorMessage = "An error occurred while reading the file";
  3. try{
  4. var str = fs.readFileSync(process.argv[3], "utf-8");
  5. }
  6. catch(ex){
  7. console.log(errorMessage);
  8. return;
  9. }
  10. if(str !== undefined && process.argv[4] !== undefined && process.argv[5] !== undefined && process.argv.length === 6)
  11. {
  12. if(process.argv[2] === "encode")
  13. {
  14. if(str === "")
  15. {
  16. console.log("nothing to compress");
  17. return;
  18. }
  19. var result = encode(str);
  20. try
  21. {
  22. fs.writeFileSync(process.argv[5], result.text, "utf-8");
  23. fs.writeFileSync(process.argv[4], result.table, "utf-8");
  24. }
  25. catch(ex)
  26. {
  27. console.log("An error occurred while writing the file");
  28. return;
  29. }
  30. echoTheoreticalCompression(str);
  31. console.log(((str.length * 8) / result.text.length).toFixed(2));
  32. }
  33. else if(process.argv[2] === "decode")
  34. {
  35. try
  36. {
  37. var decodeTable = fs.readFileSync(process.argv[4], "utf-8");
  38. }
  39. catch(ex)
  40. {
  41. console.log(errorMessage);
  42. return;
  43. }
  44. var decodeTable = decodeTableToArray(decodeTable);
  45. var result = decode(str, decodeTable);
  46. try
  47. {
  48. fs.writeFileSync(process.argv[5], result, "utf-8");
  49. }
  50. catch(ex)
  51. {
  52. console.log("An error occurred while writing the file");
  53. return;
  54. }
  55. }
  56. else
  57. console.log("error: incorrect input");
  58. }
  59.  
  60. function echoTheoreticalCompression(str)
  61. {
  62. var entropy = getEntropy(getStat(str));
  63. if(entropy === 0)
  64. entropy = 1;
  65. console.log((8 / entropy).toFixed(2));
  66. }
  67.  
  68. function encode(str)
  69. {
  70. var treeAndFirstIndex = createTree(str);
  71. var characterCodes = [];
  72. createCharacterCodeTable(treeAndFirstIndex.tree, treeAndFirstIndex.firstIndex, "", characterCodes);
  73. var encodedText = "";
  74. for(var i = 0; i < str.length; i++)
  75. {
  76. encodedText += characterCodes[str.charAt(i)];
  77. }
  78. var table = arrayToStringWithIndexes(characterCodes);
  79. return {
  80. table: table,
  81. text: encodedText
  82. };
  83. }
  84.  
  85. function createTree(str)
  86. {
  87. var branches = [];
  88. for(var i = 0; i < str.length; i++)
  89. {
  90. if(branches[str.charAt(i)] !== undefined)
  91. {
  92. branches[str.charAt(i)].weight++;
  93. }
  94. else
  95. {
  96. branches[str.charAt(i)] = {
  97. weight: 1,
  98. left: null,
  99. right: null
  100. };
  101. }
  102. }
  103. var higherBranches = Object.assign({}, branches);
  104. var lastIndex = Object.keys(branches)[0];
  105. while(Object.keys(higherBranches).length > 1)
  106. {
  107. var firstLetter = findLetterWithMinWeight(higherBranches);
  108. var firstLetterWeight = higherBranches[firstLetter].weight;
  109. delete higherBranches[firstLetter];
  110. var secondLetter = findLetterWithMinWeight(higherBranches);
  111. var secondLetterWeight = higherBranches[secondLetter].weight;
  112. delete higherBranches[secondLetter];
  113. var newLetter = {
  114. weight: firstLetterWeight + secondLetterWeight,
  115. left: firstLetter,
  116. right: secondLetter
  117. };
  118. branches[firstLetter + secondLetter] = newLetter;
  119. higherBranches[firstLetter + secondLetter] = newLetter;
  120. if(Object.keys(higherBranches).length === 1)
  121. lastIndex = firstLetter + secondLetter;
  122. }
  123. return {
  124. tree: branches,
  125. firstIndex: lastIndex
  126. };
  127. }
  128.  
  129. function findLetterWithMinWeight(higherBranches)
  130. {
  131. var letterWithMinWeight = Object.keys(higherBranches)[0];
  132. var minWeight = higherBranches[letterWithMinWeight].weight;
  133. for(var letter in higherBranches)
  134. {
  135. if(higherBranches[letter].weight < minWeight)
  136. {
  137. minWeight = higherBranches[letter].weight;
  138. letterWithMinWeight = letter;
  139. }
  140. }
  141. return letterWithMinWeight;
  142. }
  143.  
  144. function createCharacterCodeTable(tree, firstIndex, currentPath, characterCodes)
  145. {
  146. if(Object.keys(tree).length === 1)
  147. {
  148. characterCodes[firstIndex] = 0;
  149. return;
  150. }
  151. if(tree[firstIndex].left === null)
  152. {
  153. characterCodes[firstIndex] = currentPath;
  154. return;
  155. }
  156. else
  157. {
  158. createCharacterCodeTable(tree, tree[firstIndex].left, currentPath + "0", characterCodes);
  159. createCharacterCodeTable(tree, tree[firstIndex].right, currentPath + "1", characterCodes);
  160. }
  161. }
  162.  
  163. function arrayToStringWithIndexes(arr)
  164. {
  165. var result = "";
  166. for(var index in arr)
  167. {
  168. result += index + ":" + arr[index] + " ";
  169. }
  170. return result;
  171. }
  172.  
  173. function decode(str, decodeTable)
  174. {
  175. var result = "";
  176. for(var i = 0; i < str.length; i++)
  177. {
  178. var index = str.charAt(i);
  179. if(!(index in decodeTable))
  180. {
  181. while(!(index in decodeTable) && i < str.length)
  182. {
  183. i++;
  184. index = index + str.charAt(i);
  185. }
  186. }
  187. if(decodeTable[index] === undefined)
  188. {
  189. console.log("error: impossible to decode text with this table");
  190. return result;
  191. }
  192. result += decodeTable[index];
  193. }
  194. return result;
  195. }
  196.  
  197. function decodeTableToArray(decodeTable)
  198. {
  199. var result = [];
  200. var index = 0;
  201. while(index < decodeTable.length)
  202. {
  203. var i = index + 2;
  204. var value = "";
  205. while(decodeTable.charAt(i) !== " " && i < decodeTable.length)
  206. {
  207. value += decodeTable.charAt(i);
  208. i++;
  209. }
  210. result[value] = decodeTable.charAt(index);
  211. index = i + 1;
  212. }
  213. return result;
  214. }
  215.  
  216. function getStat(str)
  217. {
  218. var stat = new Array();
  219. for(var i = 0; i < str.length; i++)
  220. {
  221. if(stat[str.charAt(i)] > 0)
  222. stat[str.charAt(i)]++;
  223. else
  224. stat[str.charAt(i)] = 1;
  225. }
  226. return stat;
  227. }
  228.  
  229. function getEntropy(stat)
  230. {
  231. var lengthOfString = 0;
  232. for(var i in stat)
  233. {
  234. lengthOfString += stat[i];
  235. }
  236. var entropy = 0;
  237. for(var i in stat)
  238. {
  239. var p = stat[i] / lengthOfString;
  240. entropy += p * Math.log(p);
  241. }
  242. entropy *= (-1) / Math.log(2);
  243. return entropy;
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement