Home Manual Reference Source

src/uBound.js

import assert from 'assert';

/**
 * Computes an upper bound for the signed distance.
 *
 * Note that lBound(D, N) = uBound(D, M) is possible if and only if we have
 * D = N + M and N >= 1 and M >= 1. Case analysis:
 *
 *  - D = -D NOT POSSIBLE SINCE D >= 1
 *  - D = D - M * 2 NOT POSSIBLE SINCE M >= 1
 *  - -D = N * 2 - D  NOT POSSIBLE SINCE N >= 1
 *  - D - M * 2 = N * 2 - D POSSIBLE ONLY IF D = N + M, D >= N + 1, and D >= M + 1.
 *
 *  Note that we only use lBound and uBound when this special case does not
 *  happen. This required some refactoring in oneWay to pull-out the case D = N
 *  + M. None was required in twoWayScan since we have the assertions
 *  2 * D <= MAX + parityDelta and MAX <= N + M.
 *
 * @see lBound
 *
 * @param {number} D >= 1
 * @param {number} N >= 1
 * @return {number} A number -D < k <= N.
 */
export default function uBound(D, N) {
	assert(N >= 1);
	assert(D >= 1);
	const k = D <= N ? D | 0 : ((N << 1) - D) | 0;
	assert(k <= N);
	assert(k > -D);
	assert((D & 1) === (k & 1));
	return k;
}