* Iteration 5: * $result = 54321 (5432 * 10 + 1.2345 % 10) * $number = 0.12345 * * @param int $number * @return int * @throws \InvalidArgumentException */ function reverseDigits($number) { if (!is_int($number)) { throw new \InvalidArgumentException('$number must be an integer'); } $isNegative = $number < 0; $number = abs($number); $result = 0; while ($number >= 1) { $result = $result * 10 + $number % 10; // Known issue, working with very large numbers will cause issues. i.e. PHP_INT_MAX $number = $number / 10; } if ($isNegative) { $result *= -1; } return $result; } $inputHelper = new InputHelper(); $number = $inputHelper->readInputFromStdIn('Enter the integer to reverse: '); $result = reverseDigits((int) $number); printf('The result of reversing the digits in %d is: %d', (int) $number, $result); print PHP_EOL;
* 65 = 1000001 * 1000001 / result = 1 * 1000000 / result = 0 * parity of 65 is 0 * * This improves performance in the best and average cases but can still be as slow as brute force. For example if run * on 9223372036854775807 it will take 63 iterations which matches brute force. * * @param int $number * @return int * @throws \InvalidArgumentException */ function computeParityEraseLowestSetBit($number) { if (!is_int($number)) { throw new \InvalidArgumentException('$number must be an integer'); } $bitwiseHelper = new BitwiseHelper(); $number = $bitwiseHelper->eraseSignBit($number); $result = 0; while ($number) { $result ^= 1; $number &= $number - 1; } return $result; } $inputHelper = new InputHelper(); $number = $inputHelper->readInputFromStdIn('Enter an integer: '); $parity = computeParityEraseLowestSetBit((int) $number); printf('The parity of %d is %d', $number, $parity); print PHP_EOL;
* return true * * @param int[] $array * @param int $t * @return bool */ function hasTwoSum($array, $t) { $j = 0; $k = count($array) - 1; while ($j <= $k) { if ($array[$j] + $array[$k] == $t) { return true; } elseif ($array[$j] + $array[$k] < $t) { $j++; } else { $k--; } } return false; } $inputHelper = new InputHelper(); $array = json_decode($inputHelper->readInputFromStdIn('Enter the array of numbers as a json encoded array: ')); $t = (int) $inputHelper->readInputFromStdIn('Enter the number to test for 3-sum: '); $result = hasThreeSum($array, $t); if ($result) { printf('The array %s can be 3-summed for %d', json_encode($array), $t); } else { printf('The array %s can not be 3-summed for %d', json_encode($array), $t); } print PHP_EOL;
* If the two rectangles are {x: 2, y: 1, width: 2, height: 2} and {x: 3, y: 0, width: 4, height: 2} * * Is the first rectangles x-coordinate(2) <= the second rectangles x-coordinate(3) + the second rectangles width(4) = 7? YES * Is the first rectangles x-coordinate(2) + the first rectangles width(2) = 4 >= the second rectangles x-coordinate(3)? YES * Is the first rectangles y-coordinate(1) <= the second rectangles y-coordinate(0) + the second rectangles height(2) = 2? YES * Is the first rectangles y-coordinate(1) + the first rectangles height(2) = 3 >= the second rectangles y-coordinate(0)? YES * * They intersect * * @param Rectangle $firstRectangle * @param Rectangle $secondRectangle * @return bool */ function rectanglesIntersect(Rectangle $firstRectangle, Rectangle $secondRectangle) { return $firstRectangle->getX() <= $secondRectangle->getX() + $secondRectangle->getWidth() && $firstRectangle->getX() + $firstRectangle->getWidth() >= $secondRectangle->getX() && $firstRectangle->getY() <= $secondRectangle->getY() + $secondRectangle->getHeight() && $firstRectangle->getY() + $firstRectangle->getHeight() >= $secondRectangle->getY(); } $inputHelper = new InputHelper(); $firstX = (int) $inputHelper->readInputFromStdIn('Enter the x coordinate of the first rectangle: '); $firstY = (int) $inputHelper->readInputFromStdIn('Enter the y coordinate of the first rectangle: '); $firstWidth = (int) $inputHelper->readInputFromStdIn('Enter the width of the first rectangle: '); $firstHeight = (int) $inputHelper->readInputFromStdIn('Enter the height of the first rectangle: '); $secondX = (int) $inputHelper->readInputFromStdIn('Enter the x coordinate of the second rectangle: '); $secondY = (int) $inputHelper->readInputFromStdIn('Enter the y coordinate of the second rectangle: '); $secondWidth = (int) $inputHelper->readInputFromStdIn('Enter the width of the second rectangle: '); $secondHeight = (int) $inputHelper->readInputFromStdIn('Enter the height of the second rectangle: '); $firstRectangle = new Rectangle($firstX, $firstY, $firstWidth, $firstHeight); $secondRectangle = new Rectangle($secondX, $secondY, $secondWidth, $secondHeight); $result = getIntersectingRectangle($firstRectangle, $secondRectangle); printf('The intersection of rectangles %s and %s is %s', $firstRectangle, $secondRectangle, $result); print PHP_EOL;
* @param array $words * @return array */ function partitionIntoAnagramGroups($words = []) { if (empty($words)) { return []; } $sortedWordsToWords = []; $anagramGroups = []; foreach ($words as $word) { // There is no built in string sort so we convert the string to an array, sort it and convert it back to a // string. $sortedWord = str_split($word); sort($sortedWord); $sortedWord = implode('', $sortedWord); $sortedWordsToWords[$sortedWord][] = $word; } foreach ($sortedWordsToWords as $sortedWord => $words) { // A group must have more than one entry if (count($words) > 1) { $anagramGroups[] = $words; } } return $anagramGroups; } $inputHelper = new InputHelper(); $words = explode(' ', $inputHelper->readInputFromStdIn('Enter the words separated by spaces: ')); $result = partitionIntoAnagramGroups($words); printf('The groups of anagrams formed from %s are %s.', json_encode($words), json_encode($result)); print PHP_EOL;
* * $intersection = [2, 4] * * @param array $array1 * @param array $array2 * @return array */ function computeIntersectionUsingLinearAdvancement($array1 = [], $array2 = []) { $i = 0; $j = 0; $intersection = []; while ($i < count($array1) && $j < count($array2)) { if ($array1[$i] == $array2[$j] && ($i == 0 || $array1[$i] != $array1[$i - 1])) { $intersection[] = $array1[$i]; $i++; $j++; } elseif ($array1[$i] < $array2[$j]) { $i++; } else { $j++; } } return $intersection; } $inputHelper = new InputHelper(); $array1 = json_decode($inputHelper->readInputFromStdIn('Enter the first array in json format: ')); $array2 = json_decode($inputHelper->readInputFromStdIn('Enter the second array in json format: ')); $result = computeIntersection($array1, $array2); printf('The intersection of %s and %s is %s', json_encode($array1), json_encode($array2), json_encode($result)); print PHP_EOL;
*/ function findClosestIntegerWithTheSameWeight($number) { if (!is_int($number)) { throw new \InvalidArgumentException('$number must be an integer'); } if ($number < 0) { throw new \InvalidArgumentException('$number must be non-negative'); } $integerWidth = PHP_INT_SIZE * BitwiseHelper::WORD_SIZE; // Ignore the last bit as it's the sign bit (0 - 62 is 63 bits and 0 - 30 is 31 bits) for ($i = 0; $i < $integerWidth - 2; $i++) { // If the bits at position i and i + 1 are not the same if ($number >> $i & 1 ^ $number >> $i + 1 & 1) { // Swap the bits $number ^= 1 << $i | 1 << $i + 1; return $number; } } throw new \RuntimeException('all bits of $number are 0 or 1'); } $inputHelper = new InputHelper(); $number = $inputHelper->readInputFromStdIn('Enter a non-negative integer: '); try { $result = findClosestIntegerWithTheSameWeight((int) $number); printf('The closest integer to %d (%b) with the same weight is %d (%b)', $number, $number, $result, $result); print PHP_EOL; } catch (\RuntimeException $e) { printf('All of the bits in %d (%b) are 0 or 1', $number, $number); print PHP_EOL; }
* <<< SECOND RECURSIVE CALL BEGIN >>> * $numberOfRings = 0 * $fromPeg = 2 * $toPeg = 1 * $usePeg = 0 * * Is $numberOfRings > 0? No * <<< SECOND RECURSIVE CALL RETURN >>> * <<< SECOND RECURSIVE CALL RETURN >>> * <<< SECOND RECURSIVE CALL RETURN >>> * * @param int $numberOfRings * @param array[\SplStack] $pegs * @param int $fromPeg * @param int $toPeg * @param int $usePeg */ function printTowerOfHanoiSteps($numberOfRings, $pegs, $fromPeg, $toPeg, $usePeg) { if ($numberOfRings > 0) { printTowerOfHanoiSteps($numberOfRings - 1, $pegs, $fromPeg, $usePeg, $toPeg); printf('Move %d from peg %d to peg %d', $pegs[$fromPeg]->top(), $fromPeg, $toPeg); print PHP_EOL; $pegs[$toPeg]->push($pegs[$fromPeg]->top()); $pegs[$fromPeg]->pop(); printTowerOfHanoiSteps($numberOfRings - 1, $pegs, $usePeg, $toPeg, $fromPeg); } } $inputHelper = new InputHelper(); $numberOfRings = (int) $inputHelper->readInputFromStdIn('Enter the number of rings to move: '); computeTowerOfHanoiMoves($numberOfRings);
$start = (int) $start; $end = (int) $end; $range = $end - $start + 1; do { $result = 0; // Make sure that if 1 << $i is less than zero we stop. Otherwise we will loop forever for ($i = 0; 1 << $i < $range && 1 << $i > 0; $i++) { $result = $result << 1 | rand(0, 1); } } while ($result >= $range); return $result + $start; } if (false) { $results = [1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0]; $tests = 10000; for ($i = 0; $i < $tests; $i++) { $results[generateUniformRandomNumber(1, 5)]++; } print 'Tests run: ' . $tests . PHP_EOL; foreach ($results as $value => $count) { printf('Percentage of %d\'s: %f', $value, $count / $tests * 100); print PHP_EOL; } } else { $inputHelper = new InputHelper(); $start = $inputHelper->readInputFromStdIn('Enter the start integer: '); $end = $inputHelper->readInputFromStdIn('Enter the end integer: '); $result = generateUniformRandomNumber($start, $end); printf('Random value between %d and %d inclusive: %d', $start, $end, $result); print PHP_EOL; }
* @throws \InvalidArgumentException */ function swapBits($number, $index1, $index2) { if (!is_int($number) || !is_int($index1) || !is_int($index2)) { throw new \InvalidArgumentException('$number, $index1 and $index2 must all be integers'); } if ($index1 < 0 || $index2 < 0) { throw new \InvalidArgumentException('$index1 and $index2 must be greater than 0'); } // Don't let the sign bit be swapped if (PHP_INT_SIZE == 8 && ($index1 > 62 || $index2 > 62)) { throw new \InvalidArgumentException('$index1 and $index2 must be less than or equal to 63'); } // Don't let the sign bit be swapped if (PHP_INT_SIZE == 4 && ($index1 > 30 || $index2 > 30)) { throw new \InvalidArgumentException('$index1 and $index2 must be less than or equal to 31'); } // See if the bits differ if (($number >> $index1 & 1) != ($number >> $index2 & 1)) { $number ^= 1 << $index1 | 1 << $index2; } return $number; } $inputHelper = new InputHelper(); $number = $inputHelper->readInputFromStdIn('Enter an integer: '); $index1 = $inputHelper->readInputFromStdIn('Enter index 1 in the swap: '); $index2 = $inputHelper->readInputFromStdIn('Enter index 2 in the swap: '); $result = swapBits((int) $number, (int) $index1, (int) $index2); printf('The result of swapping the %d and %d bits of %b (%d) is %b (%d)', $index1, $index2, $number, $number, $result, $result); print PHP_EOL;
* * @param int[] $array * @param int $t * @return bool */ function hasTwoSum($array, $t) { $j = 0; $k = count($array) - 1; while ($j <= $k) { if ($array[$j] + $array[$k] == $t) { return true; } elseif ($array[$j] + $array[$k] < $t) { $j++; } else { $k--; } } return false; } $inputHelper = new InputHelper(); $array = json_decode($inputHelper->readInputFromStdIn('Enter the array of numbers as a json encoded array: ')); $k = json_decode($inputHelper->readInputFromStdIn('Enter the number of elements to add for the sum: ')); $t = (int) $inputHelper->readInputFromStdIn('Enter the number to test for ' . $k . '-sum: '); $result = hasKSum($array, $t, $k); if ($result) { printf('The array %s can be ' . $k . '-summed for %d', json_encode($array), $t); } else { printf('The array %s can not be ' . $k . '-summed for %d', json_encode($array), $t); } print PHP_EOL;
throw new \InvalidArgumentException('$integer must be a number'); } $integer = (int) $integer; if ($integer < 0) { return false; } if ($integer === 0) { return true; } $numberOfDigits = floor(log10($integer)) + 1; $integerRemaining = $integer; $msdShift = pow(10, $numberOfDigits - 1); for ($i = 0; $i < $numberOfDigits / 2; $i++) { if ((int) ($integer / $msdShift) != (int) ($integerRemaining % 10)) { return false; } $integer %= $msdShift; $msdShift /= 10; $integerRemaining /= 10; } return true; } $inputHelper = new InputHelper(); $integer = $inputHelper->readInputFromStdIn('Enter the integer to test: '); $result = isPalindromic($integer); if ($result === true) { printf('The integer %d is palindromic', $integer); } else { printf('The integer %d is not palindromic', $integer); } print PHP_EOL;
if ($score < 0 || $score > PHP_INT_MAX || !is_int($score)) { throw new \InvalidArgumentException('$score must be an integer between 0 and ' . PHP_INT_MAX); } if (!is_array($plays) || empty($plays)) { throw new \InvalidArgumentException('$plays must be a non-empty array'); } $permutations = array_fill(0, $score + 1, 0); // There is only one way to score 0 points $permutations[0] = 1; for ($i = 0; $i <= $score; $i++) { foreach ($plays as $play) { if ($play < 0) { throw new \InvalidArgumentException('negative value plays are not handled'); } // If the play can achieve the current score if ($i >= $play) { $permutations[$i] += $permutations[$i - $play]; } } } return $permutations[$score]; } $inputHelper = new InputHelper(); $score = (int) $inputHelper->readInputFromStdIn('Enter the aggregate score: '); $plays = json_decode($inputHelper->readInputFromStdIn('Enter the set of plays as a json encoded array: ')); $combinations = computeCombinations($score, $plays); $permutations = computePermutations($score, $plays); printf('The combinations to achieve an aggregate score of %d using plays that can score %s is %d', $score, json_encode($plays), $combinations); print PHP_EOL; printf('The permutations to achieve an aggregate score of %d using plays that can score %s is %d', $score, json_encode($plays), $permutations); print PHP_EOL;