return { compress: compress, naive: naive } function compress(grid) { var state = { data: '', stack: 0, size: 0 }; var color; var count; for(var i = 0; i < grid.length; i++) { for(var j = 0; j < grid.length; j++) { if(color == undefined) { color = grid[i][j]; } else if(grid[i][j] != color) { } else if(count > 6) { } else { count++; } } } return atob(compressed); } function appendLength(state, n) { append(state, 1); for(var i = 0; i < 3; i++) { append(state, n % 2); n >>= 1; } } function appendColor(state, c) { append(state, 0); for(var i = 0; i < 3; i++) { append(state, c % 2); c >>= 1; } } function appendColorNaive(state, c) { for(var i = 0; i < 3; i++) { append(state, c % 2); c >>= 1; } } function append(state, one) { if(state.size > 7) { flush(state); } state.stack = 2*state.stack + (one ? 1 : 0); state.size++; } function flush(state) { state.data = state.data + String.fromCharCode(state.stack); state.stack = 0; state.size = 0; } function naive(grid) { var state = { data: '', stack: 0, size: 0 }; for(var i = 0; i < grid.length; i++) { for(var j = 0; j < grid.length; j++) { appendColorNaive(state, grid[i][j]); } } flush(state); return btoa(state.data); }