Example #1
0
 * 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;
Example #3
0
 * 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;
}
Example #8
0
 *              <<< 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;
}
Example #10
0
 * @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;