class fruits
{
function g($str = 'fruits'){
$i=0;
$new_str = "";
while ($i < strlen($str)-1){
$new_str = $new_str + $str[$i+1];
$i = $i + 1;
}
return $new_str;
}
function f($str = 'fruits') {
if (strlen($str)== 0) {
return "";
}
else if (strlen($str)== 1)
{
return $str;
}
else
{
return $this->f($this->g($str)) + $str[0]; }
}
function h($n=1, $str = 'fruits'){
while ($n != 1){
if ($n % 2 == 0){
$n = $n/2;
}
else
{
$n = 3*$n + 1;
}
$str = $this->f($str);
}
return $str;
}
function pow($x, $y){
if (y==0)
{
return 1;
}
else
{
return $x * $this->pow($x, $y-1);
}
}
}
$obj = new fruits;
print(h(pow());
I only want to ask how to echo a function like this print(h(pow);?
First turn on error reporting with:
<?php
ini_set("display_errors", 1);
error_reporting(E_ALL);
?>
And you will see (Besides the typos):
Fatal error: Call to undefined function h() in ...
That is because you have a class with methods. So you have to take an instance of your class an call the method from it, e.g.
$obj = new fruits;
echo $obj->h($obj->pow(4, 5));
This is basic OOP PHP. Also I would highly recommed you to use more meaningful function and variable names!
Related
I'm trying to implement the ball clock (determine how many iterations an inputed number of balls in the initial queue would go before returning to its initial order) in php. I believe at this point my code is not recognizing when to stop. I'm using an SplQueue to represent the queue and keeping an int inside each ball that represents their order.
I believe the difficulty to be in traversing the $queue in the function hasTerminated(). The code runs, it just doesn't stop. An input of 30, for example (php script.php 30) should output 30 12 hour cycles to complete, but it does not terminate. I appreciate any and all ideas as to how to access the objects of the $queue and compare them without destroying the $queue. PHP is not a language I am very comfortable with.
<?php
class Ball {
static $counter = 0;
protected $index;
function __construct(){
$this->index = self::$counter;
self::$counter++;
}
function getIndex(){
return $this->index;
}
}
class Clock {
protected $queue;
protected $minuteTrack;
protected $fiveMinuteTrack;
protected $hourTrack;
protected $count;
protected $time = 0;
function __construct($num){
$this->queue = new \SplQueue;
$this->minuteTrack = new \SplStack;
$this->fiveMinuteTrack = new \SplStack;
$this->hourTrack = new \SplStack;
$this->count = $num;
for($i = 0; $i<$num; $i++){
$ball = new Ball();
$this->queue->enqueue($ball); //inefficient
}
}
function hasTerminated(){
$inOrder = true;
$prev = -1;
$q = clone $this->queue;
while($q->count() != 0){
$elt = $q->dequeue();
if($elt->getIndex() >= $prev){
$inOrder = false;
} else {
$prev = $elt->getIndex();
}
}
echo PHP_EOL;
if($inOrder){
echo 'It takes ' . $time . ' 12 hour cycles to return to the original ordering' . PHP_EOL;
exit(0);
} else {
echo 'Not finished yet' . PHP_EOL;
}
}
function run(){
while(true){
$ball = $this->queue->dequeue();
if(!$this->addBallToMinuteTrack($ball)){
if(!$this->addBallToFiveMinuteTrack($ball)){
if(!$this->addBallToHourTrack($ball)){
$this->queue->enqueue($ball);
}
}
}
}
}
function addBallToMinuteTrack($ball){
echo '1';
if($this->minuteTrack->count() < 4){
$this->minuteTrack->push($ball);
return true;
} else if( $this->minuteTrack->count() == 4){
for($i=0; $i<4; $i++){
$this->queue->enqueue($this->minuteTrack->pop()); //hate this
}
return false;
}
}
function addBallToFiveMinuteTrack($ball){
echo '5';
if($this->fiveMinuteTrack->count() < 11){
$this->fiveMinuteTrack->push($ball);
return true;
} else if( $this->fiveMinuteTrack->count() == 11){
for($i=0; $i<11; $i++){
$this->queue->enqueue($this->fiveMinuteTrack->pop());
}
return false;
}
}
function addBallToHourTrack($ball){
echo '60' . PHP_EOL;
if($this->hourTrack->count() < 11){
$this->hourTrack->push($ball);
return true;
} else if( $this->hourTrack->count() == 11){
for($i=0; $i<11; $i++){
$this->queue->enqueue($this->hourTrack->pop()); //hate this
}
$this->time = $this->time + 1; //In half day increments
$this->hasTerminated();
return false;
}
}
}
foreach (array_slice($argv, 1) as $arg) {
if(!is_numeric($arg)){
echo 'Arguments must be numeric' . PHP_EOL;
exit(1);
} else {
$clock = new Clock($arg);
$clock->run();
}
}
?>
I want to put the input like "RKKRRRRK" and try to get the output like largest continuous segment.. Suppose my input may be "RKKKR" then my program will display 'KKK' is the largest continuous segment.. and then it also display the count is 3..
I've already write the code for counting 'R' values.. now i want this program also... need help anyone help me.. thanks in advance.
Here the code:-
<?php
function numberOfR($string1)
{
for($i=0;$i <strlen($string1);$i++)
{
if($string1[$i]!='K')
{
$count++;
}
}
return $count;
}
$return_value= numberOfR("RKKRK");
echo "R's count is:";
echo $return_value;
?>
<?php
function getLongetSegment($string) {
$currentSegmentChar='';
$currentSegment="";
$biggestSegment="";
$current_length=0;
$biggest_length=0;
for($i=0;$i<strlen($string);$i++) {
$char = $string[$i];
if($char != $currentSegmentChar || $currentSegmentChar == '') {
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
$biggest_length = $current_length;
}
$currentSegmentChar = $char;
$currentSegment = $char;
$current_length = 1;
}
elseif($currentSegmentChar != '') {
$currentSegment .= $char;
$current_length++;
}
}
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
}
return array("string" => $biggestSegment,"length" => $biggest_length);
}
print_r(getLongetSegment("RKKRGGG"));
?>
Result: GGG
You can use preg_match_all over here as
preg_match_all('/(.)\1+/i','RKKRRRRK',$res);
usort($res[0],function($a,$b){
return strlen($b) - strlen($a);
});
echo $res[0][0];
Not sure if I understood this quite right. Something like this:
function maxCharSequece($string1)
{
$maxSeq = $seq = 0;
$maxChar = $lastChar = null;
for( $i = 0; $i < strlen($string1); $i++ )
{
$c = $string1[$i];
if (!$lastChar) $lastChar = $c;
if ( $lastChar == $c ){
if ( ++$seq > $maxSeq ) $maxChar = $lastChar;
}
else {
$maxSeq = $seq;
$seq = 0;
}
}
return $maxChar;
}
You can use preg_replace_callback to receive all continuous segments and select the longest
$sq = '';
preg_replace_callback('/(.)\1+/',
function ($i) use (&$sq) {
if(strlen($i[0]) > strlen($sq)) $sq = $i[0];
}, $str);
echo $sq . " " . strlen($sq);
I've created a memoized function of the recursive version of fibonacci.
I use this as an example for other kinds of functions that would use memoization.
My implementation is bad since if I include it in a library, that means that the global variable is still seen..
This is the original recursive fibonacci function:
function fibonacci($n) {
if($n > 1) {
return fibonacci($n-1) + fibonacci($n-2);
}
return $n;
}
and I modified it to a memoized version:
$memo = array();
function fibonacciMemo($n) {
global $memo;
if(array_key_exists($n, $memo)) {
return $memo[$n];
}
else {
if($n > 1) {
$result = fibonacciMemo($n-1) + fibonacciMemo($n-2);
$memo[$n] = $result;
return $result;
}
return $n;
}
}
I purposely didn't use the iterative method in implementing fibonacci.
Is there any better ways to memoize fibonacci function in php? Can you suggest me better improvements? I've seen func_get_args() and call_user_func_array as another way but I can't seem to know what is better?
So my main question is: How can I memoize fibonacci function in php properly? or What is the best way in memoizing fibonacci function in php?
Well, Edd Mann shows an excellent way to implement a memoize function in php in His post
Here is the example code (actually taken from Edd Mann's post):
$memoize = function($func)
{
return function() use ($func)
{
static $cache = [];
$args = func_get_args();
$key = md5(serialize($args));
if ( ! isset($cache[$key])) {
$cache[$key] = call_user_func_array($func, $args);
}
return $cache[$key];
};
};
$fibonacci = $memoize(function($n) use (&$fibonacci)
{
return ($n < 2) ? $n : $fibonacci($n - 1) + $fibonacci($n - 2);
});
Notice that the global definition it's replaced thanks to function clousure and PHP's first-class function support.
Other solution:
You can create a class containing as static members: fibonnacciMemo and $memo. Notice that you don't longer have to use $memo as a global variable, so it won't give any conflict with other namespaces.
Here is the example:
class Fib{
//$memo and fibonacciMemo are static members
static $memo = array();
static function fibonacciMemo($n) {
if(array_key_exists($n, static::$memo)) {
return static::$memo[$n];
}
else {
if($n > 1) {
$result = static::fibonacciMemo($n-1) + static::fibonacciMemo($n-2);
static::$memo[$n] = $result;
return $result;
}
return $n;
}
}
}
//Using the same method by Edd Mann to benchmark
//the results
$start = microtime(true);
Fib::fibonacciMemo(10);
echo sprintf("%f\n", microtime(true) - $start);
//outputs 0.000249
$start = microtime(true);
Fib::fibonacciMemo(10);
echo sprintf("%f\n", microtime(true) - $start);
//outputs 0.000016 (now with memoized fibonacci)
//Cleaning $memo
Fib::$memo = array();
$start = microtime(true);
Fib::fibonacciMemo(10);
echo sprintf("%f\n", microtime(true) - $start);
//outputs 0.000203 (after 'cleaning' $memo)
Using this, you avoid the use of global and also the problem of cleaning the cache. Althought, $memo is not thread save and the keys stored are no hashed values.
Anyways, you can use all the php memoize utilites such as memoize-php
i think... this should to to memoize a fibonacci:
function fib($n, &$computed = array(0,1)) {
if (!array_key_exists($n,$computed)) {
$computed[$n] = fib($n-1, $computed) + fib($n-2, $computed);
}
return $computed[$n];
}
some test
$arr = array(0,1);
$start = microtime(true);
fib(10,$arr);
echo sprintf("%f\n", microtime(true) - $start);
//0.000068
$start = microtime(true);
fib(10,$arr);
echo sprintf("%f\n", microtime(true) - $start);
//0.000005
//Cleaning $arr
$arr = array(0,1);
$start = microtime(true);
fib(10,$arr);
echo sprintf("%f\n", microtime(true) - $start);
//0.000039
Another solution:
function fib($n, &$memo = []) {
if (array_key_exists($n,$memo)) {
return $memo[$n];
}
if ($n <=2 ){
return 1;
}
$memo[$n] = fib($n-1, $memo) + fib($n-2, $memo);
return $memo[$n];
}
Performance:
$start = microtime(true);
fib(100);
echo sprintf("%f\n", microtime(true) - $start);
// 0.000041
This's an implementation of memoize a fibonacci:
function fib(int $n, array &$memo = [0,1,1]) : float {
return $memo[$n] ?? $memo[$n] = fib($n-1, $memo) + fib($n-2, $memo);
}
Call
echo fib(20); // 6765
function fibMemo($n)
{
static $cache = [];
//print_r($cache);
if (!empty($cache[$n])) {
return $cache[$n];
} else {
if ($n < 2) {
return $n;
} else {
$p = fibMemo($n - 1) + fibMemo($n - 2);
$cache[$n] = $p;
return $p;
}
}
}
echo fibMemo(250);
I have this PHP code which is supposed to increase a URL shortener mask on each new entry.
My problem is that it dosen't append a new char when it hits the last one (z).
(I know incrementing is a safety issue since you can guess earlier entries, but this is not a problem in this instance)
If i add 00, it can figure out 01 and so on... but is there a simple fix to why it won't do it on its own?
(The param is the last entry)
<?php
class shortener
{
public function ShortURL($str = null)
{
if (!is_null($str))
{
for($i = (strlen($str) - 1);$i >= 0;$i--)
{
if($str[$i] != 'Z')
{
$str[$i] = $this->_increase($str[$i]);
#var_dump($str[$i]);
break;
}
else
{
$str[$i] = '0';
if($i == 0)
{
$str = '0'.$str;
}
}
}
return $str;
}
else {
return '0';
}
}
private function _increase($letter)
{
//Lowercase: 97 - 122
//Uppercase: 65 - 90
// 0 - 9 : 48 - 57
$ord = ord($letter);
if($ord == 122)
{
$ord = 65;
}
elseif ($ord == 57)
{
$ord = 97;
}
else
{
$ord++;
}
return chr($ord);
}
}
?>
Effectively, all you are doing is encoding a number into Base62. So if we take the string, decode it into base 10, increment it, and reencode it into Base62, it will be much easier to know what we are doing, and the length of the string will take care of itself.
class shortener
{
public function ShortURL($str = null)
{
if ($str==null) return 0;
$int_val = $this->toBase10($str);
$int_val++;
return $this->toBase62($int_val);
}
public function toBase62($num, $b=62) {
$base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$r = $num % $b ;
$res = $base[$r];
$q = floor($num/$b);
while ($q) {
$r = $q % $b;
$q =floor($q/$b);
$res = $base[$r].$res;
}
return $res;
}
function toBase10( $num, $b=62) {
$base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$limit = strlen($num);
$res=strpos($base,$num[0]);
for($i=1;$i<$limit;$i++) {
$res = $b * $res + strpos($base,$num[$i]);
}
return $res;
}
}
I'm trying to do something like the following:
// assume $f is an arg to the wrapping function
$self = $this;
$func = function() use($f, $ctx, $self){
$self->remove($func, $ctx); // I want $func to be a reference to this anon function
$args = func_get_args();
call_user_func_array($f, $args);
};
Is it possible to reference the function assigned to $func from with the same function?
Try doing
$func = function() use (/*your variables,*/ &$func) {
var_dump($func);
return 1;
};
http://codepad.viper-7.com/cLd3Fu
Yes you can
See this example: http://php.net/manual/en/functions.anonymous.php#105564
Code from example:
<?php
$fib = function($n) use(&$fib) {
if($n == 0 || $n == 1) return 1;
return $fib($n - 1) + $fib($n - 2);
};
echo $fib(2) . "\n"; // 2
$lie = $fib;
$fib = function(){die('error');};//rewrite $fib variable
echo $lie(5); // error because $fib is referenced by closure
?>
Yes, it is possible if you use a variable by reference. For example:
$func = function($i) use(&$func) {
if ($i <= 0) {
return;
}
echo "Countdown: $i.\n";
$func($i - 1);
};
$func(3);