问题
How to check if two series of dates overlap and determine the first date that it occurs?
Imagine that I've created two events in Google Calendar. One of them in Date1 and repeating every X days; the other in Date2 and repeating every Y days.
What would be the best algorithm to determine if the two series will overlap someday, and find the first date that it would happen?
Example 1:
Date1 = Feb-15, 2016
X = 14 (repeat every 14 days)
Date2 = Feb-22, 2016
Y = 21 (repeat every 21 days)
Result: first overlap on Mar-14, 2016
Example 2:
Date1 = Feb-15, 2016
X = 14 (repeat every 14 days)
Date2 = Feb-22, 2016
Y = 28 (repeat every 28 days)
Result: will never overlap
回答1:
Lets define the mathematical relationship between the 2 series. First define some variables:
- c - This is the initial offset between the starting dates (Date2 - Date1)
- S1 - This is the "step size" (repeat) of Date1.
- S2 - This is the "step size" (repeat) of Date2.
- i - This repetition count of series 1 at point of overlap.
- j - This repetition count of series 2 at point of overlap.
We can say that when the series overlap, there exists some i, j ∈ℤ (integers) such that:
i*S1 = c + j*S2 (and then)
i = (c + j*S2) / S1
To find j (and then the overlap point by c + j*S2), we can use the following algorithm:
if c % S1 is 0 then return 0
else
let j = 1
while (S2 * j) % S1 != c
if (c + S2 * j) % S1 == 0 then return j
j = j + 1
loop
return -1 (not found)
If the algorithm returns -1, there's no overlap. Otherwise the overlap is found.
You can try this out right here:
$('#find').click(function() {
var c = +$('#C').val();
var S1 = +$('#S1').val();
var S2 = +$('#S2').val();
var j = findOverlap(c, S1, S2);
if(j === -1) {
$('#result').text('No overlap!');
return;
}
$('#result').text('Overlap found at ' + (c + S2 * j));
});
function findOverlap(c, S1, S2) {
if(c % S1 === 0) {
return 0;
}
var j = 1;
while((S2 * j) % S1 > 0) {
if((c + S2 * j) % S1 === 0) {
return j;
}
j++;
}
return -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
C: <input type="text" id="C" /><br/>
S1: <input type="text" id="S1" /><br/>
S2: <input type="text" id="S2" /><br/>
<button id="find">Find!</button><span id="result"></span>
I suppose there's also a purely mathematical method to come up with this, but I image it would involve a variation of the LCM algorithm, which would require similar iterative steps.
来源:https://stackoverflow.com/questions/35397485/how-to-check-if-two-series-of-dates-overlap-and-determine-the-first-date-that-it