| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- function read(done) {
- require("fs").readFile('./input', 'utf8', (err, data) => {
- var map = new Map(),
- line = 0;
- data.split("\n").forEach((l) => {
- if (l && l.length) {
- while (true) {
- var reg = /[\^><v]/.exec(l);
- if (!reg)
- break;
- if (reg[0] == ">" || reg[0] == "<")
- l = l.replace(reg[0], "-");
- else
- l = l.replace(reg[0], "|");
- map.carts.push(new Cart(reg.index, line, reg[0]));
- }
- map.push(l);
- ++line;
- }
- });
- done(map);
- });
- }
- function Map() {
- this.world = [];
- this.carts = [];
- }
- Map.prototype.show = function() {
- var data = [];
- this.world.forEach(row => {
- var str = "";
- row.forEach(c => str += (c == '|' || c == '-' ? ' ' : c));
- data.push(str);
- });
- this.carts.forEach(c => {
- if (!data[c.py] || c.px >= data[c.py].length) return;
- data[c.py] = data[c.py].substring(0, c.px) +'x' +data[c.py].substring(c.px +1);
- });
- data.forEach(row => {
- console.log(row);
- });
- for (var i =data[0].length; i > 0; --i)
- process.stdout.write('-');
- process.stdout.write("\n");
- }
- Map.prototype.tick = function() {
- this.carts.sort((a, b) => {
- if (a.py == b.py)
- return a.px -b.px;
- return a.py -b.py;
- });
- this.carts.some(c => {
- if (c.colided)
- return;
- c.move(this);
- var colide = this.colision(c.px, c.py);
- if (colide) {
- colide.forEach(c => c.colided = true);
- }
- });
- }
- Map.prototype.nbCartAlive = function() {
- var live = 0;
- this.carts.forEach(c => c.colided ? live : ++live);
- return live;
- }
- Map.prototype.colision = function(px, py) {
- var colided = [];
- this.carts.forEach(c => {
- if (c.px == px && c.py == py && !c.colided)
- colided.push(c);
- });
- return colided.length > 1 ? colided : null;
- }
- Map.prototype.isCross = function(px, py) {
- var c = this.world[py][px];
- return c == '/' || c == '\\' || c == '+' ? c : null;
- }
- Map.prototype.push = function(line) {
- var l = [];
- for (var i =0, len = line.length; i < len; ++i)
- l[i] = line.charAt(i);
- this.world.push(l);
- }
- function Cart(px, py, direction) {
- this.px = px;
- this.py = py;
- this.colided = false;
- this.nextTurn = 0;
- this.id = px +"x" +py;
- switch (direction) {
- case '>':
- this.direction = [1, 0];
- break;
- case '<':
- this.direction = [-1, 0];
- break;
- case '^':
- this.direction = [0, -1];
- break;
- case 'v':
- this.direction = [0, 1];
- break;
- }
- }
- Cart.prototype.move = function(map) {
- this.px += this.direction[0];
- this.py += this.direction[1];
- var cross = map.isCross(this.px, this.py);
- if (!cross)
- return;
- if (cross == '+') {
- if (this.nextTurn == 0)
- this.direction = [ this.direction[1], -this.direction[0] ];
- else if (this.nextTurn == 2)
- this.direction = [ -this.direction[1], this.direction[0] ];
- this.nextTurn = (this.nextTurn +1) %3;
- } else {
- var factor = cross == '/' ? -1 : 1;
- this.direction = [ this.direction[1] *factor, this.direction[0] *factor ];
- }
- }
- function ex1() {
- read(map => {
- while (map.nbCartAlive() == map.carts.length)
- map.tick();
- map.carts.some(c => c.colided ? (console.log(c) || true) : null);
- });
- }
- function ex2() {
- read(map => {
- while (map.nbCartAlive() > 1)
- map.tick();
- map.carts.some(c => c.colided ? null : (console.log(c) || true));
- });
- }
- ex1();
- ex2();
|