Skip to content

Instantly share code, notes, and snippets.

@skiano
Last active January 25, 2018 17:02
Show Gist options
  • Save skiano/dea11ff4b5dc6da06e3f36be61472b53 to your computer and use it in GitHub Desktop.
Save skiano/dea11ff4b5dc6da06e3f36be61472b53 to your computer and use it in GitHub Desktop.
// 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