Public
Edited
Dec 15, 2022
Insert cell
md`# Advent of Code 2019 Day 10`
Insert cell
// https://stackoverflow.com/a/15994225
angle = ( [ x1, y1 ], [ x2, y2 ] ) => {
const deltaX = x2 - x1;
const deltaY = y2 - y1;
return Math.atan2(deltaY, deltaX) * (180 / Math.PI); // In radians
}
Insert cell
angle( [ 3, 4], [ 4, 0 ] )
Insert cell
angle( [ 3, 4], [ 1, 0 ] )
Insert cell
angle( [ 3, 4], [ 2, 2 ] )
Insert cell
parse = ( spaceMap ) => {
const grid = spaceMap.split( '\n' ).map( l => l.split( '' ) );
const asteroids = [];
for ( let y = 0; y < grid.length; y++ ) {
for ( let x = 0; x < grid[y].length; x++ ) {
if ( grid[y][x] == '#' ) asteroids.push( [x, y] );
}
}
return asteroids;
}
Insert cell
test0 = parse( `.#..#
.....
#####
....#
...##`);
Insert cell
visibleAsteroids = ( [ x, y ], idx, list ) => {
return list.reduce(
( hits, [ testX, testY ] ) => {
if ( x == testX && y == testY ) return hits;
const testAngle = angle( [x, y], [testX, testY] );
hits.seen.add( testAngle );
return hits;
},
{ x, y, seen: new Set() }
);
}
Insert cell
test0.map( visibleAsteroids )
.reduce( ( a, b ) => ( a.seen.size > b.seen.size ) ? a : b )
Insert cell
findBestVisiblity = ( spaceMap ) => parse( spaceMap )
.map( visibleAsteroids )
.reduce( ( a, b ) => ( a.seen.size > b.seen.size ) ? a : b );
Insert cell
findBestVisiblity( `......#.#.
#..#.#....
..#######.
.#.#.###..
.#..#.....
..#....#.#
#..#....#.
.##.#..###
##...#..#.
.#....####` )
Insert cell
findBestVisiblity( `#.#...#.#.
.###....#.
.#....#...
##.#.#.#.#
....#.#.#.
.##..###.#
..#...##..
..##....##
......#...
.####.###.` )
Insert cell
findBestVisiblity( `.#..#..###
####.###.#
....###.#.
..###.##.#
##.##.#.#.
....###..#
..#.#..#.#
#..#.#.###
.##...##.#
.....#.#..
`)
Insert cell
Insert cell
part1 = findBestVisiblity( input )
Insert cell
md`# Part 1: ${part1.seen.size}`
Insert cell
test2 = parse( `.#....#####...#..
##...##.#####..##
##...#...#.#####.
..#.....#...###..
..#.#.....#....##` );
Insert cell
distance = ( [x1, y1], [x2, y2] ) => Math.sqrt( Math.pow( Math.abs( x2 - x1 ), 2 ) + Math.pow( Math.abs( y2 - y1 ), 2 ) );
Insert cell
distance( [0,0], [3, 4] )
Insert cell
mapAsteroids = ( [baseX, baseY], asteroids ) => asteroids.map( ( [x, y] ) => ( {
x,
y,
angleFromTop: ( angle( [baseX, baseY], [x, y] ) + 450 ) % 360,
distance: distance( [baseX, baseY], [x, y] )
} ) )
Insert cell
mapAsteroids( [8, 3 ], test2 )
Insert cell
angle( [ 0, 0], [5, 0 ] );
Insert cell
sortByNumber = ( prop ) => ( a, b ) => a[prop] - b[prop];
Insert cell
sortByAngle = ( a, b ) => a.angleFromTop - b.angleFromTop;
Insert cell
test2Mapped = mapAsteroids( [8, 3 ], test2 ).sort( sortByNumber('distance') ).sort( sortByNumber('angleFromTop') )
Insert cell
destroyOrder = ( mappedAsteroids ) => {
const destroyed = [];
let remaining = [...mappedAsteroids],
destroyedAngles = new Set();
while ( remaining.length ) {
const newRemaining = [];
remaining.forEach( ( asteroid ) => {
if ( asteroid.distance == 0 ) return;
if ( destroyedAngles.has( asteroid.angleFromTop ) ) {
newRemaining.push( asteroid );
} else {
destroyed.push( asteroid );
destroyedAngles.add( asteroid.angleFromTop );
}
} );
remaining = newRemaining;
destroyedAngles = new Set();
}
return destroyed;
}
Insert cell
destroyOrder( test2Mapped );
Insert cell
{
const allOutputs = [];
for( let i = 9; i < test2Mapped.length; i += 9 ) {
const output = [
[ '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' ],
[ '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' ],
[ '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' ],
[ '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' ],
[ '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' ],
];
output[3][8] = 'X';
destroyOrder( test2Mapped ).forEach( ( a, idx ) => { if ( idx >= (i - 9) && idx < i ) output[a.y][a.x] = ( ( idx % 9 ) + 1 ) } );
allOutputs.push( output.map( r => r.join('') ).join( '\n' ) );
}
return '\n' + allOutputs.join( '\n\n' ) + '\n';
}
Insert cell
Insert cell
baseTest3 = findBestVisiblity( test3grid );
Insert cell
test3 = parse( test3grid );
Insert cell
destroyOrder( mapAsteroids( [ baseTest3.x, baseTest3.y ], test3 ).sort( sortByNumber('distance') ).sort( sortByNumber('angleFromTop') ) )[199]
Insert cell
destroyOrder( mapAsteroids( [ part1.x, part1.y ], parse( input ) ).sort( sortByNumber('distance') ).sort( sortByNumber('angleFromTop') ) )[199]
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more