main.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. function read(done) {
  2. require("fs").readFile('./input', 'utf8', (err, data) => {
  3. var coords = [];
  4. data.split("\n").some((l) => {
  5. var r = / *(-?\d+), *(-?\d+).*< *(-?\d+), *(-?\d+)/.exec(l);
  6. if (r)
  7. coords.push(new PointAndVector(parseInt(r[1]), parseInt(r[2]), parseInt(r[3]), parseInt(r[4])));
  8. });
  9. done(new Map(coords));
  10. });
  11. }
  12. function PointAndVector(px, py, vx, vy) {
  13. this.px = px;
  14. this.py = py;
  15. this.vx = vx;
  16. this.vy = vy;
  17. }
  18. PointAndVector.prototype.next = function(val) {
  19. this.px += val*this.vx;
  20. this.py += val*this.vy;
  21. }
  22. function Map(points) {
  23. this.points = points;
  24. this.init();
  25. this.time = 0;
  26. }
  27. Map.prototype.init = function() {
  28. this.minX = this.points[0].px;
  29. this.maxX = this.points[0].px;
  30. this.minY = this.points[0].py;
  31. this.maxY = this.points[0].py;
  32. for (var i =1, nbPts = this.points.length; i < nbPts; ++i) {
  33. this.minX = Math.min(this.minX, this.points[i].px);
  34. this.maxX = Math.max(this.maxX, this.points[i].px);
  35. this.minY = Math.min(this.minY, this.points[i].py);
  36. this.maxY = Math.max(this.maxY, this.points[i].py);
  37. }
  38. }
  39. Map.prototype.next = function(val) {
  40. this.points.forEach(i => i.next(val));
  41. this.init();
  42. this.time += val;
  43. return this;
  44. }
  45. Map.prototype.print = function() {
  46. for (var i=this.minY; i <= this.maxY; ++i) {
  47. for (var j =this.minX; j <= this.maxX; ++j)
  48. process.stdout.write(this.hasPoint(j, i) ? 'X' : '.');
  49. process.stdout.write("\n");
  50. }
  51. }
  52. Map.prototype.hasPoint = function(px, py) {
  53. if (px < this.minX || py < this.minY || px > this.maxX || py > this.maxY)
  54. return false;
  55. return this.points.some((pt) => pt.px == px && pt.py == py);
  56. }
  57. Map.prototype.isIsolated = function(px, py) {
  58. var hasPoint = false,
  59. count =0;
  60. this.points.some((pt) => {
  61. if (pt.px >= px -1 && pt.px <= px +1 && pt.py >= py -1 && pt.py <= py +1) {
  62. if (pt.px == px && pt.py == py)
  63. hasPoint = true;
  64. else
  65. count++;
  66. }
  67. return hasPoint && count > 0;
  68. });
  69. return hasPoint && count == 0;
  70. }
  71. Map.prototype.countIsolated = function() {
  72. var isolated = 0;
  73. for (var i=this.minY; i <= this.maxY; ++i)
  74. for (var j =this.minX; j <= this.maxX; ++j)
  75. if (this.isIsolated(j, i))
  76. isolated++;
  77. return isolated;
  78. }
  79. Map.prototype.mapSize = function() {
  80. return (this.maxX -this.minX) * (this.maxY -this.minY);
  81. }
  82. function ex1() {
  83. read(map => {
  84. var prevIsolated = 0,
  85. currentIsolated = map.mapSize();
  86. do {
  87. map.next(1);
  88. prevIsolated = currentIsolated;
  89. currentIsolated = map.mapSize();
  90. } while (prevIsolated -currentIsolated > 0);
  91. console.log("start counting isolated");
  92. map.next(-3);
  93. currentIsolated = map.countIsolated();
  94. do {
  95. map.next(1);
  96. prevIsolated = currentIsolated;
  97. currentIsolated = map.countIsolated();
  98. } while (prevIsolated -currentIsolated > 0);
  99. map.next(-1).print();
  100. console.log(map.time);
  101. });
  102. }
  103. ex1();
  104. //ex2();