import CellSet; return { step: step }; function step(grid) { var zones = getZones(grid); var lines = getLines(grid.length); var rowClusters = checkRowsInclusions(grid); if(rowClusters.length > 0) { rowClusters.forEach(function(rowCluster) { rowCluster.toClear = difference( rowCluster.colors.map(function(color) {return zones[color];}), rowCluster.rows.map(function(row) {return lines.rows[row];}) ); }); } return rowClusters; } function getZones(grid) { var zones = {}; for(var row = 0; row < grid.length; row++) { for(var column = 0; column < grid[row].length; column++) { var color = grid[row][column]; if(zones[color] == undefined) { zones[color] = CellSet.make( {type: 'isochrome', row: row, column: column, grid: grid} ); } } } return zones; } function line(type, size, i) { if(type == 'row') { return CellSet.make( {type: 'rectangle', row: i, column: 0, width: size, height: 1} ); } else if(type == 'column') { return CellSet.make( {type: 'rectangle', row: 0, column: i, width: 1, height: size} ); } } function getLines(size) { var empty = Array.from({length: size}); return { rows: empty.map(function(x, i) {return line('row', size, i);}), columns: empty.map(function(x, i) {return line('column', size, i);}), }; } function getColorsByRow(grid) { var colorsByRow = []; for(var row = 0; row < grid.length; row++) { colorsByRow.push( quotient(grid[row], function(c0, c1) {return c0 == c1;}).map( function(colorClass) {return colorClass.specimen;} ) ); } return colorsByRow; } function checkRowsInclusions(grid) { var colorsByRow = getColorsByRow(grid); var colorSets = quotient(colorsByRow, sameColorsSet); return colorSets.reduce(function(commands, colorSet) { if(colorSet.occurrences.length == colorSet.specimen.length) { commands.push({ reason: 'rowsInColors', rows: colorSet.occurrences, colors: colorSet.specimen }); } return commands; }, []); } function quotient(elements, equivalence) { var classes = []; elements.forEach(function(element, i) { for(var c = 0; c < classes.length; c++) { if(equivalence(element, classes[c].specimen)) { classes[c].occurrences.push(i); return; } } classes.push({specimen: element, occurrences: [i]}); }); return classes; } function sameColorsSet(s0, s1) { if(s0.length != s1.length) { return false; } var o0 = {}; s0.forEach(function(x) {o0[x] = true;}); for(var i = 0; i < s1.length; i++) { if(!o0[s1[i]]) { return false; } } return true; } function difference(setsFrom, setsSubstracted) { return CellSet.union(setsFrom).difference(CellSet.union(setsSubstracted)); }