Tweak snapIntervalsTogether so that "1 time every x days" habits work better

pull/605/head
Alinson S. Xavier 5 years ago
parent e7a3f0cffa
commit 6d9ad8c56c

@ -122,22 +122,28 @@ public abstract class CheckmarkList
}
/**
* Starting from the oldest interval, this function tries to slide the
* Starting from the second newest interval, this function tries to slide the
* intervals backwards into the past, so that gaps are eliminated and
* streaks are maximized. When it detects that sliding an interval
* would not help fixing any gap, it leaves the interval unchanged.
* streaks are maximized.
*/
static void snapIntervalsTogether(@NonNull ArrayList<Interval> intervals)
{
for (int i = 1; i < intervals.size(); i++)
int n = intervals.size();
for (int i = n - 2; i >= 0; i--)
{
Interval curr = intervals.get(i);
Interval prev = intervals.get(i - 1);
Interval next = intervals.get(i + 1);
int gap = prev.end.daysUntil(curr.begin) - 1;
if (gap <= 0 || curr.end.minus(gap).isOlderThan(curr.center)) continue;
intervals.set(i, new Interval(curr.begin.minus(gap), curr.center,
curr.end.minus(gap)));
int gapNextToCurrent = next.begin.daysUntil(curr.end);
int gapCenterToEnd = curr.center.daysUntil(curr.end);
if (gapNextToCurrent >= 0)
{
int shift = Math.min(gapCenterToEnd, gapNextToCurrent + 1);
intervals.set(i, new Interval(curr.begin.minus(shift),
curr.center,
curr.end.minus(shift)));
}
}
}

@ -319,16 +319,31 @@ public class CheckmarkListTest extends BaseUnitTest
public void test_snapIntervalsTogether_1() throws Exception
{
ArrayList<CheckmarkList.Interval> original = new ArrayList<>();
original.add(new CheckmarkList.Interval(day(40), day(40), day(34)));
original.add(new CheckmarkList.Interval(day(25), day(25), day(19)));
original.add(new CheckmarkList.Interval(day(16), day(16), day(10)));
original.add(new CheckmarkList.Interval(day(27), day(27), day(21)));
original.add(new CheckmarkList.Interval(day(20), day(20), day(14)));
original.add(new CheckmarkList.Interval(day(12), day(12), day(6)));
original.add(new CheckmarkList.Interval(day(8), day(8), day(2)));
ArrayList<CheckmarkList.Interval> expected = new ArrayList<>();
expected.add(new CheckmarkList.Interval(day(40), day(40), day(34)));
expected.add(new CheckmarkList.Interval(day(25), day(25), day(19)));
expected.add(new CheckmarkList.Interval(day(18), day(16), day(12)));
expected.add(new CheckmarkList.Interval(day(11), day(8), day(5)));
expected.add(new CheckmarkList.Interval(day(29), day(27), day(23)));
expected.add(new CheckmarkList.Interval(day(22), day(20), day(16)));
expected.add(new CheckmarkList.Interval(day(15), day(12), day(9)));
expected.add(new CheckmarkList.Interval(day(8), day(8), day(2)));
CheckmarkList.snapIntervalsTogether(original);
assertThat(original, equalTo(expected));
}
@Test
public void test_snapIntervalsTogether_2() throws Exception
{
ArrayList<CheckmarkList.Interval> original = new ArrayList<>();
original.add(new CheckmarkList.Interval(day(11), day(8), day(5)));
original.add(new CheckmarkList.Interval(day(6), day(4), day(0)));
ArrayList<CheckmarkList.Interval> expected = new ArrayList<>();
expected.add(new CheckmarkList.Interval(day(13), day(8), day(7)));
expected.add(new CheckmarkList.Interval(day(6), day(4), day(0)));
CheckmarkList.snapIntervalsTogether(original);
assertThat(original, equalTo(expected));

@ -153,9 +153,9 @@ public class ScoreListTest extends BaseUnitTest
habit.getScores().groupBy(DateUtils.TruncateField.MONTH, Calendar.SATURDAY);
assertThat(list.size(), equalTo(5));
assertThat(list.get(0).getValue(), closeTo(0.653659, E));
assertThat(list.get(1).getValue(), closeTo(0.622715, E));
assertThat(list.get(2).getValue(), closeTo(0.520997, E));
assertThat(list.get(0).getValue(), closeTo(0.687724, E));
assertThat(list.get(1).getValue(), closeTo(0.636747, E));
assertThat(list.get(2).getValue(), closeTo(0.533860, E));
}
@Test

Loading…
Cancel
Save