main.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. const fs = require('fs');
  2. const readline = require('readline');
  3. function RockLine(from, to) {
  4. this.from = [];
  5. this.to = [];
  6. if (from[0] === to[0])
  7. {
  8. this.from[1] = Math.min(from[1], to[1]);
  9. this.to[1] = Math.max(from[1], to[1]);
  10. this.from[0] = this.to[0] = from[0];
  11. } else {
  12. this.from[0] = Math.min(from[0], to[0]);
  13. this.to[0] = Math.max(from[0], to[0]);
  14. this.from[1] = this.to[1] = from[1];
  15. }
  16. }
  17. RockLine.prototype.contains = function(pos) {
  18. if (this.from[0] === this.to[0])
  19. return pos[0] === this.from[0] && pos[1] >= this.from[1] && pos[1] <= this.to[1];
  20. return pos[1] === this.from[1] && pos[0] >= this.from[0] && pos[0] <= this.to[0];
  21. }
  22. function Map() {
  23. this.rockLines = [];
  24. this.sand = [];
  25. this.bottom = 0;
  26. }
  27. Map.prototype.canMove = function(pos) {
  28. return !this.sand.find(i => i[0] === pos[0] && i[1] === pos[1]) && !this.rockLines.find(i => i.contains(pos));
  29. }
  30. Map.prototype.moveSand = function() {
  31. const index = this.sand.length -1;
  32. if (this.sand[index][1] > this.bottom)
  33. return false;
  34. if (this.canMove([this.sand[index][0], this.sand[index][1]+1])) {
  35. this.sand[index][1]++;
  36. } else if (this.canMove([this.sand[index][0]-1, this.sand[index][1]+1])) {
  37. this.sand[index][0]--;
  38. this.sand[index][1]++;
  39. } else if (this.canMove([this.sand[index][0]+1, this.sand[index][1] +1])) {
  40. this.sand[index][0]++;
  41. this.sand[index][1]++;
  42. }
  43. else
  44. return false;
  45. return true;
  46. }
  47. Map.prototype.round = function(infiniteGround) {
  48. if (!this.canMove([500, 0]))
  49. return false;
  50. this.sand.push([500, 0]);
  51. while (this.moveSand());
  52. return infiniteGround ? this.sand.slice(-1)[0][1] < this.bottom : true;
  53. }
  54. async function main() {
  55. let map = new Map();
  56. for await (let line of readline.createInterface({ input: process.stdin })) {
  57. let lines = line.split(' -> ').map(i => i.split(',').map(i => parseInt(i)));
  58. for (let i =1; i < lines.length; ++i)
  59. map.rockLines.push(new RockLine(lines[i -1], lines[i]));
  60. }
  61. map.bottom = map.rockLines.map(i => Math.max(i.from[1], i.to[1])).reduce((i, j) => Math.max(i||0, j));
  62. while (map.round(true));
  63. console.log(map.sand.length -1);
  64. while (map.round(false));
  65. console.log(map.sand.length);
  66. };
  67. (main());