開発環境
- macOS Sierra - Apple (OS)
- Emacs (Text Editor)
- JavaScript (プログラミング言語)
- Node.js, Safari(JavaScript エンジン)
- Learning JavaScript [邦訳](参考書籍)
Think Perl 6: How to Think Like a Computer Scientist (Laurent Rosenfeld(著)、Allen B. Downey(著)、Oreilly & Associates Inc)の Part 1(Starting with the basics)、Chapter 11(Case Study: Data Structure Selection)の Building the Huffman Code、Exercise 11-9: Huffman coding of a DNA:1、2、3、4.を JavaScript で取り組んでみる。
Exercise 11-9: Huffman coding of a DNA:1、2、3、4.
コード(Emacs)
HTML5
<pre id="output0"></pre> <input id="file0" type="file"> <button id="run0">run</button> <button id="clear0">clear</button> <script src="sample9.js"></script>
JavaScript
let btn0 = document.querySelector('#run0'), btn1 = document.querySelector('#clear0'), pre0 = document.querySelector('#output0'), input_file0 = document.querySelector('#file0'), p = (x) => pre0.textContent += x + '\n', range = (start, end, step=1) => { let result = []; for (let i = start; i < end; i += 1) { result.push(i); } return result; }, pObj = (obj) => Object.keys(obj).forEach((k) => p(`${k}: ${obj[k]}`)); let reader = new FileReader(), encodeMorseHuffmanTable = (s, huffmanTable) => s.split('') .map((letter) => huffmanTable[letter]) .join(''), decodeMorseHuffmanTable = (s, huffmanTable) => { let result = '', table = {}, morse = ''; Object.keys(huffmanTable) .forEach((letter) => table[huffmanTable[letter]] = letter); s.split('') .forEach((letter) => { morse += letter; if (table[morse]) { result += table[morse]; morse = ''; } }); return result; }; reader.onload = () => { p('3.'); let s = reader.result; frequency = {}; s.split('') .forEach((c) => { if (frequency[c]) { frequency[c] += 1; } else { frequency[c] = 1; } }); let frequencyArray = Object.keys(frequency) .map((k) => { return {letter:k, n:frequency[k]} }) .sort((x, y) => x.n - y.n), huffmanTree = {}; for (;frequencyArray.length > 2;) { let a = frequencyArray.shift(), b = frequencyArray.shift(), t = a.letter + b.letter, o = {letter:t, n:a.n + b.n} huffmanTree[a.letter] = `[${t}].`; huffmanTree[b.letter] = `[${t}]-`; frequencyArray.push(o); frequencyArray.sort((x, y) => x.n - y.n); } let a = frequencyArray.shift(), b = frequencyArray.shift(), t = a.letter + b.letter, o = {letter:t, n:a.n + b.n} huffmanTree[a.letter] = `.`; huffmanTree[b.letter] = `-`; let huffmanTable = {}; Object.keys(frequency) .filter((x) => x.length === 1) .forEach((letter) => { let result = ''; val = huffmanTree[letter]; for (;val.length > 1;) { result = val[val.length - 1]+ result; val = huffmanTree[val.substring(1, val.length - 2)]; } huffmanTable[letter] = val + result; }); let encoded = encodeMorseHuffmanTable(s, huffmanTable); p(encoded); p('4.'); let decoded = decodeMorseHuffmanTable(encoded, huffmanTable); p(decoded === s); }; input_file0.onchange = () => reader.readAsText(input_file0.files[0]); let output = () => { p('1.'); let dna = 'CCTATCCTCGACTCCAGTCCA', frequency = {}; dna.split('') .forEach((c) => { if (frequency[c]) { frequency[c] += 1; } else { frequency[c] = 1; } }); let frequencyArray = Object.keys(frequency) .map((k) => { return {letter:k, n:frequency[k]} }) .sort((x, y) => x.n - y.n), huffmanTree = {}; for (;frequencyArray.length > 2;) { let a = frequencyArray.shift(), b = frequencyArray.shift(), t = a.letter + b.letter, o = {letter:t, n:a.n + b.n} huffmanTree[a.letter] = `[${t}].`; huffmanTree[b.letter] = `[${t}]-`; frequencyArray.push(o); frequencyArray.sort((x, y) => x.n - y.n); } let a = frequencyArray.shift(), b = frequencyArray.shift(), t = a.letter + b.letter, o = {letter:t, n:a.n + b.n} huffmanTree[a.letter] = `.`; huffmanTree[b.letter] = `-`; pObj(huffmanTree); let huffmanCode = {}; Object.keys(frequency) .filter((x) => x.length === 1) .forEach((letter) => { let result = ''; val = huffmanTree[letter]; for (;val.length > 1;) { result = val[val.length - 1]+ result; val = huffmanTree[val.substring(1, val.length - 2)]; } huffmanCode[letter] = val + result; }); pObj(huffmanCode); p('2.'); let s = 'think perl 6, think python, think javascript'; frequency = {}; s.split('') .forEach((c) => { if (frequency[c]) { frequency[c] += 1; } else { frequency[c] = 1; } }); frequencyArray = Object.keys(frequency) .map((k) => { return {letter:k, n:frequency[k]} }) .sort((x, y) => x.n - y.n), huffmanTree = {}; for (;frequencyArray.length > 2;) { let a = frequencyArray.shift(), b = frequencyArray.shift(), t = a.letter + b.letter, o = {letter:t, n:a.n + b.n} huffmanTree[a.letter] = `[${t}].`; huffmanTree[b.letter] = `[${t}]-`; frequencyArray.push(o); frequencyArray.sort((x, y) => x.n - y.n); } a = frequencyArray.shift(), b = frequencyArray.shift(), t = a.letter + b.letter, o = {letter:t, n:a.n + b.n} huffmanTree[a.letter] = `.`; huffmanTree[b.letter] = `-`; pObj(huffmanTree); huffmanCode = {}; Object.keys(frequency) .filter((x) => x.length === 1) .forEach((letter) => { let result = ''; val = huffmanTree[letter]; for (;val.length > 1;) { result = val[val.length - 1]+ result; val = huffmanTree[val.substring(1, val.length - 2)]; } huffmanCode[letter] = val + result; }); pObj(huffmanCode); }; let clear = () => pre0.textContent = ''; btn0.onclick = output; btn1.onclick = clear; output();
0 コメント:
コメントを投稿