/**
* @param {number} sx
* @param {number} sy
* @param {number} tx
* @param {number} ty
* @return {boolean}
*
* 算法: 将(tx, ty)不断变小, 直到(tx, ty)与(sx, sy)相等。
根据规则, (tx, ty)只能由一个数对变来, 不可能由两个数对变来。
当tx > ty时, (tx, ty)的最近一个比他小的数对是(tx - ty, ty),
当tx < ty时, (tx, ty)的最近一个比他小的数对是(tx, ty - tx),
当tx == ty时, 只能与(sx, sy)比较是否相等。相等就是true, 不能结果就是false
*/
var reachingPoints = function(sx, sy, tx, ty) {
/*
如果tx < sx 或ty < sy, 可以直接返回false, 不进while循环
*/
while((tx >= sx) && (ty >= sy)) {
/* 拦截相等, 这里包括了(tx === sx) && (ty === sy)的情况和(tx > sx) && (ty > sy) && (tx === ty)的情况 */
if(tx === ty) break
/**
* 剩下的情况有三种:
* 1. ty === sy
* 2. tx === sx
* 3. (ty > sy) && (tx > sx)
* 对第1中情况, tx必须能通过减0个或n个ty变成sx, 否则无论如何都无法将终点数对变成起点数对
*第二种情况类似
对第3种情况,可分两种情况:
(1) tx > ty
(2) ty > tx
如果是情况(1), 那么必须将tx - ty n次, 直到tx <= ty(tx === ty的话直接退出while),
因为这时候ty !== sy, 如果tx 减 (n - k)个ty使得tx > sx,那么要使(tx, ty)与(sx, sy)相等,那么下次还是要tx - ty,直到tx === sx,或tx <= ty。如果tx减(n - k2)(其中k2 < k),个ty后tx === sx,
那么进入了情况2, 那这时候必须(ty === sy)或 ((ty - sy %) tx === 0),在情况(1)中ty !== sy, 且(ty > sy) && (ty < tx) 也就是说, ((ty - sy) % tx === 0)为false。这种情况下, 不管tx是一直减ty直到 tx <ty还是减一半, 结果是一样的, 都是false。如果tx减(n - k2)(其中k2 < k),个ty后tx > sx 且tx减(n - k2 + 1)====(其中k2 < k),个ty后tx < sx,这个时候如果减到tx > sx为止, 因为ty > sy,那么下一次还是必须tx - ty,就只能继续减到一次直到tx < sx,这种情况下最终结果就是false,不管是减一部分还是减n个ty。如果tx 减 n个ty后 tx === sx,这时因为ty > tx 且ty > sy,那就根据等式(ty - sy) % tx === 0判断。如果tx减 n个 ty后 tx > sx,那有就进入了情况(2),情况(2)的判断与情况(1)类似。也就是说, 对于情况3, tx 减满n个ty后必须有 tx >= sx才有可能为true, 否则一定为false
*/
if(ty === sy) {
return (tx - sx) % ty === 0
} else if(tx === sx) {
return (ty - sy) % tx === 0
}else if(ty > tx) {
// 可以一减到底, 因为如果一减到底后 tx < sx,那结果一定是false,
// 如果减后tx >= sx,那就进入了新的循环
ty %= tx
} else tx %= ty
}
return (tx === sx) && (ty === sy)
};```