From abe7cfc13df0a80845793937ad7b02689116ba61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Votruba?= Date: Sun, 29 Oct 2017 19:14:38 +0100 Subject: [PATCH 01/15] composer: fix coding standard --- composer.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 44e2566..a7bedc7 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,5 @@ -{ "name": "mizan/phpds", +{ + "name": "mizan/phpds", "description": "PHP Data structures and algorithms", "license": "MIT", "keywords": [ @@ -8,15 +9,15 @@ "graph algorithm" ], "authors": [ - { - "name": "Mizanur Rahman", - "email": "mizanur.rahman@gmail.com" - } - ], + { + "name": "Mizanur Rahman", + "email": "mizanur.rahman@gmail.com" + } + ], "autoload": { "psr-4": { "DS\\": "DS/", "Algorithms\\":"Algorithms/" } } -} \ No newline at end of file +} From 6cbed1ed00f426d31385927632ee0b09247c6b40 Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Mon, 30 Oct 2017 03:52:10 +0600 Subject: [PATCH 02/15] PHP Big Integer Implementation - V1 --- Algorithms/Numbers-Maths/BigNumber.php | 285 +++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 Algorithms/Numbers-Maths/BigNumber.php diff --git a/Algorithms/Numbers-Maths/BigNumber.php b/Algorithms/Numbers-Maths/BigNumber.php new file mode 100644 index 0000000..5ac0a2b --- /dev/null +++ b/Algorithms/Numbers-Maths/BigNumber.php @@ -0,0 +1,285 @@ + + * + * Actual algorithm from: Steven Skiena + */ + + +define("MAXDIGITS", 1000); +define("PLUS", 1); +define("MINUS", -1); + + +class BigInteger +{ + + public $digits; + public $lastDigit; + public $signBit; + + public function __construct(string $number) + { + if (strlen($number) == 0) throw new Exception("Number must be present"); + + if (!preg_match("/(-)?(\d)*/", $number)) { + throw new Exception("Only valid digits are allowed"); + } + + $this->signBit = PLUS; + + if ($number[0] == "-") + $this->signBit = MINUS; + + for ($i = 0; $i < MAXDIGITS; $i++) $this->digits[$i] = 0; + + $this->lastDigit = -1; + + for ($t = strlen($number); $t > 0; $t--) { + $this->lastDigit++; + $this->digits[$this->lastDigit] = $number[$t - 1]; + } + + if ($number == "0") $this->lastDigit = 0; + } +} + +function printBigInteger(BigInteger &$n) +{ + if ($n->signBit == MINUS) echo "- "; + for ($i = $n->lastDigit; $i >= 0; $i--) + echo $n->digits[$i]; + echo "\n"; +} + +function intToBigInteger(string $s, BigInteger &$n) +{ + if ($s >= 0) + $n->signBit = PLUS; + else + $n->signBit = MINUS; + + for ($i = 0; $i < MAXDIGITS; $i++) $n->digits[$i] = 0; + + $n->lastDigit = -1; + + $t = abs($s); + + while ($t > 0) { + $n->lastDigit++; + $n->digits[$n->lastDigit] = ($t % 10); + $t /= 10; + } + + if ($s == 0) $n->lastDigit = 0; +} + +function initBigInteger(BigInteger &$n) +{ + intToBigInteger(0, $n); +} + +function zeroJustify(BigInteger &$n) +{ + while (($n->lastDigit > 0) && ($n->digits[$n->lastDigit] == 0)) + $n->lastDigit--; + + if (($n->lastDigit == 0) && ($n->digits[0] == 0)) + $n->signBit = PLUS; /* hack to avoid -0 */ +} + + +function digitShift(BigInteger $n, int $d) /* multiply n by 10^d */ +{ + if (($n->lastDigit == 0) && ($n->digits[0] == 0)) return; + + for ($i = $n->lastDigit; $i >= 0; $i--) + $n->digits[$i + $d] = $n->digits[$i]; + + for ($i = 0; $i < $d; $i++) $n->digits[$i] = 0; + + $n->lastDigit = $n->lastDigit + $d; +} + +function compareBigInteger(BigInteger &$a, BigInteger &$b) +{ + + if (($a->signBit == MINUS) && ($b->signBit == PLUS)) return (PLUS); + if (($a->signBit == PLUS) && ($b->signBit == MINUS)) return (MINUS); + + if ($b->lastDigit > $a->lastDigit) return (PLUS * $a->signBit); + if ($a->lastDigit > $b->lastDigit) return (MINUS * $a->signBit); + + for ($i = $a->lastDigit; $i >= 0; $i--) { + if ($a->digits[$i] > $b->digits[$i]) return (MINUS * $a->signBit); + if ($b->digits[$i] > $a->digits[$i]) return (PLUS * $a->signBit); + } + + return 0; +} + +function addBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) +{ + initBigInteger($c); + + if ($a->signBit == $b->signBit) + $c->signBit = $a->signBit; + else { + if ($a->signBit == MINUS) { + $a->signBit = PLUS; + subtractBigInteger($b, $a, $c); + $a->signBit = MINUS; + } else { + $b->signBit = PLUS; + subtractBigInteger($a, $b, $c); + $b->signBit = MINUS; + } + return; + } + + $c->lastDigit = max($a->lastDigit, $b->lastDigit) + 1; + $carry = 0; + + + for ($i = 0; $i <= $c->lastDigit; $i++) { + $c->digits[$i] = ($carry + $a->digits[$i] + $b->digits[$i]) % 10; + $carry = intval(($carry + $a->digits[$i] + $b->digits[$i]) / 10); + } + + zeroJustify($c); +} + +function subtractBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) +{ + initBigInteger($c); + + if (($a->signBit == MINUS) || ($b->signBit == MINUS)) { + $b->signBit = -1 * $b->signBit; + addBigInteger($a, $b, $c); + $b->signBit = -1 * $b->signBit; + return; + } + + if (compareBigInteger($a, $b) == PLUS) { + subtractBigInteger($b, $a, $c); + $c->signBit = MINUS; + return; + } + + $c->lastDigit = max($a->lastDigit, $b->lastDigit); + $borrow = 0; + + for ($i = 0; $i <= ($c->lastDigit); $i++) { + $v = ($a->digits[$i] - $borrow - $b->digits[$i]); + if ($a->digits[$i] > 0) + $borrow = 0; + if ($v < 0) { + $v = $v + 10; + $borrow = 1; + } + + $c->digits[$i] = $v % 10; + } + + zeroJustify($c); +} + + +function multiplyBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) +{ + $numbers = []; + for ($i = 0; $i <= $b->lastDigit; $i++) { + $carry = 0; + $tmp = clone $c; + $tmp->lastDigit = 0; + for ($j = 0; $j <= $a->lastDigit; $j++) { + $tmp->digits[$tmp->lastDigit++] = ($carry + $a->digits[$j] * $b->digits[$i]) % 10; + $carry = intval(($carry + $a->digits[$j] * $b->digits[$i]) / 10); + + } + if ($carry > 0) { + $tmp->digits[$tmp->lastDigit] = $carry; + } + + digitShift($tmp, $i); + zeroJustify($tmp); + $numbers[] = $tmp; + } + + foreach ($numbers as $number) { + $tmp = clone $c; + addBigInteger($number, $tmp, $c); + } + + $c->signBit = $a->signBit * $b->signBit; + + zeroJustify($c); +} + + +function divideBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) +{ + + $row = clone $c; + $tmp = clone $c; + + $c->signBit = $a->signBit * $b->signBit; + + $asign = $a->signBit; + $bsign = $b->signBit; + + $a->signBit = PLUS; + $b->signBit = PLUS; + + $c->lastDigit = $a->lastDigit; + + for ($i = $a->lastDigit; $i >= 0; $i--) { + digitShift($row, 1); + $row->digits[0] = $a->digits[$i]; + $c->digits[$i] = 0; + while (compareBigInteger($row, $b) != PLUS) { + $c->digits[$i]++; + subtractBigInteger($row, $b, $tmp); + $row = clone $tmp; + } + } + + zeroJustify($c); + + $a->signBit = $asign; + $b->signBit = $bsign; +} + +function factorial (int $n, BigInteger &$c) { + + intToBigInteger("1", $c); + + if($n > 0) { + for($i = 1;$i<=$n;$i++) { + $tmp = clone $c; + $number = new BigInteger($i); + $result = new BigInteger("0"); + multiplyBigInteger($number, $tmp, $result); + $c = $result; + } + } + zeroJustify($c); +} + + +$first = new BigInteger("12345678"); +$second = new BigInteger("2222"); +$result = new BigInteger("0"); + +printBigInteger($first); +printBigInteger($second); + +//divideBigInteger($first, $second, $result); +$start = microtime(false); +factorial(100, $result); +$end = microtime(false); +printBigInteger($result); + + + diff --git a/README.md b/README.md index fa3fe07..7c1a81e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PHP-Data-Structure-and-Algorithms +# PHP Data Structures and Algorithms Data structure and Algorithm is always important for any programming language. PHP, being one of the most popular language for web development, also requires the pure data structure and algorithm implementations. From cf40c71bdc5831f6c2f60763f6b2a6b544cc7744 Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Mon, 30 Oct 2017 15:44:17 +0600 Subject: [PATCH 03/15] PHP Big Integer Implementation - Add - Subtraction - Multiplication - Division - Factorial --- Algorithms/Numbers-Maths/BigNumber.php | 365 +++++++++++++------------ 1 file changed, 183 insertions(+), 182 deletions(-) diff --git a/Algorithms/Numbers-Maths/BigNumber.php b/Algorithms/Numbers-Maths/BigNumber.php index 5ac0a2b..48e7027 100644 --- a/Algorithms/Numbers-Maths/BigNumber.php +++ b/Algorithms/Numbers-Maths/BigNumber.php @@ -3,14 +3,10 @@ /* * Author: Mizanur rahman * - * Actual algorithm from: Steven Skiena + * Inspired from algorithm by Steven Skiena */ -define("MAXDIGITS", 1000); -define("PLUS", 1); -define("MINUS", -1); - class BigInteger { @@ -19,6 +15,10 @@ class BigInteger public $lastDigit; public $signBit; + const MAXDIGITS = 10000; + const PLUS = 1; + const MINUS = -1; + public function __construct(string $number) { if (strlen($number) == 0) throw new Exception("Number must be present"); @@ -27,12 +27,12 @@ public function __construct(string $number) throw new Exception("Only valid digits are allowed"); } - $this->signBit = PLUS; + $this->signBit = BigInteger::PLUS; if ($number[0] == "-") - $this->signBit = MINUS; + $this->signBit = BigInteger::MINUS; - for ($i = 0; $i < MAXDIGITS; $i++) $this->digits[$i] = 0; + for ($i = 0; $i < BigInteger::MAXDIGITS; $i++) $this->digits[$i] = 0; $this->lastDigit = -1; @@ -43,243 +43,244 @@ public function __construct(string $number) if ($number == "0") $this->lastDigit = 0; } -} - -function printBigInteger(BigInteger &$n) -{ - if ($n->signBit == MINUS) echo "- "; - for ($i = $n->lastDigit; $i >= 0; $i--) - echo $n->digits[$i]; - echo "\n"; -} -function intToBigInteger(string $s, BigInteger &$n) -{ - if ($s >= 0) - $n->signBit = PLUS; - else - $n->signBit = MINUS; + public static function print(BigInteger &$n) { + if ($n->signBit == BigInteger::MINUS) echo "- "; + for ($i = $n->lastDigit; $i >= 0; $i--) + echo $n->digits[$i]; + echo "\n"; + } - for ($i = 0; $i < MAXDIGITS; $i++) $n->digits[$i] = 0; + public static function toBigInteger(string $s, BigInteger &$n) + { + if ($s >= 0) + $n->signBit = BigInteger::PLUS; + else + $n->signBit = BigInteger::MINUS; - $n->lastDigit = -1; + for ($i = 0; $i < BigInteger::MAXDIGITS; $i++) $n->digits[$i] = 0; - $t = abs($s); + $n->lastDigit = -1; - while ($t > 0) { - $n->lastDigit++; - $n->digits[$n->lastDigit] = ($t % 10); - $t /= 10; - } + $t = abs($s); - if ($s == 0) $n->lastDigit = 0; -} + while ($t > 0) { + $n->lastDigit++; + $n->digits[$n->lastDigit] = ($t % 10); + $t /= 10; + } -function initBigInteger(BigInteger &$n) -{ - intToBigInteger(0, $n); -} + if ($s == 0) $n->lastDigit = 0; + } -function zeroJustify(BigInteger &$n) -{ - while (($n->lastDigit > 0) && ($n->digits[$n->lastDigit] == 0)) - $n->lastDigit--; + public static function zeroJustify(BigInteger &$n) + { + while (($n->lastDigit > 0) && ($n->digits[$n->lastDigit] == 0)) + $n->lastDigit--; - if (($n->lastDigit == 0) && ($n->digits[0] == 0)) - $n->signBit = PLUS; /* hack to avoid -0 */ -} + if (($n->lastDigit == 0) && ($n->digits[0] == 0)) + $n->signBit = BigInteger::PLUS; + } + public static function shift(BigInteger $n, int $d) /* multiply n by 10^d */ + { + if (($n->lastDigit == 0) && ($n->digits[0] == 0)) return; -function digitShift(BigInteger $n, int $d) /* multiply n by 10^d */ -{ - if (($n->lastDigit == 0) && ($n->digits[0] == 0)) return; + for ($i = $n->lastDigit; $i >= 0; $i--) + $n->digits[$i + $d] = $n->digits[$i]; - for ($i = $n->lastDigit; $i >= 0; $i--) - $n->digits[$i + $d] = $n->digits[$i]; + for ($i = 0; $i < $d; $i++) $n->digits[$i] = 0; - for ($i = 0; $i < $d; $i++) $n->digits[$i] = 0; + $n->lastDigit = $n->lastDigit + $d; + } - $n->lastDigit = $n->lastDigit + $d; -} + public static function compare(BigInteger &$a, BigInteger &$b) + { -function compareBigInteger(BigInteger &$a, BigInteger &$b) -{ + if (($a->signBit == BigInteger::MINUS) && ($b->signBit == BigInteger::PLUS)) return (BigInteger::PLUS); + if (($a->signBit == BigInteger::PLUS) && ($b->signBit == BigInteger::MINUS)) return (BigInteger::MINUS); - if (($a->signBit == MINUS) && ($b->signBit == PLUS)) return (PLUS); - if (($a->signBit == PLUS) && ($b->signBit == MINUS)) return (MINUS); + if ($b->lastDigit > $a->lastDigit) return (BigInteger::PLUS * $a->signBit); + if ($a->lastDigit > $b->lastDigit) return (BigInteger::MINUS * $a->signBit); - if ($b->lastDigit > $a->lastDigit) return (PLUS * $a->signBit); - if ($a->lastDigit > $b->lastDigit) return (MINUS * $a->signBit); + for ($i = $a->lastDigit; $i >= 0; $i--) { + if ($a->digits[$i] > $b->digits[$i]) return (BigInteger::MINUS * $a->signBit); + if ($b->digits[$i] > $a->digits[$i]) return (BigInteger::PLUS * $a->signBit); + } - for ($i = $a->lastDigit; $i >= 0; $i--) { - if ($a->digits[$i] > $b->digits[$i]) return (MINUS * $a->signBit); - if ($b->digits[$i] > $a->digits[$i]) return (PLUS * $a->signBit); + return 0; } - return 0; -} + public static function add(BigInteger &$a, BigInteger &$b, BigInteger &$c) + { -function addBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) -{ - initBigInteger($c); - - if ($a->signBit == $b->signBit) - $c->signBit = $a->signBit; - else { - if ($a->signBit == MINUS) { - $a->signBit = PLUS; - subtractBigInteger($b, $a, $c); - $a->signBit = MINUS; - } else { - $b->signBit = PLUS; - subtractBigInteger($a, $b, $c); - $b->signBit = MINUS; + if ($a->signBit == $b->signBit) + $c->signBit = $a->signBit; + else { + if ($a->signBit == BigInteger::MINUS) { + $a->signBit = BigInteger::PLUS; + BigInteger::subtract($b, $a, $c); + $a->signBit = BigInteger::MINUS; + } else { + $b->signBit = BigInteger::PLUS; + BigInteger::subtract($a, $b, $c); + $b->signBit = BigInteger::MINUS; + } + return; } - return; - } - - $c->lastDigit = max($a->lastDigit, $b->lastDigit) + 1; - $carry = 0; + $c->lastDigit = max($a->lastDigit, $b->lastDigit) + 1; + $carry = 0; - for ($i = 0; $i <= $c->lastDigit; $i++) { - $c->digits[$i] = ($carry + $a->digits[$i] + $b->digits[$i]) % 10; - $carry = intval(($carry + $a->digits[$i] + $b->digits[$i]) / 10); - } - zeroJustify($c); -} + for ($i = 0; $i <= $c->lastDigit; $i++) { + $c->digits[$i] = ($carry + $a->digits[$i] + $b->digits[$i]) % 10; + $carry = intval(($carry + $a->digits[$i] + $b->digits[$i]) / 10); + } -function subtractBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) -{ - initBigInteger($c); + BigInteger::zeroJustify($c); - if (($a->signBit == MINUS) || ($b->signBit == MINUS)) { - $b->signBit = -1 * $b->signBit; - addBigInteger($a, $b, $c); - $b->signBit = -1 * $b->signBit; - return; } - if (compareBigInteger($a, $b) == PLUS) { - subtractBigInteger($b, $a, $c); - $c->signBit = MINUS; - return; - } + public static function subtract(BigInteger &$a, BigInteger &$b, BigInteger &$c) + { - $c->lastDigit = max($a->lastDigit, $b->lastDigit); - $borrow = 0; - for ($i = 0; $i <= ($c->lastDigit); $i++) { - $v = ($a->digits[$i] - $borrow - $b->digits[$i]); - if ($a->digits[$i] > 0) - $borrow = 0; - if ($v < 0) { - $v = $v + 10; - $borrow = 1; + if (($a->signBit == BigInteger::MINUS) || ($b->signBit == BigInteger::MINUS)) { + $b->signBit = -1 * $b->signBit; + BigInteger::add($a, $b, $c); + $b->signBit = -1 * $b->signBit; + return; } - $c->digits[$i] = $v % 10; - } + if (BigInteger::compare($a, $b) == BigInteger::PLUS) { + BigInteger::subtract($b, $a, $c); + $c->signBit = BigInteger::MINUS; + return; + } - zeroJustify($c); -} + $c->lastDigit = max($a->lastDigit, $b->lastDigit); + $borrow = 0; + for ($i = 0; $i <= ($c->lastDigit); $i++) { + $v = ($a->digits[$i] - $borrow - $b->digits[$i]); + if ($a->digits[$i] > 0) + $borrow = 0; + if ($v < 0) { + $v = $v + 10; + $borrow = 1; + } -function multiplyBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) -{ - $numbers = []; - for ($i = 0; $i <= $b->lastDigit; $i++) { - $carry = 0; - $tmp = clone $c; - $tmp->lastDigit = 0; - for ($j = 0; $j <= $a->lastDigit; $j++) { - $tmp->digits[$tmp->lastDigit++] = ($carry + $a->digits[$j] * $b->digits[$i]) % 10; - $carry = intval(($carry + $a->digits[$j] * $b->digits[$i]) / 10); + $c->digits[$i] = $v % 10; + } + + BigInteger::zeroJustify($c); + } + public static function multiply(BigInteger &$a, BigInteger &$b, BigInteger &$c) + { + $numbers = []; + for ($i = 0; $i <= $b->lastDigit; $i++) { + $carry = 0; + $tmp = clone $c; + $tmp->lastDigit = 0; + for ($j = 0; $j <= $a->lastDigit; $j++) { + $tmp->digits[$tmp->lastDigit++] = ($carry + $a->digits[$j] * $b->digits[$i]) % 10; + $carry = intval(($carry + $a->digits[$j] * $b->digits[$i]) / 10); + + } + if ($carry > 0) { + $tmp->digits[$tmp->lastDigit] = $carry; + } + + BigInteger::shift($tmp, $i); + BigInteger::zeroJustify($tmp); + $numbers[] = $tmp; } - if ($carry > 0) { - $tmp->digits[$tmp->lastDigit] = $carry; + + foreach ($numbers as $number) { + $tmp = clone $c; + BigInteger::add($number, $tmp, $c); } - digitShift($tmp, $i); - zeroJustify($tmp); - $numbers[] = $tmp; - } + $c->signBit = $a->signBit * $b->signBit; - foreach ($numbers as $number) { - $tmp = clone $c; - addBigInteger($number, $tmp, $c); + BigInteger::zeroJustify($c); } - $c->signBit = $a->signBit * $b->signBit; - zeroJustify($c); -} + public static function divide(BigInteger &$a, BigInteger &$b, BigInteger &$c) + { + $row = clone $c; + $tmp = clone $c; -function divideBigInteger(BigInteger &$a, BigInteger &$b, BigInteger &$c) -{ + $c->signBit = $a->signBit * $b->signBit; - $row = clone $c; - $tmp = clone $c; + $asign = $a->signBit; + $bsign = $b->signBit; - $c->signBit = $a->signBit * $b->signBit; + $a->signBit = BigInteger::PLUS; + $b->signBit = BigInteger::PLUS; - $asign = $a->signBit; - $bsign = $b->signBit; + $c->lastDigit = $a->lastDigit; - $a->signBit = PLUS; - $b->signBit = PLUS; + for ($i = $a->lastDigit; $i >= 0; $i--) { + BigInteger::shift($row, 1); + $row->digits[0] = $a->digits[$i]; + $c->digits[$i] = 0; + while (BigInteger::compare($row, $b) != BigInteger::PLUS) { + $c->digits[$i]++; + BigInteger::subtract($row, $b, $tmp); + $row = clone $tmp; + } + } - $c->lastDigit = $a->lastDigit; + BigInteger::zeroJustify($c); - for ($i = $a->lastDigit; $i >= 0; $i--) { - digitShift($row, 1); - $row->digits[0] = $a->digits[$i]; - $c->digits[$i] = 0; - while (compareBigInteger($row, $b) != PLUS) { - $c->digits[$i]++; - subtractBigInteger($row, $b, $tmp); - $row = clone $tmp; - } + $a->signBit = $asign; + $b->signBit = $bsign; } - zeroJustify($c); - - $a->signBit = $asign; - $b->signBit = $bsign; -} + public static function factorial (int $n, BigInteger &$c) { -function factorial (int $n, BigInteger &$c) { + BigInteger::toBigInteger("1", $c); - intToBigInteger("1", $c); - - if($n > 0) { - for($i = 1;$i<=$n;$i++) { - $tmp = clone $c; - $number = new BigInteger($i); - $result = new BigInteger("0"); - multiplyBigInteger($number, $tmp, $result); - $c = $result; + if($n > 0) { + for($i = 1;$i<=$n;$i++) { + $tmp = clone $c; + $number = new BigInteger($i); + $result = new BigInteger("0"); + BigInteger::multiply($number, $tmp, $result); + $c = $result; + } } + BigInteger::zeroJustify($c); } - zeroJustify($c); + } -$first = new BigInteger("12345678"); -$second = new BigInteger("2222"); -$result = new BigInteger("0"); -printBigInteger($first); -printBigInteger($second); +$first = new BigInteger("1234567812345678123456781234567812345678"); +$second = new BigInteger("12345678123456781234567812345678"); +$sum = new BigInteger("0"); + +BigInteger::add($first, $second, $sum); +BigInteger::print($sum); -//divideBigInteger($first, $second, $result); -$start = microtime(false); -factorial(100, $result); -$end = microtime(false); -printBigInteger($result); +$diff = new BigInteger("0"); +BigInteger::subtract($first, $second, $diff); +BigInteger::print($diff); +$multiply = new BigInteger("0"); +BigInteger::multiply($first, $second, $multiply); +BigInteger::print($multiply); +$divide = new BigInteger("0"); +BigInteger::divide($first, $second, $divide); +BigInteger::print($divide); +$factorial = new BigInteger("0"); +BigInteger::factorial(100, $factorial); +BigInteger::print($factorial); \ No newline at end of file From 34f71dd2027644cf8bbb0759319579456ba28f6e Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Mon, 30 Oct 2017 15:45:49 +0600 Subject: [PATCH 04/15] PHP Big Integer Implementation - Add - Subtraction - Multiplication - Division - Factorial --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7c1a81e..b833dfd 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Any feedback, bugs or suggestion will be welcomed. - Min Heap - Max Heap -5. Graph +6. Graph - BFS - Bellman Ford Algorithm - DFS @@ -45,7 +45,7 @@ Any feedback, bugs or suggestion will be welcomed. - Prim Minimum Spanning tree - Topological Sorting -6. Sorting +7. Sorting - Bubble sort - Bubble Sort with improvements - Bucket sort @@ -56,7 +56,7 @@ Any feedback, bugs or suggestion will be welcomed. - Radix Sort - Selection Sort -7. Searching +8. Searching - BFS - Binary Search (Iterative) - Binary Search (Recursive) @@ -66,7 +66,7 @@ Any feedback, bugs or suggestion will be welcomed. - Interpolation Search - Repetitive Binary Search -8. Dynamic Programming and Others +9. Dynamic Programming and Others - Sudoku (Backtracking) - Collaborative Filtering - DNA Sequencing (NeedlemanWunsch Algorithm) @@ -79,6 +79,9 @@ Any feedback, bugs or suggestion will be welcomed. - Longest Common Subsequences (LCS) - Pattern Matching - Sparse Array + + 10. Numbers and Maths + - PHP Big Integer Implementation I know lots of things are missing in the list? Would you mind to let me know what you wanna see implemented? I will priortize those and add here. @@ -86,7 +89,6 @@ I know lots of things are missing in the list? Would you mind to let me know wha # Coming Soon # -- Big Number implementation using PHP - Prime number generation - AVL tree implemenations - Project Euler Solutions in PHP for Hackerrank.com From 201eed4312d27b30cd002b80e93506196c4c5175 Mon Sep 17 00:00:00 2001 From: Mizanur Rahman Date: Mon, 30 Oct 2017 15:48:40 +0600 Subject: [PATCH 05/15] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..14488c0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Mizanur Rahman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From cdbeae3b0e3f822f8adc78869e7f053c7b5bff46 Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Mon, 30 Oct 2017 23:27:26 +0600 Subject: [PATCH 06/15] PHP Big Integer Implementation - Power Prime number generation - Sieve --- Algorithms/Numbers-Maths/BigNumber.php | 33 +++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/Algorithms/Numbers-Maths/BigNumber.php b/Algorithms/Numbers-Maths/BigNumber.php index 48e7027..6129067 100644 --- a/Algorithms/Numbers-Maths/BigNumber.php +++ b/Algorithms/Numbers-Maths/BigNumber.php @@ -7,7 +7,6 @@ */ - class BigInteger { @@ -44,7 +43,8 @@ public function __construct(string $number) if ($number == "0") $this->lastDigit = 0; } - public static function print(BigInteger &$n) { + public static function print(BigInteger &$n) + { if ($n->signBit == BigInteger::MINUS) echo "- "; for ($i = $n->lastDigit; $i >= 0; $i--) echo $n->digits[$i]; @@ -242,12 +242,13 @@ public static function divide(BigInteger &$a, BigInteger &$b, BigInteger &$c) $b->signBit = $bsign; } - public static function factorial (int $n, BigInteger &$c) { + public static function factorial(int $n, BigInteger &$c) + { BigInteger::toBigInteger("1", $c); - if($n > 0) { - for($i = 1;$i<=$n;$i++) { + if ($n > 0) { + for ($i = 1; $i <= $n; $i++) { $tmp = clone $c; $number = new BigInteger($i); $result = new BigInteger("0"); @@ -258,8 +259,23 @@ public static function factorial (int $n, BigInteger &$c) { BigInteger::zeroJustify($c); } -} + public static function power(BigInteger &$a, int $n, BigInteger &$c) + { + BigInteger::toBigInteger("1", $c); + + if ($n > 0) { + for ($i = 0; $i < $n; $i++) { + $tmp = clone $c; + $result = new BigInteger("0"); + BigInteger::multiply($a, $tmp, $result); + $c = $result; + } + } + BigInteger::zeroJustify($c); + } + +} $first = new BigInteger("1234567812345678123456781234567812345678"); @@ -281,6 +297,11 @@ public static function factorial (int $n, BigInteger &$c) { BigInteger::divide($first, $second, $divide); BigInteger::print($divide); +$number = new BigInteger("55"); +$power = new BigInteger("0"); +BigInteger::power($number, 5, $power); +BigInteger::print($power); + $factorial = new BigInteger("0"); BigInteger::factorial(100, $factorial); BigInteger::print($factorial); \ No newline at end of file From f132a5e9ba7c49756384b51fafb4b38b541bc61c Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Tue, 31 Oct 2017 00:13:39 +0600 Subject: [PATCH 07/15] updating the list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b833dfd..45417a4 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Any feedback, bugs or suggestion will be welcomed. 10. Numbers and Maths - PHP Big Integer Implementation + - Prime number generation - Sieve I know lots of things are missing in the list? Would you mind to let me know what you wanna see implemented? I will priortize those and add here. @@ -89,7 +90,6 @@ I know lots of things are missing in the list? Would you mind to let me know wha # Coming Soon # -- Prime number generation - AVL tree implemenations - Project Euler Solutions in PHP for Hackerrank.com - More algorithms \ No newline at end of file From 8002426a8f102e8191c5938722448fb8df9dd878 Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Wed, 1 Nov 2017 17:31:32 +0600 Subject: [PATCH 08/15] Fixing naming convention Hacker rank repository added. --- Algorithms/Graph/Dijkstra.php | 4 +- Algorithms/Graph/Kruskal.php | 4 +- Algorithms/Numbers-Maths/Sieve.php | 29 +++++ .../BacktrackingSudoku.php | 22 ++-- .../Recursion-DP-Others/DNASequencing.php | 4 +- .../Recursion-DP-Others/KMPMatching.php | 8 +- DS/Heap/Classes/MinHeap.php | 113 ++++++++++-------- HackerRank/Euler/12.php | 63 ++++++++++ HackerRank/Euler/2.php | 46 +++++++ HackerRank/Euler/21.php | 64 ++++++++++ HackerRank/Euler/23.php | 68 +++++++++++ HackerRank/Euler/34.php | 33 +++++ HackerRank/Euler/35.php | 64 ++++++++++ HackerRank/Euler/36.php | 26 ++++ HackerRank/Euler/37.php | 84 +++++++++++++ 15 files changed, 559 insertions(+), 73 deletions(-) create mode 100644 Algorithms/Numbers-Maths/Sieve.php create mode 100644 HackerRank/Euler/12.php create mode 100644 HackerRank/Euler/2.php create mode 100644 HackerRank/Euler/21.php create mode 100644 HackerRank/Euler/23.php create mode 100644 HackerRank/Euler/34.php create mode 100644 HackerRank/Euler/35.php create mode 100644 HackerRank/Euler/36.php create mode 100644 HackerRank/Euler/37.php diff --git a/Algorithms/Graph/Dijkstra.php b/Algorithms/Graph/Dijkstra.php index 13ca987..77b3dbc 100644 --- a/Algorithms/Graph/Dijkstra.php +++ b/Algorithms/Graph/Dijkstra.php @@ -5,7 +5,7 @@ * */ -function Dijkstra(array $graph, string $source, string $target): array { +function dijkstra(array $graph, string $source, string $target): array { $dist = []; $pred = []; $Queue = new SplPriorityQueue(); @@ -60,7 +60,7 @@ function Dijkstra(array $graph, string $source, string $target): array { $source = "A"; $target = "F"; -$result = Dijkstra($graph, $source, $target); +$result = dijkstra($graph, $source, $target); extract($result); echo "Distance from $source to $target is $distance \n"; diff --git a/Algorithms/Graph/Kruskal.php b/Algorithms/Graph/Kruskal.php index 5c45187..335bc9a 100644 --- a/Algorithms/Graph/Kruskal.php +++ b/Algorithms/Graph/Kruskal.php @@ -7,7 +7,7 @@ * */ -function Kruskal(array $graph): array { +function kruskal(array $graph): array { $len = count($graph); $tree = []; @@ -67,7 +67,7 @@ function unionSet(array &$set, int $i, int $j) { [0, 0, 4, 2, 6, 0] ]; -$mst = Kruskal($graph); +$mst = kruskal($graph); $minimumCost = 0; diff --git a/Algorithms/Numbers-Maths/Sieve.php b/Algorithms/Numbers-Maths/Sieve.php new file mode 100644 index 0000000..5324392 --- /dev/null +++ b/Algorithms/Numbers-Maths/Sieve.php @@ -0,0 +1,29 @@ + + * + */ + +function sieveOfEratosthenes(int $n) +{ + + $prime = array_fill(0, $n + 1, true); + + for ($p = 2; $p * $p <= $n; $p++) { + // If prime[p] is not changed, then it is a prime + if (isset($prime[$p]) && $prime[$p] == true) { + // Update all multiples of p + for ($i = $p * 2; $i <= $n; $i += $p) + $prime[$i] = false; + } + } + + // Print all prime numbers + for ($p = 2; $p <= $n; $p++) + if ($prime[$p]) + echo $p . " "; +} + + +sieveOfEratosthenes(5000000); \ No newline at end of file diff --git a/Algorithms/Recursion-DP-Others/BacktrackingSudoku.php b/Algorithms/Recursion-DP-Others/BacktrackingSudoku.php index cece398..a86dd9c 100644 --- a/Algorithms/Recursion-DP-Others/BacktrackingSudoku.php +++ b/Algorithms/Recursion-DP-Others/BacktrackingSudoku.php @@ -9,17 +9,17 @@ define("N", 9); define("UNASSIGNED", 0); -function SolveSudoku(array &$grid): bool { +function solveSudoku(array &$grid): bool { $row = $col = 0; - if (!FindUnassignedLocation($grid, $row, $col)) + if (!findUnassignedLocation($grid, $row, $col)) return true; // success! no empty space for ($num = 1; $num <= N; $num++) { if (isSafe($grid, $row, $col, $num)) { $grid[$row][$col] = $num; // make tentative assignment - if (SolveSudoku($grid)) + if (solveSudoku($grid)) return true; // return, if success// return, if success $grid[$row][$col] = UNASSIGNED; // failure, unmake & try again @@ -28,7 +28,7 @@ function SolveSudoku(array &$grid): bool { return false; // triggers backtracking } -function FindUnassignedLocation(array &$grid, int &$row, int &$col): bool { +function findUnassignedLocation(array &$grid, int &$row, int &$col): bool { for ($row = 0; $row < N; $row++) for ($col = 0; $col < N; $col++) if ($grid[$row][$col] == UNASSIGNED) @@ -36,15 +36,15 @@ function FindUnassignedLocation(array &$grid, int &$row, int &$col): bool { return false; } -function UsedInRow(array &$grid, int $row, int $num): bool { +function usedInRow(array &$grid, int $row, int $num): bool { return in_array($num, $grid[$row]); } -function UsedInColumn(array &$grid, int $col, int $num): bool { +function usedInColumn(array &$grid, int $col, int $num): bool { return in_array($num, array_column($grid, $col)); } -function UsedInBox(array &$grid, int $boxStartRow, int $boxStartCol, int $num):bool { +function usedInBox(array &$grid, int $boxStartRow, int $boxStartCol, int $num):bool { for ($row = 0; $row < 3; $row++) for ($col = 0; $col < 3; $col++) if ($grid[$row + $boxStartRow][$col + $boxStartCol] == $num) @@ -54,9 +54,9 @@ function UsedInBox(array &$grid, int $boxStartRow, int $boxStartCol, int $num):b function isSafe(array $grid, int $row, int $col, int $num): bool { - return !UsedInRow($grid, $row, $num) && - !UsedInColumn($grid, $col, $num) && - !UsedInBox($grid, $row - $row % 3, $col - $col % 3, $num); + return !usedInRow($grid, $row, $num) && + !usedInColumn($grid, $col, $num) && + !usedInBox($grid, $row - $row % 3, $col - $col % 3, $num); } /* A utility function to print grid */ @@ -80,7 +80,7 @@ function printGrid(array $grid) { [0, 0, 2, 0, 9, 0, 5, 0, 0] ]; -if (SolveSudoku($grid) == true) +if (solveSudoku($grid) == true) printGrid($grid); else echo "No solution exists"; \ No newline at end of file diff --git a/Algorithms/Recursion-DP-Others/DNASequencing.php b/Algorithms/Recursion-DP-Others/DNASequencing.php index b6f77eb..1d9b776 100644 --- a/Algorithms/Recursion-DP-Others/DNASequencing.php +++ b/Algorithms/Recursion-DP-Others/DNASequencing.php @@ -11,7 +11,7 @@ define("GP", -1); define("MS", -1); -function NWSquencing(string $s1, string $s2) { +function nwSquencing(string $s1, string $s2) { $grid = []; $M = strlen($s1); $N = strlen($s2); @@ -89,4 +89,4 @@ function printSequence($grid, $s1, $s2, $j, $i) { $X = "GAATTCAGTTA"; $Y = "GGATCGA"; -NWSquencing($X, $Y); +nwSquencing($X, $Y); diff --git a/Algorithms/Recursion-DP-Others/KMPMatching.php b/Algorithms/Recursion-DP-Others/KMPMatching.php index 09b1113..71cabd0 100644 --- a/Algorithms/Recursion-DP-Others/KMPMatching.php +++ b/Algorithms/Recursion-DP-Others/KMPMatching.php @@ -5,14 +5,14 @@ * */ -function KMPStringMatching(string $str, string $pattern): array { +function kmpStringMatching(string $str, string $pattern): array { $matches = []; $M = strlen($pattern); $N = strlen($str); $i = $j = 0; $lps = []; - ComputeLPS($pattern, $lps); + computeLPS($pattern, $lps); while ($i < $N) { if ($pattern[$j] == $str[$i]) { @@ -33,7 +33,7 @@ function KMPStringMatching(string $str, string $pattern): array { return $matches; } -function ComputeLPS(string $pattern, array &$lps) { +function computeLPS(string $pattern, array &$lps) { $len = 0; $i = 1; $M = strlen($pattern); @@ -58,7 +58,7 @@ function ComputeLPS(string $pattern, array &$lps) { $txt = "AABAACAADAABABBBAABAA"; $pattern = "AABA"; -$matches = KMPStringMatching($txt, $pattern); +$matches = kmpStringMatching($txt, $pattern); if ($matches) { foreach ($matches as $pos) { diff --git a/DS/Heap/Classes/MinHeap.php b/DS/Heap/Classes/MinHeap.php index 3c62795..26d82bd 100644 --- a/DS/Heap/Classes/MinHeap.php +++ b/DS/Heap/Classes/MinHeap.php @@ -7,77 +7,86 @@ namespace DS\Heap\Classes; -class MinHeap { +class MinHeap +{ public $heap; public $count; - public function __construct(int $size) { - $this->heap = array_fill(0, $size + 1, 0); - $this->count = 0; + public function __construct(int $size) + { + $this->heap = array_fill(0, $size + 1, 0); + $this->count = 0; } - public function create(array $arr = []) { - if ($arr) { - foreach ($arr as $val) { - $this->insert($val); - } - } + public function create(array $arr = []) + { + if ($arr) { + foreach ($arr as $val) { + $this->insert($val); + } + } } - public function display() { - echo implode("\t", array_slice($this->heap, 1)) . "\n"; + public function display() + { + echo implode("\t", array_slice($this->heap, 1)) . "\n"; } - public function insert(int $i) { - if ($this->count == 0) { - $this->heap[1] = $i; - $this->count = 2; - } else { - $this->heap[$this->count++] = $i; - $this->siftUp(); - } + public function insert(int $i) + { + if ($this->count == 0) { + $this->heap[1] = $i; + $this->count = 2; + } else { + $this->heap[$this->count++] = $i; + $this->siftUp(); + } } - public function siftUp() { - $tmpPos = $this->count - 1; - $tmp = intval($tmpPos / 2); + public function siftUp() + { + $tmpPos = $this->count - 1; + $tmp = intval($tmpPos / 2); - while ($tmpPos > 0 && $this->heap[$tmp] > $this->heap[$tmpPos]) { - $this->swap($tmpPos, $tmp); - $tmpPos = intval($tmpPos / 2); - $tmp = intval($tmpPos / 2); - } + while ($tmpPos > 0 && $this->heap[$tmp] > $this->heap[$tmpPos]) { + $this->swap($tmpPos, $tmp); + $tmpPos = intval($tmpPos / 2); + $tmp = intval($tmpPos / 2); + } } - public function swap(int $a, int $b) { - $tmp = $this->heap[$a]; - $this->heap[$a] = $this->heap[$b]; - $this->heap[$b] = $tmp; + public function swap(int $a, int $b) + { + $tmp = $this->heap[$a]; + $this->heap[$a] = $this->heap[$b]; + $this->heap[$b] = $tmp; } - public function extractMin() { - $min = $this->heap[1]; - $this->heap[1] = $this->heap[$this->count - 1]; - $this->heap[--$this->count] = 0; - $this->siftDown(1); - return $min; + public function extractMin() + { + $min = $this->heap[1]; + $this->heap[1] = $this->heap[$this->count - 1]; + $this->heap[--$this->count] = 0; + $this->siftDown(1); + return $min; } - public function siftDown(int $k) { - $smallest = $k; - $left = 2 * $k; - $right = 2 * $k + 1; - if ($left < $this->count && $this->heap[$smallest] > $this->heap[$left]) { - $smallest = $left; - } - if ($right < $this->count && $this->heap[$smallest] > $this->heap[$right]) { - $smallest = $right; - } - if ($smallest != $k) { - $this->swap($k, $smallest); - $this->siftDown($smallest); - } + public function siftDown(int $k) + { + $smallest = $k; + $left = 2 * $k; + $right = 2 * $k + 1; + if ($left < $this->count && $this->heap[$smallest] > $this->heap[$left]) { + $smallest = $left; + } + if ($right < $this->count && $this->heap[$smallest] > $this->heap[$right]) { + $smallest = $right; + } + if ($smallest != $k) { + $this->swap($k, $smallest); + $this->siftDown($smallest); + } } } \ No newline at end of file diff --git a/HackerRank/Euler/12.php b/HackerRank/Euler/12.php new file mode 100644 index 0000000..df70f4a --- /dev/null +++ b/HackerRank/Euler/12.php @@ -0,0 +1,63 @@ + + * + * Project Euler #12: Highly divisible triangular number + */ + +$triangleNumbers = []; + +function numberOfDivisors($triangle) { + + global $triangleNumbers; + + if (isset($triangleNumbers[$triangle])) { + return $triangleNumbers[$triangle]; + } else { + $tempTriangle = $triangle; + $primePowerCount = 1; + $count = 0; + while ($triangle % 2 == 0) { + $triangle =floor($triangle/ 2); + $count += 1; + } + $primePowerCount *= ($count + 1); + for ($i = 3; $i <= intval(sqrt($triangle)); $i++) { + $count = 0; + while ($triangle % $i == 0) { + $count += 1; + $triangle = floor($triangle/$i); + } + $primePowerCount *= ($count + 1); + } + if ($triangle > 2) { + $primePowerCount *= 2; + } + $triangleNumbers[$tempTriangle] = $primePowerCount; + return $triangleNumbers[$tempTriangle]; + } +} + +function getTriangle($number) { + return floor($number * ($number + 1)/ 2); +} + + +$handle = fopen ("php://stdin","r"); +$t = fgets($handle); +for($i=0; $i<$t; $i++) { + + $n = trim(fgets($handle)); + $number = 1; + $triangle = getTriangle($number); + $divisorCount = numberOfDivisors($triangle); + $triangleNumbers[$number] = $divisorCount; + while ($divisorCount <= $n) { + $number += 1; + $triangle = getTriangle($number); + $divisorCount = numberOfDivisors($triangle); + $triangleNumbers[$triangle] = $divisorCount; + + } + echo $triangle."\n"; +} \ No newline at end of file diff --git a/HackerRank/Euler/2.php b/HackerRank/Euler/2.php new file mode 100644 index 0000000..edf012b --- /dev/null +++ b/HackerRank/Euler/2.php @@ -0,0 +1,46 @@ + + * + * Project Euler #2: Even Fibonacci numbers + */ + +$fibs = fibo(80); + + +$handle = fopen ("php://stdin","r"); +$t = fgets($handle); + +for($i=0; $i<$t; $i++) { + $num = trim(fgets($handle)); + + $sum = 0; + foreach($fibs as $fib) { + if($fib<=$num) { + $sum += $fib; + } + } + + print($sum)."\n"; +} +fclose($handle); + + +function fibo($n) { + $prev = 1; + $next = 2; + + $fibs = array(2); + + for($i = 1;$i<$n;$i++) { + $tmp = $next; + $next = $next+$prev; + $prev = $tmp; + + if(($next+$prev)%2 == 0) + $fibs[] = $next+$prev; + } + + return $fibs; +} \ No newline at end of file diff --git a/HackerRank/Euler/21.php b/HackerRank/Euler/21.php new file mode 100644 index 0000000..559cddd --- /dev/null +++ b/HackerRank/Euler/21.php @@ -0,0 +1,64 @@ + + * + * Project Euler #21: Amicable numbers + */ + +$amicableNumbers = []; + +function numberOfDivisors($amicable) +{ + global $amicableNumbers; + + $tempAmicable = $amicable; + $factors = [1]; + $sum = 1; + for ($i = 2; $i <= intval(sqrt($tempAmicable)); $i++) { + $amicable = $tempAmicable; + $count = 0; + while ($amicable % $i == 0) { + if (!in_array($i, $factors)) { + $factors[] = $i; + $sum += $i; + } + + $amicable = floor($amicable / $i); + if (!in_array($amicable, $factors)) { + $factors[] = $amicable; + $sum += $amicable; + } + } + } + + $amicableNumbers[$tempAmicable] = $sum; +} + +for ($i = 1; $i <= 100000; $i++) { + numberOfDivisors($i); +} + +$validAmicableNumbers = []; + +foreach ($amicableNumbers as $i => $val) { + if (isset($amicableNumbers[$i]) && isset($amicableNumbers[$val]) && $amicableNumbers[$val] == $i && $i != $val) { + $validAmicableNumbers[$i] = $i; + } +} + + +$handle = fopen("php://stdin", "r"); +$t = fgets($handle); +for ($i = 0; $i < $t; $i++) { + $n = trim(fgets($handle)); + $sum = 0; + + foreach ($validAmicableNumbers as $number) { + if ($number > $n) { + break; + } + $sum += $number; + } + + echo $sum . "\n"; +} \ No newline at end of file diff --git a/HackerRank/Euler/23.php b/HackerRank/Euler/23.php new file mode 100644 index 0000000..b85a82f --- /dev/null +++ b/HackerRank/Euler/23.php @@ -0,0 +1,68 @@ + + * + * Project Euler #23: Non-abundant sums + */ + +$abundantNumbers = []; + +function numberOfDivisors($abundant) +{ + global $abundantNumbers; + + $tempAbundant = $abundant; + $factors = [1]; + $sum = 1; + for ($i = 2; $i <= intval(sqrt($tempAbundant)); $i++) { + $abundant = $tempAbundant; + $count = 0; + while ($abundant % $i == 0) { + if (!in_array($i, $factors)) { + $factors[] = $i; + $sum += $i; + } + + $abundant = floor($abundant / $i); + if (!in_array($abundant, $factors)) { + $factors[] = $abundant; + $sum += $abundant; + } + } + } + + $abundantNumbers[$tempAbundant] = $sum; +} + +for ($i = 1; $i <= 100000; $i++) { + numberOfDivisors($i); +} + +$validAbundantNumbers = []; + +foreach ($abundantNumbers as $i => $val) { + if ($i < $val) { + $validAbundantNumbers[$i] = $val; + } +} + +$handle = fopen("php://stdin", "r"); +$t = fgets($handle); +for ($i = 0; $i < $t; $i++) { + $n = trim(fgets($handle)); + $sum = 0; + $possible = false; + + foreach ($validAbundantNumbers as $number => $val) { + if ($number > $n) { + break; + } + + if(isset($validAbundantNumbers[$n-$number])) { + $possible = true; + break; + } + } + + echo $possible ? 'YES'."\n" : 'NO' . "\n"; +} \ No newline at end of file diff --git a/HackerRank/Euler/34.php b/HackerRank/Euler/34.php new file mode 100644 index 0000000..d509d00 --- /dev/null +++ b/HackerRank/Euler/34.php @@ -0,0 +1,33 @@ + + * + * Project Euler #34: Digit factorials + */ + + +$factorial = [1,1,2,6,24,120,720,5040,40320,362880]; + +$factorialSum = []; + + + +$handle = fopen("php://stdin", "r"); +$number = fgets($handle); +$total = 0; + +for($i = 10;$i<=$number;$i++) { + $sum = 0; + $n = $i; + while($n!=0) { + $tmp = $n%10; + $sum += $factorial[$tmp]; + $n = intval($n/10); + } + + if($sum%$i == 0) { + $total += $i; + } +} + +echo $total . "\n"; diff --git a/HackerRank/Euler/35.php b/HackerRank/Euler/35.php new file mode 100644 index 0000000..933bff7 --- /dev/null +++ b/HackerRank/Euler/35.php @@ -0,0 +1,64 @@ + + * + * Project Euler #35: Circular primes + */ + + +$n = 1000000; +$primes = []; +$prime = $prime = array_fill(0, $n + 1, true); + +function sieveOfEratosthenes(int $n) +{ + global $primes, $prime; + + for ($p = 2; $p * $p <= $n; $p++) { + // If prime[p] is not changed, then it is a prime + if (isset($prime[$p]) && $prime[$p] == true) { + // Update all multiples of p + for ($i = $p * 2; $i <= $n; $i += $p) + $prime[$i] = false; + } + } + + // Print all prime numbers + for ($p = 2; $p <= $n; $p++) + if ($prime[$p]) + $primes[] = $p; + //echo $p . " "; +} + + +sieveOfEratosthenes($n); + + + +$handle = fopen("php://stdin", "r"); +$number = fgets($handle); +$total = 0; + + +foreach($primes as $tmpPrime) { + if($tmpPrime > $number) { + break; + } + + $isCircularPrime = true; + + for($i = 1;$i + * + * Project Euler #36: Double-base palindromes + */ + + + +$handle = fopen("php://stdin", "r"); +$tmp = explode(" ",fgets($handle)); + +$n = intval($tmp[0]); +$k = intval($tmp[1]); + +$total = 0; +for($i = 1;$i<=$n;$i++) { + + $baseConv = base_convert($i, 10, $k); + + if($i == strrev($i) && $baseConv == strrev($baseConv)) { + $total += $i; + } +} + +echo $total . "\n"; diff --git a/HackerRank/Euler/37.php b/HackerRank/Euler/37.php new file mode 100644 index 0000000..35bbbbb --- /dev/null +++ b/HackerRank/Euler/37.php @@ -0,0 +1,84 @@ + + * + * Project Euler #37: Truncatable primes + */ + + +$n = 1000000; +$primes = []; +$prime = $prime = array_fill(0, $n + 1, true); +$prime[0] = $prime[1] = false; +function sieveOfEratosthenes(int $n) +{ + global $primes, $prime; + + for ($p = 2; $p * $p <= $n; $p++) { + // If prime[p] is not changed, then it is a prime + if (isset($prime[$p]) && $prime[$p] == true) { + // Update all multiples of p + for ($i = $p * 2; $i <= $n; $i += $p) + $prime[$i] = false; + } + } + + // Print all prime numbers + for ($p = 2; $p <= $n; $p++) + if ($prime[$p]) + $primes[] = $p; +} + + +sieveOfEratosthenes($n); + + + +$handle = fopen("php://stdin", "r"); +$number = fgets($handle); +$total = 0; + + +foreach($primes as $tmpPrime) { + + if($tmpPrime >= $number) { + break; + } else if($tmpPrime < 9) continue; + + $tmpStorage = []; + $backupPrime = $tmpPrime; + + $isCircularPrime = true; + + $tmpStorage[] = $tmpPrime; + + for($i = 1;$i Date: Tue, 12 Dec 2017 14:11:42 -0500 Subject: [PATCH 09/15] fixing dijkstra's algorithm --- Algorithms/Graph/Dijkstra.php | 142 +++++++++++++++++----------------- 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/Algorithms/Graph/Dijkstra.php b/Algorithms/Graph/Dijkstra.php index 77b3dbc..864205e 100644 --- a/Algorithms/Graph/Dijkstra.php +++ b/Algorithms/Graph/Dijkstra.php @@ -1,71 +1,73 @@ - - * - */ - -function dijkstra(array $graph, string $source, string $target): array { - $dist = []; - $pred = []; - $Queue = new SplPriorityQueue(); - - foreach ($graph as $v => $adj) { - $dist[$v] = PHP_INT_MAX; - $pred[$v] = null; - $Queue->insert($v, min($adj)); - } - - $dist[$source] = 0; - - while (!$Queue->isEmpty()) { - $u = $Queue->extract(); - if (!empty($graph[$u])) { - foreach ($graph[$u] as $v => $cost) { - if ($dist[$u] + $cost < $dist[$v]) { - $dist[$v] = $dist[$u] + $cost; - $pred[$v] = $u; - } - } - } - } - - $S = new SplStack(); - $u = $target; - $distance = 0; - - while (isset($pred[$u]) && $pred[$u]) { - $S->push($u); - $distance += $graph[$u][$pred[$u]]; - $u = $pred[$u]; - } - - if ($S->isEmpty()) { - return ["distance" => 0, "path" => $S]; - } else { - $S->push($source); - return ["distance" => $distance, "path" => $S]; - } -} - -$graph = [ - 'A' => ['B' => 3, 'C' => 5, 'D' => 9], - 'B' => ['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7], - 'C' => ['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3], - 'D' => ['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2], - 'E' => ['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5], - 'F' => ['C' => 3, 'D' => 2, 'E' => 5], -]; - -$source = "A"; -$target = "F"; - -$result = dijkstra($graph, $source, $target); -extract($result); - -echo "Distance from $source to $target is $distance \n"; -echo "Path to follow : "; - -while (!$path->isEmpty()) { - echo $path->pop() . "\t"; + + * + */ + +function dijkstra(array $graph, string $source, string $target): array { + $dist = []; + $pred = []; + $Queue = new SplPriorityQueue(); + + foreach ($graph as $v => $adj) { + $dist[$v] = PHP_INT_MAX; + $pred[$v] = null; + foreach ($adj as $w => $cost) { + $Queue->insert($w, $cost); + } + } + + $dist[$source] = 0; + + while (!$Queue->isEmpty()) { + $u = $Queue->extract(); + if (!empty($graph[$u])) { + foreach ($graph[$u] as $v => $cost) { + if ($dist[$u] + $cost < $dist[$v]) { + $dist[$v] = $dist[$u] + $cost; + $pred[$v] = $u; + } + } + } + } + + $S = new SplStack(); + $u = $target; + $distance = 0; + + while (isset($pred[$u]) && $pred[$u]) { + $S->push($u); + $distance += $graph[$u][$pred[$u]]; + $u = $pred[$u]; + } + + if ($S->isEmpty()) { + return ["distance" => 0, "path" => $S]; + } else { + $S->push($source); + return ["distance" => $distance, "path" => $S]; + } +} + +$graph = [ + 'A' => ['B' => 3, 'C' => 5, 'D' => 9], + 'B' => ['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7], + 'C' => ['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3], + 'D' => ['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2], + 'E' => ['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5], + 'F' => ['C' => 3, 'D' => 2, 'E' => 5], +]; + +$source = "E"; +$target = "F"; + +$result = dijkstra($graph, $source, $target); +extract($result); + +echo "Distance from $source to $target is $distance \n"; +echo "Path to follow : "; + +while (!$path->isEmpty()) { + echo $path->pop() . "\t"; } \ No newline at end of file From 9cf0fb69221b850d9faeb49c421acb069d95ec8d Mon Sep 17 00:00:00 2001 From: Stanislav Karassyov Date: Mon, 22 Jan 2018 00:00:13 +0600 Subject: [PATCH 10/15] fix: You can't insert before the first element with method insertBefore Resolves: #4 --- DS/LinkedList/Classes/LinkedList.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DS/LinkedList/Classes/LinkedList.php b/DS/LinkedList/Classes/LinkedList.php index 1d6bfa3..405e7f7 100644 --- a/DS/LinkedList/Classes/LinkedList.php +++ b/DS/LinkedList/Classes/LinkedList.php @@ -69,6 +69,11 @@ public function insertBefore(string $data = NULL, string $query = NULL) { while ($currentNode !== NULL) { if ($currentNode->data === $query) { $newNode->next = $currentNode; + if ($previous === NULL) { + $this->_firstNode = &$newNode; + } else { + $previous->next = $newNode; + } $previous->next = $newNode; $this->_totalNode++; break; From 676602d384cbe81594234258f3b1dc3fb9cc0bd6 Mon Sep 17 00:00:00 2001 From: Stanislav Karassyov Date: Mon, 22 Jan 2018 00:30:09 +0600 Subject: [PATCH 11/15] fix: You can't insert before the first element with method insertBefore --- DS/LinkedList/Classes/LinkedList.php | 1 - 1 file changed, 1 deletion(-) diff --git a/DS/LinkedList/Classes/LinkedList.php b/DS/LinkedList/Classes/LinkedList.php index 405e7f7..40dd272 100644 --- a/DS/LinkedList/Classes/LinkedList.php +++ b/DS/LinkedList/Classes/LinkedList.php @@ -74,7 +74,6 @@ public function insertBefore(string $data = NULL, string $query = NULL) { } else { $previous->next = $newNode; } - $previous->next = $newNode; $this->_totalNode++; break; } From 0a7afbaad737b0ff66632241f3fef92f0ea9a55f Mon Sep 17 00:00:00 2001 From: Mizanur Rahman Date: Mon, 13 Jan 2020 23:18:16 +0900 Subject: [PATCH 12/15] Create FUNDING.yml --- .github/FUNDING.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..53253a8 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms +github: [mirahman] +custom: ["paypal.me/mirahman1221", mizanurrahman.com] From 54e88a3f7dad9d51254ea0cb27732c7e9fc1a554 Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Thu, 16 Jan 2020 19:15:25 +0600 Subject: [PATCH 13/15] adding TRIE data structure in PHP --- DS/Tree/.DS_Store | Bin 0 -> 6148 bytes DS/Tree/Classes/Trie.php | 49 +++++++++++++++++++++++++++++++++++ DS/Tree/Classes/TrieNode.php | 21 +++++++++++++++ DS/Tree/Examples/trie.php | 30 +++++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 DS/Tree/.DS_Store create mode 100644 DS/Tree/Classes/Trie.php create mode 100644 DS/Tree/Classes/TrieNode.php create mode 100644 DS/Tree/Examples/trie.php diff --git a/DS/Tree/.DS_Store b/DS/Tree/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1ad25cbe90a6572f8b80a99612b73f93e916116c GIT binary patch literal 6148 zcmeHKJ5B>Z41I=3M50MaIalBYqYzHO1t0{fm9|*XZ^gNCG@d_-6gJS&py!qSW<0h> z`-=4%fNehx_rM0gn(By8H%swz*M(e_$I+t3gf~ow>2=tTi|ES^&%MC|2E1V6bIKnF zmi&J7&f5Dik1p4fR}6>&F(3xSfEf6l0dKIB^=+c87!U(u;KYD`9~#xM7tV?C>7a=b zfViSNgzK0kh|L|uUN|SxL$ORHW~$YQVVO>UtGHe`CuTYV!&3rr`?vXRK0caa^7nj^_l81N2&|gkwO#g lm>BJt8*j&V5tMPw*F5iqb7G{^AL&H>3^*?mG4R(6d;tOm8=L?D literal 0 HcmV?d00001 diff --git a/DS/Tree/Classes/Trie.php b/DS/Tree/Classes/Trie.php new file mode 100644 index 0000000..2fe2292 --- /dev/null +++ b/DS/Tree/Classes/Trie.php @@ -0,0 +1,49 @@ + + * + */ + +namespace DS\Tree\Classes; + +use DS\Tree\Classes\TrieNode; + +class Trie +{ + public $root; + public function __construct() + { + $this->root = new TrieNode; + } + + public function insert(string $key) + { + $key = strtolower($key); + $length = strlen($key); + $pCrawl = $this->root; + for ($level = 0; $level < $length; $level++) { + $index = ord($key[$level]) - ord('a'); + if (is_null($pCrawl->children[$index])) + $pCrawl->children[$index] = new TrieNode(); + + $pCrawl = $pCrawl->children[$index]; + } + $pCrawl->isEndOfWord = true; + } + + public function search(string $key) + { + $key = strtolower($key); + $length = strlen($key); + $pCrawl = $this->root; + for ($level = 0; $level < $length; $level++) { + $index = ord($key[$level]) - ord('a'); + if (is_null($pCrawl->children[$index])) + return false; + + $pCrawl = $pCrawl->children[$index]; + } + return (!is_null($pCrawl) && $pCrawl->isEndOfWord); + } +} diff --git a/DS/Tree/Classes/TrieNode.php b/DS/Tree/Classes/TrieNode.php new file mode 100644 index 0000000..ee49527 --- /dev/null +++ b/DS/Tree/Classes/TrieNode.php @@ -0,0 +1,21 @@ + + * + */ + +namespace DS\Tree\Classes; + +class TrieNode +{ + public $children; + public $isEndOfWord; + const ALPHABETSIZE = 26; + + public function __construct() + { + $this->isEndOfWord = false; + $this->children = array_fill(0,self::ALPHABETSIZE, null); + } +} \ No newline at end of file diff --git a/DS/Tree/Examples/trie.php b/DS/Tree/Examples/trie.php new file mode 100644 index 0000000..23e9ab0 --- /dev/null +++ b/DS/Tree/Examples/trie.php @@ -0,0 +1,30 @@ + + * + */ + +include __DIR__ . '/../../../Vendor/Autoload.php'; + +use \DS\Tree\Classes\Trie; + +try { + $keys = ["dhaka", "bangladesh", "there", "answer", "any", "by", "bye", "their"]; + + $trie = new Trie(); + // Construct trie + for ($i = 0; $i < count($keys); $i++) + $trie->insert($keys[$i]); + + $searches = ["dhaka", "three", "these", "there", "the", "any", "DHAKA", "anyone", "desh"]; + foreach ($searches as $search) { + if ($trie->search($search)) { + echo "$search - is present in the trie \n"; + } else { + echo "$search - is not present in the trie \n"; + } + } +} catch (Exception $e) { + echo $e->getMessage(); +} From 7574f25f96c6b77bf036fcf2a8ef560719d0e21e Mon Sep 17 00:00:00 2001 From: Mizanur rahman Date: Thu, 16 Jan 2020 19:26:03 +0600 Subject: [PATCH 14/15] added Trie in our list of solved DS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 45417a4..057c7ab 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Any feedback, bugs or suggestion will be welcomed. - Binary Tree - Binary Search Tree - Tree Traversal (In-order, pre-order, post-order) + - Trie (Simple insert and search operation) 5. Heaps From eee6c1b6164c2a74295bd75ed38f13cbbc903971 Mon Sep 17 00:00:00 2001 From: Mizanur Rahman Date: Fri, 21 Feb 2020 05:20:12 +0600 Subject: [PATCH 15/15] Create .sonarcloud.properties --- .sonarcloud.properties | 1 + 1 file changed, 1 insertion(+) create mode 100644 .sonarcloud.properties diff --git a/.sonarcloud.properties b/.sonarcloud.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.sonarcloud.properties @@ -0,0 +1 @@ +