我会改写你的问题:你正在寻找一个函数/算法,给定一个数字 N,将返回以下内容(在这里制作一个小表):
N return
1 1
2 2
3 3
4 4
5 4
6 4
7 4
8 4
9 5
10 6
以下代码演示了如何执行此操作的简单方法 - 它仅在相同数量的付费天数 (4) 后跟相同数量的未付费天数 (4) 时有效:
<?php
for($n=1; $n<20; $n++)
{
$m = ($n-1)%4 + 1; // returns 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4...
$unpaid = intval(($n-1)/4)%2; // returns 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,...
$fourBlocks = intval(($n-1)/8); // returns 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,...
if ($unpaid == 1)
{
$daysCharged = $n - $m - 4 * $fourBlocks;
}
else
{
$daysCharged = $n - 4 * $fourBlocks;
}
echo $n . " days: " . $daysCharged . " days charged, ". ($n - $daysCharged) . " free\n";
}
?>
这会产生以下输出:
1 days: 1 days charged, 0 free
2 days: 2 days charged, 0 free
3 days: 3 days charged, 0 free
4 days: 4 days charged, 0 free
5 days: 4 days charged, 1 free
6 days: 4 days charged, 2 free
7 days: 4 days charged, 3 free
8 days: 4 days charged, 4 free
9 days: 5 days charged, 4 free
10 days: 6 days charged, 4 free
11 days: 7 days charged, 4 free
12 days: 8 days charged, 4 free
13 days: 8 days charged, 5 free
14 days: 8 days charged, 6 free
15 days: 8 days charged, 7 free
16 days: 8 days charged, 8 free
17 days: 9 days charged, 8 free
18 days: 10 days charged, 8 free
19 days: 11 days charged, 8 free
注意 - 在更一般的情况下,您有 N 天收费,然后是 M 天不收费,您可以按如下方式更改代码:
<?php
$N = 4;
$M = 4;
echo $N . " days charged followed by " . $M . " days free:\n";
for($days=1; $days<20; $days++)
{
$numBlocks = intval(($days - 1) / ($N + $M)); // a "block" is a complete cycle of paid & unpaid days
$remainder = $days - ($N + $M) * $numBlocks; // the "remainder" contains an incomplete cycle
$unpaid = $remainder - $N;
if ($unpaid < 0) $unpaid = 0; // this now contains the number of unpaid days in the incomplete cycle
$daysCharged = $numBlocks * $N + $remainder - $unpaid; // easy to compute the number that must be charged
echo $days . " days: " . $daysCharged . " days charged, ". ($days - $daysCharged) . " free\n";
}
?>
这实际上更加稳健,无论 M 和 N 的值如何,都会为您提供正确的答案(因此您可以很容易地更改收费方案)。