Last active
December 17, 2017 20:37
-
-
Save skiano/bfdf6c6cbd0a7fc70fd311fd7ef749cd to your computer and use it in GitHub Desktop.
2D letter grid compression
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
// TAKES A 2D ARRAY OF LETTERS AND COMPRESSES TO STRING | |
// for example ... | |
// compressGrid([ | |
// ['A','A','A','B','B'], | |
// ['B','A','B','B','B'], | |
// ['B','A','B','B','B'], | |
// ['B','A','B','B','B'], | |
// ]) | |
// becomes... | |
// 'A2B1,BAB2,2' | |
// | |
// and... | |
// expandGrid('A2B1,BAB2,2') | |
// becomes... | |
// [ | |
// ['A','A','A','B','B'], | |
// ['B','A','B','B','B'], | |
// ['B','A','B','B','B'], | |
// ['B','A','B','B','B'], | |
// ] | |
const ROW_DELIMETER = ',' | |
const compressGrid = (grid) => { | |
let str = '' | |
let lastRow | |
let rowRepeats = 0 | |
for (let r = 0; r < grid.length; r++) { | |
let lastV | |
let vRepeats = 0 | |
let rowStr = '' | |
for (let c = 0; c < grid[r].length; c++) { | |
const v = grid[r][c] | |
// if column repeats | |
if (v === lastV) { | |
vRepeats += 1 | |
} else { | |
if (vRepeats) rowStr += vRepeats | |
rowStr += v | |
vRepeats = 0 | |
} | |
lastV = v | |
} | |
// repeats at the end | |
if (vRepeats) rowStr += vRepeats | |
// if row repeate | |
if (rowStr === lastRow) { | |
rowRepeats += 1 | |
} else { | |
if (rowRepeats) { | |
str += ROW_DELIMETER | |
str += rowRepeats | |
if (r < grid.length - 1) str += ROW_DELIMETER | |
} else if (str) { | |
str += ROW_DELIMETER | |
} | |
str += rowStr | |
rowRepeats = 0 | |
} | |
lastRow = rowStr | |
} | |
// repeats at the end | |
if (rowRepeats) { | |
str += ROW_DELIMETER | |
str += rowRepeats | |
} | |
return str | |
} | |
const expandGrid = (compressed) => { | |
const grid = [] | |
const tokens = /(,|\d+|\D)/g | |
let match = tokens.exec(compressed) | |
let lastV = null | |
let r = [] | |
let v | |
while (match) { | |
v = parseInt(match[1]) || match[1] | |
if (v === ROW_DELIMETER) { | |
lastV = null | |
if (r.length) grid.push(r) | |
r = [] | |
} else if (typeof v === 'number') { | |
if (lastV) { | |
for (let i = 0; i < v; i++) { r.push(lastV) } | |
} else { | |
const prev = grid[grid.length - 1] | |
for (let i = 0; i < v; i++) { grid.push(prev.slice()) } | |
} | |
} else { | |
r.push(v) | |
lastV = v | |
} | |
match = tokens.exec(compressed) | |
} | |
if (r.length) grid.push(r) | |
return grid | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment