function read(cb) { require("fs").readFile('./input', 'utf8', (err, data) => { data.split("\n").forEach((l)=> { var data = l.split(/\D+/); if (data.length == 2) cb(new Flag(parseInt(data[0]), parseInt(data[1]))); }); cb(null); }); } function Flag(px, py) { this.px = px; this.py = py; this.cover = []; } Flag.prototype.translate = function(vx, vy) { this.px += vx; this.py += vy; } function Map() { this.flags = []; this.infinite = []; this.safe = []; this.min = undefined; this.max = undefined; } Map.prototype.closestFlag = function(px, py) { var closest = null, sum =0; this.flags.forEach(f => { var dist = Math.abs(px -f.px) +Math.abs(py -f.py); if (closest == null || dist < closest.dist) closest = { dist: dist, flag: [ f ] }; else if (closest.dist == dist) closest.flag.push(f); sum += dist; }); return { flags: closest.flag, sum: sum }; } Map.prototype.fillMap = function() { var bound = this.max +this.min; for (var i =0; i < bound; ++i) for (var j =0; j < bound; ++j) { var closestFlag = this.closestFlag(i, j); closestFlag.flags.forEach(f => { if ((i == 0 || j == 0 || i == bound -1 || j == bound -1) && this.infinite.indexOf(f) == -1) this.infinite.push(f); }); if (closestFlag.flags.length == 1) closestFlag.flags[0].cover.push({ x: i, y: j }); if (closestFlag.sum < 10000) this.safe.push({ x: i, y: j }); } } Map.prototype.addFlag = function(f) { this.min = this.min === undefined ? f.px : Math.min(f.px, this.min); this.min = this.min === undefined ? f.py : Math.min(f.py, this.min); this.max = this.max === undefined ? f.px : Math.max(f.px, this.max); this.max = this.max === undefined ? f.py : Math.max(f.py, this.max); this.flags.push(f); } Map.prototype.resize = function() { var vx = -this.min; this.flags.forEach((f) => f.translate(vx, vx)); this.min += vx; this.max += vx; } function ex1() { var m = new Map(); read((flag) => { if (flag) { m.addFlag(flag); } else { m.resize(); m.fillMap(); var maxFlag = null; m.flags.forEach((f) => { if (m.infinite.indexOf(f) === -1) { maxFlag = maxFlag && maxFlag.cover.length >= f.cover.length ? maxFlag : f; } }); console.log("largest area that isn't infinite: " +maxFlag.cover.length); } }); } function ex2() { var m = new Map(); read((flag) => { if (flag) { m.addFlag(flag); } else { m.fillMap(); console.log("found " +m.safe.length +" safe zones"); } }); } ex1(); ex2();