<?php
/*
Sample Input
100
9999
123456
1000000000
0
Sample Output
21
356
1684
438744
*/
// n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34...
// opsAddCountDown 0 0 1 0 1 0 2 1 0 2 1....
// opsAddCount 1 2 2 3 3 4 4 4 5 5 5....
// opsAddFut 1 2 2 3 3 4 4 4 5 5 5 6 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 9 10 10 10 10 10 11...
// opsAdd +1 +2 . +2 . +3 . . +3 . . +4 . . . +4 . . . +4 . . . +5 . . . . +5 . . . . +5...
// sum 1 3 3 5 5 8 8 8 11 11 11 15 15 15 15 19 19 19 19 23 23 23 23 28 28 28 28 28 33 33 33 33 33 38...
// goto n(sum+1) 2 4 6 9 12 16 20 24 29 34 39...
/**
*
* @author Starson Hochschild <starsonh@gmail.com>
*
*/
abstract class golomb
{
/**
* V2 - implement conditional array building and count
*
* @param int $n
* @return NULL|number
*/
public static function f($n)
{
$n = (int)$n;
if($n < 1)
return null;
$queueOpsAddCountDown = array();
$ops = 0;
$opsAdd = 0;
$opsAddCountDown = 0;
$opsAddFuture = 0;
$opsAddDone = true;
$predictSum = true;
$sum = 0;
$sumFuture = 0;
while ($sum < $n)
{
$opsAddDone = $opsAddCountDown == 0;
// If we're done with this $opsAdd increment it, separated from the $opsAddDone block below on purpose
if($opsAddDone)
{
$opsAdd++;
}
// Cache a future $opsAddCountDown
if($predictSum)
{
$opsAddFuture++;
$queueOpsAddCountDown[] = $opsAdd;
// See if this will be enough to equal or overtake $n
$sumFuture += $opsAddFuture * $opsAdd;
$predictSum = $sumFuture < $n;
}
// If we're done with this $opsAdd grab a new $opsAddCountDown from $listOpsAddCountDown
if($opsAddDone)
{
$opsAddCountDown = array_shift($queueOpsAddCountDown);
}
// Do the real work
$sum += $opsAdd;
$ops++;
$opsAddCountDown--;
}
return $ops;
}
public static function fThisList($listN)
{
$listN = preg_split("/[\s,]+/", $listN);
$fN = array();
foreach($listN as $n)
$fN[$n] = self::f($n);
return $fN;
}
}
$listN = "1
2
3
4
5
6
7
8
9
10
11
12
100
9999
123456
1000000000
2000000000
2147483647";
$fn = 0;
if(isset($_GET["listN"]))
{
$listN = $_GET["listN"];
$start = microtime(true);
$fn = golomb::fThisList($listN);
$end = microtime(true);
}
?>
<html>
<head></head>
<body>
<form action="" method="get">
<i>f(<textarea name="listN" rows="15"><?php echo htmlentities($listN); ?></textarea>)</i><br />
<input type="submit" value="Calculate f(n)" /><br /><br />
<i>f(n) =</i>
<pre><?php var_export($fn); ?></pre><br />
<?php
if(isset($end))
{ ?>
Combined processing time: <?php echo $end - $start ?> seconds
<?php
} ?>
</form>
This page's source:<br />
<?php
htmlentities(highlight_file(__FILE__));
?>
</body>
</html>
<?php
/**
* This is here for historical purposes. It shows the progression that lead to the method above.
* @author Starson Hochschild <starsonh@gmail.com>
*
*/
abstract class golombArchive
{
/**
* V1.1 - added some memory management
* Better, but still takes a lot of memory and crashes on large(r) numbers due to running out of memory
*
* @param int $n
* @return NULL|number
*/
public static function fWithCleanup($n)
{
$n = (int)$n;
if($n < 1)
return null;
$listFn = array();
$ops = 0;
$sum = 0;
for($cn = 0; $sum < $n; $cn++)
{
if($sum < $cn)
{
$ops++;
$listFn[$cn] = $ops;
$sum += $listFn[$ops];
// Cleanup
unset($listFn[$ops]);
if($ops % 4096 == 0)
gc_collect_cycles();
}
else
{
$listFn[$cn] = $ops;
}
}
return $ops;
}
/**
* V1 - a simple, "brute force" type of approach
* Takes a lot of memory and crashes on large numbers due to running out of memory
*
* @param int $n
* @return NULL|number
*/
public static function fBrute($n)
{
$listFn = array();
$n = (int)$n;
if($n < 1)
return null;
$ops = 0;
$sum = 0;
for($cn = 0; $sum < $n; $cn++)
{
if($sum < $cn)
{
$ops++;
$listFn[$cn] = $ops;
$sum += $listFn[$ops];
}
else
{
$listFn[$cn] = $ops;
}
}
return $ops;
}
}
?>
- Output for 5.4.35 - 5.4.45, 5.5.19 - 5.5.38, 5.6.2 - 5.6.38, 7.0.0 - 7.0.31, 7.1.0 - 7.1.22, 7.2.0 - 7.2.10
- <html>
<head></head>
<body>
<form action="" method="get">
<i>f(<textarea name="listN" rows="15">1
2
3
4
5
6
7
8
9
10
11
12
100
9999
123456
1000000000
2000000000
2147483647</textarea>)</i><br />
<input type="submit" value="Calculate f(n)" /><br /><br />
<i>f(n) =</i>
<pre>0</pre><br />
</form>
This page's source:<br />
<code><span style="color: #000000">
<span style="color: #0000BB"><?php<br /></span><span style="color: #FF8000">/*<br />Sample Input<br />100<br />9999<br />123456<br />1000000000<br />0<br /><br />Sample Output<br />21<br />356<br />1684<br />438744<br />*/<br /><br />// n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34...<br />// opsAddCountDown 0 0 1 0 1 0 2 1 0 2 1....<br />// opsAddCount 1 2 2 3 3 4 4 4 5 5 5....<br />// opsAddFut 1 2 2 3 3 4 4 4 5 5 5 6 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 9 10 10 10 10 10 11...<br />// opsAdd +1 +2 . +2 . +3 . . +3 . . +4 . . . +4 . . . +4 . . . +5 . . . . +5 . . . . +5...<br />// sum 1 3 3 5 5 8 8 8 11 11 11 15 15 15 15 19 19 19 19 23 23 23 23 28 28 28 28 28 33 33 33 33 33 38...<br />// goto n(sum+1) 2 4 6 9 12 16 20 24 29 34 39...<br /><br />/**<br /> * <br /> * @author Starson Hochschild <starsonh@gmail.com><br /> *<br /> */<br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">golomb<br /></span><span style="color: #007700">{<br /> </span><span style="color: #FF8000">/**<br /> * V2 - implement conditional array building and count<br /> *<br /> * @param int $n<br /> * @return NULL|number<br /> */<br /> </span><span style="color: #007700">public static function </span><span style="color: #0000BB">f</span><span style="color: #007700">(</span><span style="color: #0000BB">$n</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$n </span><span style="color: #007700">= (int)</span><span style="color: #0000BB">$n</span><span style="color: #007700">;<br /> if(</span><span style="color: #0000BB">$n </span><span style="color: #007700">< </span><span style="color: #0000BB">1</span><span style="color: #007700">)<br /> return </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br /><br /> </span><span style="color: #0000BB">$queueOpsAddCountDown </span><span style="color: #007700">= array();<br /> </span><span style="color: #0000BB">$ops </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$opsAdd </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$opsAddCountDown </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$opsAddFuture </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$opsAddDone </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$predictSum </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$sum </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$sumFuture </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /><br /> while (</span><span style="color: #0000BB">$sum </span><span style="color: #007700">< </span><span style="color: #0000BB">$n</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$opsAddDone </span><span style="color: #007700">= </span><span style="color: #0000BB">$opsAddCountDown </span><span style="color: #007700">== </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #FF8000">// If we're done with this $opsAdd increment it, separated from the $opsAddDone block below on purpose<br /> </span><span style="color: #007700">if(</span><span style="color: #0000BB">$opsAddDone</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$opsAdd</span><span style="color: #007700">++;<br /> }<br /><br /> </span><span style="color: #FF8000">// Cache a future $opsAddCountDown<br /> </span><span style="color: #007700">if(</span><span style="color: #0000BB">$predictSum</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$opsAddFuture</span><span style="color: #007700">++;<br /> </span><span style="color: #0000BB">$queueOpsAddCountDown</span><span style="color: #007700">[] = </span><span style="color: #0000BB">$opsAdd</span><span style="color: #007700">;<br /> </span><span style="color: #FF8000">// See if this will be enough to equal or overtake $n<br /> </span><span style="color: #0000BB">$sumFuture </span><span style="color: #007700">+= </span><span style="color: #0000BB">$opsAddFuture </span><span style="color: #007700">* </span><span style="color: #0000BB">$opsAdd</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$predictSum </span><span style="color: #007700">= </span><span style="color: #0000BB">$sumFuture </span><span style="color: #007700">< </span><span style="color: #0000BB">$n</span><span style="color: #007700">;<br /> }<br /><br /> </span><span style="color: #FF8000">// If we're done with this $opsAdd grab a new $opsAddCountDown from $listOpsAddCountDown<br /> </span><span style="color: #007700">if(</span><span style="color: #0000BB">$opsAddDone</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$opsAddCountDown </span><span style="color: #007700">= </span><span style="color: #0000BB">array_shift</span><span style="color: #007700">(</span><span style="color: #0000BB">$queueOpsAddCountDown</span><span style="color: #007700">);<br /> }<br /><br /> </span><span style="color: #FF8000">// Do the real work<br /> </span><span style="color: #0000BB">$sum </span><span style="color: #007700">+= </span><span style="color: #0000BB">$opsAdd</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$ops</span><span style="color: #007700">++;<br /> </span><span style="color: #0000BB">$opsAddCountDown</span><span style="color: #007700">--;<br /> }<br /> <br /> return </span><span style="color: #0000BB">$ops</span><span style="color: #007700">;<br /> }<br /><br /> public static function </span><span style="color: #0000BB">fThisList</span><span style="color: #007700">(</span><span style="color: #0000BB">$listN</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$listN </span><span style="color: #007700">= </span><span style="color: #0000BB">preg_split</span><span style="color: #007700">(</span><span style="color: #DD0000">"/[\s,]+/"</span><span style="color: #007700">, </span><span style="color: #0000BB">$listN</span><span style="color: #007700">);<br /><br /> </span><span style="color: #0000BB">$fN </span><span style="color: #007700">= array();<br /><br /> foreach(</span><span style="color: #0000BB">$listN </span><span style="color: #007700">as </span><span style="color: #0000BB">$n</span><span style="color: #007700">)<br /> </span><span style="color: #0000BB">$fN</span><span style="color: #007700">[</span><span style="color: #0000BB">$n</span><span style="color: #007700">] = </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">f</span><span style="color: #007700">(</span><span style="color: #0000BB">$n</span><span style="color: #007700">);<br /><br /> return </span><span style="color: #0000BB">$fN</span><span style="color: #007700">;<br /> }<br />}<br /><br /></span><span style="color: #0000BB">$listN </span><span style="color: #007700">= </span><span style="color: #DD0000">"1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />100<br />9999<br />123456<br />1000000000<br />2000000000<br />2147483647"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$fn </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />if(isset(</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">"listN"</span><span style="color: #007700">]))<br />{<br /> </span><span style="color: #0000BB">$listN </span><span style="color: #007700">= </span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">"listN"</span><span style="color: #007700">];<br /> </span><span style="color: #0000BB">$start </span><span style="color: #007700">= </span><span style="color: #0000BB">microtime</span><span style="color: #007700">(</span><span style="color: #0000BB">true</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$fn </span><span style="color: #007700">= </span><span style="color: #0000BB">golomb</span><span style="color: #007700">::</span><span style="color: #0000BB">fThisList</span><span style="color: #007700">(</span><span style="color: #0000BB">$listN</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$end </span><span style="color: #007700">= </span><span style="color: #0000BB">microtime</span><span style="color: #007700">(</span><span style="color: #0000BB">true</span><span style="color: #007700">);<br />}<br /></span><span style="color: #0000BB">?><br /></span><html><br /><head></head><br /><body><br /><form action="" method="get"><br /><i>f(<textarea name="listN" rows="15"><span style="color: #0000BB"><?php </span><span style="color: #007700">echo </span><span style="color: #0000BB">htmlentities</span><span style="color: #007700">(</span><span style="color: #0000BB">$listN</span><span style="color: #007700">); </span><span style="color: #0000BB">?></span></textarea>)</i><br /><br /><input type="submit" value="Calculate f(n)" /><br /><br /><br /><i>f(n) =</i><br /><pre><span style="color: #0000BB"><?php var_export</span><span style="color: #007700">(</span><span style="color: #0000BB">$fn</span><span style="color: #007700">); </span><span style="color: #0000BB">?></span></pre><br /><br /><span style="color: #0000BB"><?php<br /></span><span style="color: #007700">if(isset(</span><span style="color: #0000BB">$end</span><span style="color: #007700">))<br />{ </span><span style="color: #0000BB">?><br /></span>Combined processing time: <span style="color: #0000BB"><?php </span><span style="color: #007700">echo </span><span style="color: #0000BB">$end </span><span style="color: #007700">- </span><span style="color: #0000BB">$start ?></span> seconds<br /><span style="color: #0000BB"><?php<br /></span><span style="color: #007700">} </span><span style="color: #0000BB">?><br /></span></form><br />This page's source:<br /><br /><span style="color: #0000BB"><?php<br />htmlentities</span><span style="color: #007700">(</span><span style="color: #0000BB">highlight_file</span><span style="color: #007700">(</span><span style="color: #0000BB">__FILE__</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">?><br /></span></body><br /></html><br /><span style="color: #0000BB"><?php<br /></span><span style="color: #FF8000">/**<br /> * This is here for historical purposes. It shows the progression that lead to the method above.<br /> * @author Starson Hochschild <starsonh@gmail.com><br /> *<br /> */<br /></span><span style="color: #007700">abstract class </span><span style="color: #0000BB">golombArchive<br /></span><span style="color: #007700">{<br /> </span><span style="color: #FF8000">/**<br /> * V1.1 - added some memory management<br /> * Better, but still takes a lot of memory and crashes on large(r) numbers due to running out of memory<br /> *<br /> * @param int $n<br /> * @return NULL|number<br /> */<br /> </span><span style="color: #007700">public static function </span><span style="color: #0000BB">fWithCleanup</span><span style="color: #007700">(</span><span style="color: #0000BB">$n</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$n </span><span style="color: #007700">= (int)</span><span style="color: #0000BB">$n</span><span style="color: #007700">;<br /> if(</span><span style="color: #0000BB">$n </span><span style="color: #007700">< </span><span style="color: #0000BB">1</span><span style="color: #007700">)<br /> return </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br /> <br /> </span><span style="color: #0000BB">$listFn </span><span style="color: #007700">= array();<br /> </span><span style="color: #0000BB">$ops </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$sum </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> for(</span><span style="color: #0000BB">$cn </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">; </span><span style="color: #0000BB">$sum </span><span style="color: #007700">< </span><span style="color: #0000BB">$n</span><span style="color: #007700">; </span><span style="color: #0000BB">$cn</span><span style="color: #007700">++)<br /> {<br /> if(</span><span style="color: #0000BB">$sum </span><span style="color: #007700">< </span><span style="color: #0000BB">$cn</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$ops</span><span style="color: #007700">++;<br /> </span><span style="color: #0000BB">$listFn</span><span style="color: #007700">[</span><span style="color: #0000BB">$cn</span><span style="color: #007700">] = </span><span style="color: #0000BB">$ops</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$sum </span><span style="color: #007700">+= </span><span style="color: #0000BB">$listFn</span><span style="color: #007700">[</span><span style="color: #0000BB">$ops</span><span style="color: #007700">];<br /> <br /> </span><span style="color: #FF8000">// Cleanup<br /> </span><span style="color: #007700">unset(</span><span style="color: #0000BB">$listFn</span><span style="color: #007700">[</span><span style="color: #0000BB">$ops</span><span style="color: #007700">]);<br /> if(</span><span style="color: #0000BB">$ops </span><span style="color: #007700">% </span><span style="color: #0000BB">4096 </span><span style="color: #007700">== </span><span style="color: #0000BB">0</span><span style="color: #007700">)<br /> </span><span style="color: #0000BB">gc_collect_cycles</span><span style="color: #007700">();<br /> }<br /> else<br /> {<br /> </span><span style="color: #0000BB">$listFn</span><span style="color: #007700">[</span><span style="color: #0000BB">$cn</span><span style="color: #007700">] = </span><span style="color: #0000BB">$ops</span><span style="color: #007700">;<br /> }<br /> }<br /> <br /> return </span><span style="color: #0000BB">$ops</span><span style="color: #007700">;<br /> }<br /><br /> </span><span style="color: #FF8000">/**<br /> * V1 - a simple, "brute force" type of approach<br /> * Takes a lot of memory and crashes on large numbers due to running out of memory<br /> *<br /> * @param int $n<br /> * @return NULL|number<br /> */<br /> </span><span style="color: #007700">public static function </span><span style="color: #0000BB">fBrute</span><span style="color: #007700">(</span><span style="color: #0000BB">$n</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$listFn </span><span style="color: #007700">= array();<br /> </span><span style="color: #0000BB">$n </span><span style="color: #007700">= (int)</span><span style="color: #0000BB">$n</span><span style="color: #007700">;<br /> if(</span><span style="color: #0000BB">$n </span><span style="color: #007700">< </span><span style="color: #0000BB">1</span><span style="color: #007700">)<br /> return </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br /> <br /> </span><span style="color: #0000BB">$ops </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$sum </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br /> for(</span><span style="color: #0000BB">$cn </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">; </span><span style="color: #0000BB">$sum </span><span style="color: #007700">< </span><span style="color: #0000BB">$n</span><span style="color: #007700">; </span><span style="color: #0000BB">$cn</span><span style="color: #007700">++)<br /> {<br /> if(</span><span style="color: #0000BB">$sum </span><span style="color: #007700">< </span><span style="color: #0000BB">$cn</span><span style="color: #007700">)<br /> {<br /> </span><span style="color: #0000BB">$ops</span><span style="color: #007700">++;<br /> </span><span style="color: #0000BB">$listFn</span><span style="color: #007700">[</span><span style="color: #0000BB">$cn</span><span style="color: #007700">] = </span><span style="color: #0000BB">$ops</span><span style="color: #007700">;<br /> </span><span style="color: #0000BB">$sum </span><span style="color: #007700">+= </span><span style="color: #0000BB">$listFn</span><span style="color: #007700">[</span><span style="color: #0000BB">$ops</span><span style="color: #007700">];<br /> }<br /> else<br /> {<br /> </span><span style="color: #0000BB">$listFn</span><span style="color: #007700">[</span><span style="color: #0000BB">$cn</span><span style="color: #007700">] = </span><span style="color: #0000BB">$ops</span><span style="color: #007700">;<br /> }<br /> }<br /> <br /> return </span><span style="color: #0000BB">$ops</span><span style="color: #007700">;<br /> }<br />}<br /></span><span style="color: #0000BB">?></span>
</span>
</code></body>
</html>
preferences:
242.12 ms | 466 KiB | 139 Q