import std/strutils import zippy type Dictionary* = object words: string width: uint32 proc `[]`*(d: Dictionary, i: Natural): string = let start = i.uint32 * d.width d.words[start ..< start + d.width] proc len*(d: Dictionary): int = result = d.words.len div d.width.int proc addU32(s: var string, i: uint32) = for offset in 0..3: let b = cast[char](i shr (offset * 8)) s.add(b) proc getU32(s: string): uint32 = for offset in 0..3: result = result or (cast[uint32](s[offset]) shl (offset * 8)) proc pack*(d: Dictionary): string = var data: string data.addU32(d.width) data.add(d.words) data.compress(dataFormat = dfGzip) proc unpack*(p: string): Dictionary = let data = p.uncompress(dataFormat = dfGzip) result.width = data.getU32() result.words = data[4..^1] proc loadWords*(path: string): Dictionary = result.width = 25 for word in readFile(path).strip().splitLines(): if word.len > 25: continue result.words.add(word) for _ in 0 ..< (25 - word.len): result.words.add(' ') when isMainModule: import std/os echo "Loading words..." let dictionary = loadWords(paramStr(1)) echo "Packing dictionary..." let packed = dictionary.pack() writeFile(paramStr(2), packed) echo "Dictionary packed."