| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- const fs = require('fs');
- const readline = require('readline');
- function RockLine(from, to) {
- this.from = [];
- this.to = [];
- if (from[0] === to[0])
- {
- this.from[1] = Math.min(from[1], to[1]);
- this.to[1] = Math.max(from[1], to[1]);
- this.from[0] = this.to[0] = from[0];
- } else {
- this.from[0] = Math.min(from[0], to[0]);
- this.to[0] = Math.max(from[0], to[0]);
- this.from[1] = this.to[1] = from[1];
- }
- }
- RockLine.prototype.contains = function(pos) {
- if (this.from[0] === this.to[0])
- return pos[0] === this.from[0] && pos[1] >= this.from[1] && pos[1] <= this.to[1];
- return pos[1] === this.from[1] && pos[0] >= this.from[0] && pos[0] <= this.to[0];
- }
- function Map() {
- this.rockLines = [];
- this.sand = [];
- this.bottom = 0;
- }
- Map.prototype.canMove = function(pos) {
- return !this.sand.find(i => i[0] === pos[0] && i[1] === pos[1]) && !this.rockLines.find(i => i.contains(pos));
- }
- Map.prototype.moveSand = function() {
- const index = this.sand.length -1;
- if (this.sand[index][1] > this.bottom)
- return false;
- if (this.canMove([this.sand[index][0], this.sand[index][1]+1])) {
- this.sand[index][1]++;
- } else if (this.canMove([this.sand[index][0]-1, this.sand[index][1]+1])) {
- this.sand[index][0]--;
- this.sand[index][1]++;
- } else if (this.canMove([this.sand[index][0]+1, this.sand[index][1] +1])) {
- this.sand[index][0]++;
- this.sand[index][1]++;
- }
- else
- return false;
- return true;
- }
- Map.prototype.round = function(infiniteGround) {
- if (!this.canMove([500, 0]))
- return false;
- this.sand.push([500, 0]);
- while (this.moveSand());
- return infiniteGround ? this.sand.slice(-1)[0][1] < this.bottom : true;
- }
- async function main() {
- let map = new Map();
- for await (let line of readline.createInterface({ input: process.stdin })) {
- let lines = line.split(' -> ').map(i => i.split(',').map(i => parseInt(i)));
- for (let i =1; i < lines.length; ++i)
- map.rockLines.push(new RockLine(lines[i -1], lines[i]));
- }
- map.bottom = map.rockLines.map(i => Math.max(i.from[1], i.to[1])).reduce((i, j) => Math.max(i||0, j));
- while (map.round(true));
- console.log(map.sand.length -1);
- while (map.round(false));
- console.log(map.sand.length);
- };
- (main());
|