Javascript solution

I enjoyed doing this one. It somehow felt satisfying. Maybe it's because for this one I was able to realize it's a series of steps and I could develop and test each one of them step-by-step, so I felt confident I was moving into the right direction.

``````const fs = require('fs');

const readLines = (file, onLine) => {
crlfDelay: Infinity
});

return new Promise(resolve => reader.on('close', resolve));
};

const readFile = async file => {
const lines = [];
return lines;
}

module.exports = {
};
``````

06-common.js

``````class Coordinate {
constructor(x, y, id) {
this.x = x;
this.y = y;
this.id = id;
}
}

const buildCoordinates = lines => {
return lines.map((line, index) => {
const [x, y] = line.split(', ');
return new Coordinate(+x, +y, index);
});
};

const getGridDimension = coordinates => {
let largestX = 0;
let largestY = 0;
for (let coordinate of coordinates) {
const { x, y } = coordinate;
largestX = Math.max(largestX, x);
largestY = Math.max(largestY, y);
}
return Math.max(largestX, largestY) + 1;
}

const plotCoordinates = coordinates => {
const n = getGridDimension(coordinates);

const grid = Array.from({ length: n }, row => Array.from({ length: n }));
for (let coordinate of coordinates) {
const { x, y } = coordinate;
grid[x][y] = coordinate;
}
return grid;
};

const calculateManhattanDistance = (c1, c2) => {
return Math.abs(c1.x - c2.x) + Math.abs(c1.y - c2.y);
};

module.exports = {
Coordinate,
buildCoordinates,
getGridDimension,
plotCoordinates,
calculateManhattanDistance
};
``````

06a.js

``````const { readFile } = require('./reader');

const {
Coordinate,
buildCoordinates,
getGridDimension,
plotCoordinates,
calculateManhattanDistance
} = require('./06-common');

const plotLocations = (coordinates, grid) => {
const n = grid.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (!grid[i][j]) {
const location = new Coordinate(i, j);
grid[i][j] = location;

let smallestDistance;
let closestCoordinates;
for (let coordinate of coordinates) {
const distance = calculateManhattanDistance(location, coordinate);

if (!closestCoordinates || distance < smallestDistance) {
smallestDistance = distance;
closestCoordinates = [coordinate];
}
else if (distance === smallestDistance) {
closestCoordinates.push(coordinate);
}
}

if (closestCoordinates.length === 1) {
location.closestCoordinate = closestCoordinates[0];
}
}
}
}
};

const getFiniteCoordinateIds = (coordinates, grid) => {
const n = grid.length;
const infiniteCoordinateIds = new Set();

// Top and bottom edges
for (let i = 0; i < n; i += n-1) {
for (let j = 0; j < n; j++) {
const closestCoordinate = grid[i][j].closestCoordinate;
if (closestCoordinate) {
}
}
}

// Left and right edges
for (let j = 0; j < n; j += n-1) {
for (let i = 0; i < n; i++) {
const closestCoordinate = grid[i][j].closestCoordinate;
if (closestCoordinate) {
}
}
}

const finiteCoordinateIds = coordinates
.filter(coordinate => !infiniteCoordinateIds.has(coordinate.id))
.map(coordinate => coordinate.id);

return new Set(finiteCoordinateIds);
};

const calculateCoordinateRegions = (finiteCoordinates, grid) => {
const n = grid.length;
const frequencyMap = new Map();
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
const closestCoordinate = grid[i][j].closestCoordinate;
if (closestCoordinate && finiteCoordinates.has(closestCoordinate.id)) {
const { id } = closestCoordinate;
const frequency = frequencyMap.get(id) || 1;
frequencyMap.set(id, frequency+1);
}
}
}
return frequencyMap;
};

(async () => {

const coordinates = buildCoordinates(lines);
const grid = plotCoordinates(coordinates);
plotLocations(coordinates, grid);
const finiteCoordinateIds = getFiniteCoordinateIds(coordinates, grid);
const coordinateRegions = calculateCoordinateRegions(finiteCoordinateIds, grid);
const largestRegion = Math.max(...coordinateRegions.values());

console.log(`The largest region is \${largestRegion}`);
})();
``````

06b.js

``````const { readFile } = require('./reader');

const {
Coordinate,
buildCoordinates,
getGridDimension,
plotCoordinates,
calculateManhattanDistance
} = require('./06-common');

const MAX_TOTAL_DISTANCE = 10000;

const plotLocations = (coordinates, grid) => {
const n = grid.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
let location = grid[i][j];
if (!grid[i][j]) {
location = new Coordinate(i, j);
grid[i][j] = location;
}

const totalDistance = coordinates.reduce((sum, coordinate) =>{
return sum + calculateManhattanDistance(location, coordinate);
}, 0);

location.inSafeRegion = totalDistance < MAX_TOTAL_DISTANCE;
}
}
};

const getSafeRegionSize = grid => {
const n = grid.length;
let safeRegionSize = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
const location = grid[i][j];
safeRegionSize += +location.inSafeRegion;
}
}
return safeRegionSize;
};

(async () => {