Skip to content

Instantly share code, notes, and snippets.

@skiano
Last active December 17, 2017 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skiano/bfdf6c6cbd0a7fc70fd311fd7ef749cd to your computer and use it in GitHub Desktop.
Save skiano/bfdf6c6cbd0a7fc70fd311fd7ef749cd to your computer and use it in GitHub Desktop.
2D letter grid compression
// 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