Skip to content

Instantly share code, notes, and snippets.

@Mellen
Last active December 11, 2019 17:29
Show Gist options
  • Save Mellen/f4bfb2fe01885a41ee6209a879d19c32 to your computer and use it in GitHub Desktop.
Save Mellen/f4bfb2fe01885a41ee6209a879d19c32 to your computer and use it in GitHub Desktop.
AoC 2019 day 10
function Asteroid(position)
{
this.position = position;
this.slopes = new Map();
}
Asteroid.prototype.slopeAndDistance = function(other)
{
let xdiff = (other.position.x - this.position.x);
let ydiff = (other.position.y - this.position.y);
let slope = xdiff / ydiff;
this.slopes.set(other, {slope:slope, sign:Math.sign(ydiff)});
};
Asteroid.prototype.seeCount = function()
{
let count = 0;
let slopeSeen = [];
for(let [asteroid, slope] of this.slopes)
{
if(typeof(slopeSeen.find(s => s.slope == slope.slope && s.sign == slope.sign)) === 'undefined')
{
count++;
slopeSeen.push(slope);
}
}
return count;
};
Asteroid.prototype.varporisationOrder = function()
{
let distances = new Map();
let angles = new Map();
let sortedroids = [];
let uniqueangles = new Set();
console.log(`starting x: ${this.position.x} y: ${this.position.y}`);
for(let other of this.slopes.keys())
{
let xdiff = other.position.x - this.position.x;
let ydiff = this.position.y - other.position.y;
let dist = Math.sqrt(xdiff**2 + ydiff**2);
distances.set(other, dist);
let angle = Math.acos(ydiff/dist);
angles.set(other, angle);
uniqueangles.add(angle);
sortedroids.push([other, angles.get(other), dist]);
}
sortedroids.sort((A, B) =>
{
if(angles.get(A[0]) < angles.get(B[0]))
{
return -1;
}
if(angles.get(A[0]) > angles.get(B[0]))
{
return 1;
}
if(angles.get(A[0]) == angles.get(B[0]))
{
if(distances.get(A[0]) < distances.get(B[0]))
{
return -1;
}
if(distances.get(A[0]) > distances.get(B[0]))
{
return 1;
}
}
return 0;
});
let resorted = [];
let usedangles = new Set();
while(sortedroids.length > 0)
{
let delindex = [];
for(let a of sortedroids)
{
let [asteroid, angle, distance] = a;
if(uniqueangles.has(angle))
{
resorted.push(asteroid);
delindex.push(sortedroids.indexOf(a));
usedangles.add(angle);
uniqueangles.delete(angle);
}
if(uniqueangles.size == 0)
{
uniqueangles = new Set(usedangles);
}
}
for(let index of delindex)
{
sortedroids.splice(index, 1);
}
}
for(let ast of resorted)
{
console.log(`${ast.position.x}, ${ast.position.y}, angle: ${angles.get(ast)}, distance: ${distances.get(ast)}`);
}
return resorted;
}
function Field(input)
{
this.asteroids = [];
let rows = input.split('\n');
for(let ri = 0; ri < rows.length; ri++)
{
let row = rows[ri];
for(let ci = 0; ci < row.length; ci++)
{
let c = row[ci];
if(c === '#')
{
let asteroid = new Asteroid({x:ci, y:ri})
this.asteroids.push(asteroid);
}
}
}
}
Field.prototype.bestAsteroid = function()
{
for(let asteroid of this.asteroids)
{
for(let otherA of this.asteroids)
{
if(asteroid === otherA)
{
continue;
}
asteroid.slopeAndDistance(otherA);
}
}
let bestcount = 0;
let besteroid = null;
for(let asteroid of this.asteroids)
{
let seecount = asteroid.seeCount();
if(seecount > bestcount)
{
bestcount = seecount;
besteroid = asteroid;
}
}
return [besteroid, bestcount];
}
Field.prototype.destroy200 = function()
{
let laserPos = this.bestAsteroid()[0];
let order = laserPos.varporisationOrder();
return order[200].position;
}
function testPart1()
{
let input =`.#..##.###...#######
##.############..##.
.#.######.########.#
.###.#######.####.#.
#####.##.#.##.###.##
..#####..#.#########
####################
#.####....###.#.#.##
##.#################
#####.##.###..####..
..######..##.#######
####.##.####...##..#
.#####..#.######.###
##...#.##########...
#.##########.#######
.####.#.###.###.#.##
....##.##.###..#####
.#.#.###########.###
#.#.#.#####.####.###
###.##.####.##.#..##`;
let field = new Field(input);
let result = field.bestAsteroid();
console.log('expected x: 11, expected y: 13, expected count: 210');
console.log(`actual x: ${result[0].position.x}, actual y: ${result[0].position.y}, actual count: ${result[1]}`);
console.log('passed;', result[0].position.x==11 && result[0].position.y==13 && result[1] == 210);
}
function part1()
{
let input = document.querySelector('pre').innerHTML;
let field = new Field(input);
return field.bestAsteroid();
}
function testPart2()
{
let input =`.#..##.###...#######
##.############..##.
.#.######.########.#
.###.#######.####.#.
#####.##.#.##.###.##
..#####..#.#########
####################
#.####....###.#.#.##
##.#################
#####.##.###..####..
..######..##.#######
####.##.####...##..#
.#####..#.######.###
##...#.##########...
#.##########.#######
.####.#.###.###.#.##
....##.##.###..#####
.#.#.###########.###
#.#.#.#####.####.###
###.##.####.##.#..##`;
let field = new Field(input);
let result = field.destroy200();
console.log('expected x: 8, expected y: 2');
console.log(`actual x: ${result.x}, actual y: ${result.y}`);
console.log('passed;', result.x==8 && result.y==2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment