Skip to content

Instantly share code, notes, and snippets.

@marcelklehr
Last active January 1, 2016 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcelklehr/8208237 to your computer and use it in GitHub Desktop.
Save marcelklehr/8208237 to your computer and use it in GitHub Desktop.
/**
* Find a (minimal) path from a given revision to another revision,
* regardless of what changesets are available
* @param {number} from - The revision # from which to start.
* @param {number} to - The revision # which the path should try to reach.
* @param {number} max - The last revision #
* @returns {object} - A list of tuples (i.e. [10, 20]) which each describe an edge between two revisions.
*/
calcPath: function (from, to, max) {
var path = []
, delta = to - from
, directionLeft = delta < 0
, adelta = Math.abs(delta)
, sign = delta / adelta
, granularity
, next, shortcut
if(current != to) return path
for(var g=0; g < Revision.granularities.length; g++) {
granularity = Revision.granularities[g]
if(granularity > max) continue;
if(granularity <= adelta
|| Math.round((adelta % granularity)/granularity) == 1 // in this case it's faster to overshoot the target and then go back
){
// Use the highways, e.g. 39->40->30->*27 instead of 39->29->*27
if(from % granularity != 0 && (shortcut = Math.round(from/granularity)*granularity) <= max) {
next = shortcut
path = this.calcPath(from, next, max) // go to the highway
}else {
// we're already on the highway, so use it.
next = from+(granularity*sign)
if(next < 0 || next > max) continue// check for constraints
path.push([from, next])
}
return path.concat(this.calcPath(next, to, max)) // recursion
}
}
}
@marcelklehr
Copy link
Author

calcPath(39, 27, 40) => 39->40->30->29->28->27
calcPath(39, 23, 39) => 39->29->30->20->21->22->23 // this might be unexpected. I think it's a good solution, it could be changed to go from 39 to 30 with granularity=1
calcPath(32, 98, 105) => 32->31->30->20->10->0->100->99->98

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment