public static class UserDocumentUtility
private const int UserDocumentPayoutDurationInYears = 3;
private const decimal ExpectedUserDocumentIncreasePerYear = 100m / UserDocumentPayoutDurationInYears;
private static readonly Random Random = new Random();
private static decimal GetRandomFactor(bool slow)
return (decimal)Random.NextDouble() * (slow ? 3m : 0.2m);
private static decimal CalculateUserDocumentPercentage(decimal previousPercentage, DateTime createDate, DateTime? simulatedNow = null)
var now = simulatedNow ?? DateTime.Now;
var diff = new DateTime(now.Year, now.Month, now.Day) - createDate;
var diffInYears = Math.Abs(diff.Days) / 365m;
var expectedPercentage = ExpectedUserDocumentIncreasePerYear * diffInYears;
var margin = previousPercentage - expectedPercentage;
var factor = GetRandomFactor(margin > 0);
var nextPercentage = previousPercentage - margin * factor;
return Math.Min(nextPercentage, 100m);
public static void Main(string[] args)
DateTime createDate = new DateTime(2024, 1, 1);
DateTime endDate = createDate.AddYears(3);
Console.WriteLine($"Start Date: {createDate}");
Console.WriteLine($"End Date: {endDate}");
decimal previousPercentage = 0;
Console.WriteLine("Percentage over time:");
for (DateTime date = createDate; date <= endDate; date = date.AddDays(7))
decimal percentage = CalculateUserDocumentPercentage(previousPercentage, createDate, date);
string bar = new string ('%', (int)Math.Round(percentage));
Console.WriteLine($"{date:MMM yyyy} | {bar} {percentage}%");
previousPercentage = percentage;