How to check if two series of dates overlap and determine the first date that it occurs?

a 夏天 提交于 2020-05-13 10:57:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!