main.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. function read(cb) {
  2. require("fs").readFile('./input', 'utf8', (err, data) => {
  3. data.split("\n").forEach((l)=> {
  4. var data = l.split(/\D+/);
  5. if (data.length == 2)
  6. cb(new Flag(parseInt(data[0]), parseInt(data[1])));
  7. });
  8. cb(null);
  9. });
  10. }
  11. function Flag(px, py) {
  12. this.px = px;
  13. this.py = py;
  14. this.cover = [];
  15. }
  16. Flag.prototype.translate = function(vx, vy) {
  17. this.px += vx;
  18. this.py += vy;
  19. }
  20. function Map() {
  21. this.flags = [];
  22. this.infinite = [];
  23. this.safe = [];
  24. this.min = undefined;
  25. this.max = undefined;
  26. }
  27. Map.prototype.closestFlag = function(px, py) {
  28. var closest = null,
  29. sum =0;
  30. this.flags.forEach(f => {
  31. var dist = Math.abs(px -f.px) +Math.abs(py -f.py);
  32. if (closest == null || dist < closest.dist)
  33. closest = { dist: dist, flag: [ f ] };
  34. else if (closest.dist == dist)
  35. closest.flag.push(f);
  36. sum += dist;
  37. });
  38. return {
  39. flags: closest.flag,
  40. sum: sum
  41. };
  42. }
  43. Map.prototype.fillMap = function() {
  44. var bound = this.max +this.min;
  45. for (var i =0; i < bound; ++i)
  46. for (var j =0; j < bound; ++j) {
  47. var closestFlag = this.closestFlag(i, j);
  48. closestFlag.flags.forEach(f => {
  49. if ((i == 0 || j == 0 || i == bound -1 || j == bound -1) && this.infinite.indexOf(f) == -1)
  50. this.infinite.push(f);
  51. });
  52. if (closestFlag.flags.length == 1)
  53. closestFlag.flags[0].cover.push({ x: i, y: j });
  54. if (closestFlag.sum < 10000)
  55. this.safe.push({ x: i, y: j });
  56. }
  57. }
  58. Map.prototype.addFlag = function(f) {
  59. this.min = this.min === undefined ? f.px : Math.min(f.px, this.min);
  60. this.min = this.min === undefined ? f.py : Math.min(f.py, this.min);
  61. this.max = this.max === undefined ? f.px : Math.max(f.px, this.max);
  62. this.max = this.max === undefined ? f.py : Math.max(f.py, this.max);
  63. this.flags.push(f);
  64. }
  65. Map.prototype.resize = function() {
  66. var vx = -this.min;
  67. this.flags.forEach((f) => f.translate(vx, vx));
  68. this.min += vx;
  69. this.max += vx;
  70. }
  71. function ex1() {
  72. var m = new Map();
  73. read((flag) => {
  74. if (flag) {
  75. m.addFlag(flag);
  76. } else {
  77. m.resize();
  78. m.fillMap();
  79. var maxFlag = null;
  80. m.flags.forEach((f) => {
  81. if (m.infinite.indexOf(f) === -1) {
  82. maxFlag = maxFlag && maxFlag.cover.length >= f.cover.length ? maxFlag : f;
  83. }
  84. });
  85. console.log("largest area that isn't infinite: " +maxFlag.cover.length);
  86. }
  87. });
  88. }
  89. function ex2() {
  90. var m = new Map();
  91. read((flag) => {
  92. if (flag) {
  93. m.addFlag(flag);
  94. } else {
  95. m.fillMap();
  96. console.log("found " +m.safe.length +" safe zones");
  97. }
  98. });
  99. }
  100. ex1();
  101. ex2();