DevFest Quizパッチワーク問題の回答 CommonJS編
DevFest Quizの回答期限が過ぎたのでエントリにします。パッチワーク問題はJavaScript(CommonJS, Narwhal on Rhino)で解きました。
"A" または "B" という文字のみを含む 600 桁、600 行のテキストがあります。これを 600 x 600 の升目状に並べ、上下左右に同じ文字がある部分をつながっているとみなします。
まず、最も多くの文字がつながっている領域をすべて "_" で塗りつぶしてください。 最も多くの文字がつながっている領域が複数存在するならば、それらすべての領域を "_"で塗りつぶすこととします。
そして、各行ごとに "_" が何個含まれているかを数え、それらの数値を改行区切りのテキスト(600 行)として答えてください。
以下の例1を見てください。この入力には単一の文字4つでつながった領域が3箇所あります。これらすべてが「最も多くの文字がつながっている領域」なので、全て"_"で塗りつぶし、その数を数えています。
(以下略)
アルゴリズムの枝刈りが甘いせいか10秒もかかります。data.txtから読み込んでresult.txtに出力してます。
var fs = require('file'); var io = require('io'); var dataSize = {x:600,y:600}; var maxScore = 0; var maxScoreCells = []; var dataMap = createMap(); var scoreMap = createScoreMap(); dataMap.forEach(function(line, y) { print('check linenum:' + y); line.forEach(function(c, x) { var score = check(x, y, c); scoreMap[y][x] = score; if (score > maxScore) { maxScore = score; maxScoreCells = [{x:x, y:y}]; } else if (score === maxScore) { maxScoreCells.push({x:x, y:y}); } }); }); maxScoreCells.forEach(function(p) { fill(p.x, p.y, dataMap[p.y][p.x]); }); output(); // ---- end ----- function createMap() { var lines = new io.StringIO(fs.read('data.txt')); var result = []; lines.forEach(function(line) { result.push(line.split('')); }); return result; } function createScoreMap() { var result = []; for(var i=0; i<dataSize.y; i++) { var line = []; for(var j=0; j<dataSize.x; j++) { line.push(-1); } result.push(line); } return result; } function check(x, y, c) { if (x < 0 || 600 <= x || y < 0 || 600 <= y){ return 0; } if (scoreMap[y][x] !== -1) { return 0; } var score = 0; if (c === dataMap[y][x]) { score++; } else { return 0; } scoreMap[y][x] = 0; score+=check(x+1, y, c); score+=check(x, y+1, c); score+=check(x-1, y, c); score+=check(x, y-1, c); return score; } function fill(x, y, c) { if (x < 0 || 600 <= x || y < 0 || 600 <= y){ return 0; } if (dataMap[y][x] !== c) { return; } dataMap[y][x] = '_'; fill(x+1, y, c); fill(x, y+1, c); fill(x-1, y, c); fill(x, y-1, c); } function output() { var results = []; dataMap.forEach(function(line) { var cnt = 0; line.forEach(function(c){if(c === '_'){cnt++;}}); results.push(cnt); }); fs.write('result.txt', results.join('\n')); }