Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## 2024-04-15 - [Avoid O(N log N) Sorting on Massive Geographical Collections]
**Learning:** In spatial queries like `findNearbyStations` where we scan `railwayData` containing thousands of stations to find the top K nearest points, allocating all elements to an array and running `Array.prototype.sort()` results in massive temporary object allocation and $O(N \log N)$ execution time (taking ~8.5ms in benchmarks).
**Action:** Replace full array sorts with a bounded Top-K array using a simple $O(K)$ insertion sort during the $O(N)$ iteration phase. This brings the time complexity effectively down to $O(N)$, speeding up operations by ~36x (taking ~0.24ms). Remember to apply a final sort if total elements found are less than $K$.

## 2024-05-25 - [O(1) Station Name Lookup in getTransferableLines]
**Learning:** getTransferableLines loops over all lines and stations to match station names, taking O(L*S) time.
**Action:** Use the existing buildStationIndex which provides an O(1) cache for station names to optimize this search.
24 changes: 15 additions & 9 deletions src/core/railwayRouting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,21 @@ export const getTransferableLines = (station: Station | undefined, currentLineKe
});
}

for (const lineKey in railwayData) {
if (!Object.prototype.hasOwnProperty.call(railwayData, lineKey)) continue;
if (lineKey === currentLineKey) continue;
if (validLines.has(lineKey)) continue;
const nextMeta = railwayData[lineKey].meta;
const sameNameStation = railwayData[lineKey].stations.find(s => s.name_ja === station.name_ja);
if (sameNameStation) {
const dist = calcDist(station.lat, station.lng, sameNameStation.lat, sameNameStation.lng);
if (dist < 0.5) validLines.add(lineKey);
// Optimize: Use O(1) station index instead of O(L*S) loop
const stationIndexMap = buildStationIndex(railwayData);
const sameNameStations = stationIndexMap.get(station.name_ja);

if (sameNameStations) {
for (const match of sameNameStations) {
const lineKey = match.lineKey;
if (lineKey === currentLineKey) continue;
if (validLines.has(lineKey)) continue;

const sameNameStation = railwayData[lineKey].stations[match.stationIndex];
if (sameNameStation) {
const dist = calcDist(station.lat, station.lng, sameNameStation.lat, sameNameStation.lng);
if (dist < 0.5) validLines.add(lineKey);
}
}
}
return Array.from(validLines);
Expand Down