Last active
January 25, 2018 17:02
-
-
Save skiano/dea11ff4b5dc6da06e3f36be61472b53 to your computer and use it in GitHub Desktop.
anagram compressor: https://repl.it/@skiano/SympatheticWarpedRaptors-2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A compressor for anagram puzzle data | |
// because we know all the solutions to anagram puzzles | |
// have a very small number of characters, we can compress | |
// the data more strategically | |
// | |
// given a list of letters, this creates an encode and decode function | |
// | |
// for example | |
// given the letters: | |
// 'NCEHITK' | |
// and the list of words: | |
// ['KITCHEN', 'KITCHENETTE', 'THICKEN', 'CENT', 'CHIN', 'CINE', 'HENT', 'HINT', 'INCH', 'KEEN', 'KENT', 'KINE', 'KNEE', 'KNIT'] | |
// the compressed data looks like this: | |
// ɽͪN,ɽͪɕȜ,Ș͚N,ͮT,ͨN,͞E,˾T,ˮT,ʫH,ʒN,ʎT,ɾE,ɲE,ɰT | |
const createAnagramCompressor = (letters, a, b, c, v, k2, k3) => { | |
const sorted = letters.split('').sort() | |
const len = sorted.length | |
const map = {} | |
const reverseMap = {} | |
let i = 500 // just a charcode well out of range | |
a = len | |
while(a--) { | |
b = len | |
while(b--) { | |
k2 = sorted[a] + sorted[b] | |
v = String.fromCharCode(i) | |
map[k2] = v | |
reverseMap[v] = k2 | |
c = len | |
while(i++, c--) { | |
k3 = k2 + sorted[c] | |
v = String.fromCharCode(i) | |
map[k3] = v | |
reverseMap[v] = k3 | |
} | |
} | |
} | |
const encodeWord = (word, final, i) => { | |
final = '' | |
i = 0 | |
while (i < word.length) { | |
const chunk = word.substr(i, 3) | |
final += map[chunk] || chunk | |
i += 3 | |
} | |
return final | |
} | |
const decodeWord = (word, i) => { | |
final = '' | |
i = 0 | |
while(i < word.length) { | |
const k = word.charAt(i) | |
final += reverseMap[k] || k | |
i++ | |
} | |
return final | |
} | |
return { | |
encode: (words) => words.map(encodeWord).join(), | |
decode: (str) => str.split(',').map(decodeWord), | |
} | |
} | |
const letters = 'NCEHITK' | |
const solutions = ['KITCHEN', 'KITCHENETTE', 'THICKEN', 'CENT', 'CHIN', 'CINE', 'HENT', 'HINT', 'INCH', 'KEEN', 'KENT', 'KINE', 'KNEE', 'KNIT', 'NECK', 'NICE', 'NICK', 'NINE', 'NITE', 'TEEN', 'TENT', 'TEIN', 'THEN', 'THIN', 'TINE', 'TINT', 'CHICKEN', 'CHINK', 'CINCH', 'ENTENTE', 'ENTICE', 'ETHNIC', 'HEINIE', 'HENCE', 'INCITE', 'INNIE', 'INTENT', 'KINETIC', 'KITTEN','NECKTIE', 'NICHE', 'NIECE', 'NINETEEN', 'NINETEENTH', 'NINETIETH', 'NINTH', 'TENET', 'TENTH', 'THENCE', 'THINE', 'THINK', 'TINCT'] | |
const { encode, decode } = createAnagramCompressor(letters) | |
const encoded = encode(solutions) | |
const decoded = decode(encoded) | |
console.log(` | |
compressed anagram list: | |
${encoded} | |
--- | |
base64 ${btoa(JSON.stringify(solutions)).length} | |
JSON.stringify ${JSON.stringify(solutions).length} | |
custom ${encoded.length} | |
matches ${JSON.stringify(decoded) === JSON.stringify(solutions)} | |
`) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment