Skip to content

Instantly share code, notes, and snippets.

@acelot
Last active August 21, 2018 06:57
Show Gist options
  • Save acelot/8b5e1b10124f8d4b9a0f428a639751d1 to your computer and use it in GitHub Desktop.
Save acelot/8b5e1b10124f8d4b9a0f428a639751d1 to your computer and use it in GitHub Desktop.
The adder of big numbers
#!/usr/bin/env php
<?php declare(strict_types=1);
if ($argc !== 3) {
echo 'Usage: bigsum NUMBER1 NUMBER2' . PHP_EOL;
exit(2);
}
[, $n1, $n2] = $argv;
if (!preg_match('/^\d+$/', $n1 . $n2)) {
echo 'Only positive numbers are allowed' . PHP_EOL;
exit(2);
}
echo sum($n1, $n2) . PHP_EOL;
exit(0);
function sum(string $n1, string $n2): string
{
$length = max(strlen($n1), strlen($n2)); // Находим самое длинное число
$n1 = str_pad($n1, $length, '0', STR_PAD_LEFT); // Отбиваем спереди нулями, чтобы длины строк были одинаковые
$n2 = str_pad($n2, $length, '0', STR_PAD_LEFT);
$v1 = array_reverse(array_map('intval', str_split($n1))); // Разделяем строки на массивы цифр и реверсируем
$v2 = array_reverse(array_map('intval', str_split($n2)));
$v3 = array_fill(0, $length + 1, 0); // Создаем результирующий массив забитый нулями (длиннее на один)
$mem = 0; // Здесь будем хранить "лишний десяток"
for ($i = 0; $i < $length; $i++) { // Проходимся по массиву
$v3[$i] = $v1[$i] + $v2[$i] + $mem; // Пишем в результат сумму текущих цифр
if ($v3[$i] >= 10) { // Если сумма больше или равно 10
$mem = 1; // То пишем в память десяток
$v3[$i] -= 10; // А из результата вычитаем 10
} else {
$mem = 0; // Иначе обнуляем память
}
}
if ($mem > 0) { // Если в памяти что-то осталось, то просто дописываем в конец
$v3[$length] = $mem;
}
$result = ltrim(join('', array_reverse($v3)), '0'); // Реверсируем результирующий массив и вырезаем лидирующие нули
return $result !== '' ? $result : '0';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment