Reduce number to single digit using recurssion - php

$result = reduce($number);
function reduce($number) {
$new_number = 0;
if($number < 10) {
return $number;
}
$q = floor($number / 10 );
$r = $number % 10;
$new_number = $q + $r;
if($new_number <= 9) {
return $new_number;
}
else {
reduce($new_number);
}
}
I want to sum the numbers by its digits
For example, if i pass 10, it should return 1+0 = 1
This works if i pass 10
But not working when i pass 100.

This should work for you:
Just split your number into an array with str_split() and then use array_sum() to add all digits together.
echo array_sum(str_split($number));
EDIT:
If you don't want the checksum, but go down to a single digit, you also don't have to write that much code. Just call the function over and over again until the array_sum() is equal or less than 9.
function reduceToOneSingleDigit($result) {
$result = str_split($result);
while(array_sum($result) > 9)
return reduceToOneSingleDigit(array_sum($result));
return array_sum($result);
}
echo reduceToOneSingleDigit(99);

Just too much code, take a look at next one
print sum(125); // 8
// 5 12
// 2 1
// 1 + ~>0
function findSum($num)
{
if($num == 0)
return 0;
return $num%10 + findSum(floor($num/10));
}
so, even 100000 or 000001 will be 1, works just as U want, but it will have troubles if the paramater will be 0001000

You are missing the word return near the end. It should look like this:
return reduce($new_number);

Related

Making a function with adding up the numbers between a set of numbers

I have to make a function that works like this:
telOp(2, 5) => 2 + 3 + 4 + 5 = 14
Or
telOp(1, 6) => 1 + 2 + 3 + 4 + 5 + 6 = 21
I have tried a few things but I can't seem to figure it out. I tried making a while loop in the function:
<?php
function telOp($getal1, $getal2){
while ($getal1 <= $getal2){
echo $getal1++;
}
}
$resultaat = telOp(5, 10);
print ($resultaat);
Now this will print the numbers from 5 through 10 but I can't seem to make it work that they add up.
I have also tried simply adding the numbers up with a return statement but combining the 2 doesn't seem to work.:
<?php
function telOp($getal1, $getal2){
while ($getal1 <= $getal2){
echo $getal1++;
}
$resultaat = ($getal1 + $getal2);
return $resultaat;
}
$resultaat = telOp(5, 10);
print ($resultaat);
I am new to php so any tips would also be appreciated!
Problem is that you are adding the numbers outside of the while loop. Also you shouldn't add the upper bound always. Here's the fixed code.
<?php
function telOp($getal1, $getal2){
$resultaat=0;
while ($getal1 <= $getal2){
$resultaat = ($resultaat+ $getal1);
$getal1++;
}
return $resultaat;
}
$resultaat = telOp(5, 10);
print ($resultaat);
Also, here's a small hint to making this run way faster. in order to achieve what you are trying, you don't need to iterate through all the numbers, you can just use a math formula that says that the sum of the first n numbers is n*(n+1)/2. So essentially if you have two numbers a and b, and want to compute a+(a+1)+...+(b-1)+b, you can just compute the sum of the first b numbers with that formula, and subtract the sum of the first a-1 numbers.
You are fairly close. You need to add the numbers up in the telOp function. That can be done in the following way:
<?php
function telOp($getal1, $getal2){
$result = 0;
while ($getal1 <= $getal2){
$result += $getal1++;
}
return $result;
}
$resultaat = telOp(5, 10);
echo ($resultaat);

Format number to N significant digits in PHP

I would like to format (round) float (double) numbers to lets say 2 significant digits for example like this:
1 => 1
11 => 11
111 => 110
119 => 120
0.11 => 0.11
0.00011 => 0.00011
0.000111 => 0.00011
So the arbitrary precision remains same
I expect there is some nice function for it already built in, but could not find any so far
I was pointed to How to round down to the nearest significant figure in php, which is close but doesn't work for N significant digits and I'm not sure what it does with 0.000XXX numbers
To get a number rounded to n significant figures you need to find the size of the number in powers of ten, and subtract that from n.
This works fine for simple rounding:
function sigFig($value, $digits)
{
if ($value == 0) {
$decimalPlaces = $digits - 1;
} elseif ($value < 0) {
$decimalPlaces = $digits - floor(log10($value * -1)) - 1;
} else {
$decimalPlaces = $digits - floor(log10($value)) - 1;
}
$answer = round($value, $decimalPlaces);
return $answer;
}
This will give the following:
0.0001234567 returns 0.0001235
123456.7 returns 123500
However a value such as 10 to four significant figures should strictly be represented as 10.00 to signify the precision to which the value is known.
If this is the desired output you can use the following:
function sigFig($value, $digits)
{
if ($value == 0) {
$decimalPlaces = $digits - 1;
} elseif ($value < 0) {
$decimalPlaces = $digits - floor(log10($value * -1)) - 1;
} else {
$decimalPlaces = $digits - floor(log10($value)) - 1;
}
$answer = ($decimalPlaces > 0) ?
number_format($value, $decimalPlaces) : round($value, $decimalPlaces);
return $answer;
}
Now 1 is displayed as 1.000
With little modification to possible duplicate, answer by Todd Chaffee:
public static function roundRate($rate, $digits)
{
$mod = pow(10, intval(round(log10($rate))));
$mod = $mod / pow(10, $digits);
$answer = ((int)($rate / $mod)) * $mod;
return $answer;
}
To make sigFig(0.9995, 3) output 1.00, use
if(floor(log10($value)) !== floor(log10(round($value, $decimalPlaces)))) {$decimalPlaces--;}
Said line of code should be placed before declaring $answer.
If input $value is negative, set a flag and remove the sign at the beginning of the function, like this:
if($value < 0){$flag = 1;}
$value = ltrim($value, "-");
Then right before returning $answer, detect if the flag is set and if so restore the negative sign, like this:
if(isset($flag)){$answer = "-".$answer;}
Finally, for result values with ambiguous number of significant digits (e.g., 1000, 12000,...), express the result in scientific notation to the desired number of significant digits using sprintf or printf.

Get total numbers presented in integer with PHP

I don't know how is called the thing I'm looking for, that's why I ask the question.
So, I have numbers like 5, 35, 1823, 355581. And when I use something like totalNumbers(35) then it should return 2, because it has 3 and 5. It should be applicable to all the numbers.
I know I can create a code like this:
function totalNumbers($int) {
if($int / 1000 > 0) return 3;
if($int / 100 > 0) return 2;
if($int / 10 > 0) return 1;
}
But I don't want to add if for every number in the world. How do you call this?
Use the strlen function
$number = 4353;
echo strlen($number);
Result: 4
You could use
function totalNumbers($int){
return strlen((string) $int);
}
Why not use a string for that purpose? In the example below we use the function that returns the number of characters in string.
function totalNumbers($int) {
return strlen($int);
}

PHP math (numbering)

$temp is currently 6. But the variable result can be changing every time to a different number so it is not a fixed value.
Anyway, for this $temp * 1.1666666, the result will be 6.99999996. Since I used the floor function, it will be rounded down to 6.
Is there any way when the value is more then>*.49999 it will stay at *.5 instead of *?
Example: 6.51111111, 6.78948123, 6.9747124
Expected Output: 6.5
Example: 6.49999999, 6.12412431, 6.33452361
Expected Output: 6
Do note that, $temp value will be ever changing..thank you!
Use round($number, 1). That will round to the nearest decimal point.
$number = round(.1666666 * $temp, 1);
If you want to round to the nearest half you can do this:
function round_to_half($num)
{
if($num >= ($half = ($ceil = ceil($num))- 0.5) + 0.25) return $ceil;
else if($num < $half - 0.25) return floor($num);
else return $half;
}
$number = round_to_half(.1666666 * $temp);
Try this code...
<?php
$temp = 6.94444;
echo myRound($temp);
function myRound($temp)
{
$frac = $temp - floor($temp);
$frac = ($frac >= .5) ? .5 : 0;
return ( floor($temp) + $frac );
}
?>
Hope this is what you want.

PHP Random numbers

I would like to draw a random number from the interval 1,49 but I would like to add a number as an exception ( let's say 44 ) , I cannot use round(rand(1,49)) .So I decided to make an array of 49 numbers ( 1-49) , unset[$aray[44]] and apply array_rand
Now I want to draw a number from the interval [$left,49] , how can I do that using the same array that I used before ?The array now misses value 44.
The function pick takes an array as an argument with all the numbers you have already picked. It will then pick a number between the start and the end that IS NOT in that array. It will add this number into that array and return the number.
function pick(&$picked, $start, $end) {
sort($picked);
if($start > $end - count($picked)) {
return false;
}
$pick = rand($start, $end - count($picked));
foreach($picked as $p) {
if($pick >= $p) {
$pick += 1;
} else {
break;
}
}
$picked[] = $pick;
return $pick;
}
This function will efficiently get a random number that is not in the array AND WILL NEVER INFINITELY RECURSE!
To use this like you want:
$array = array(44); // you have picked 44 for example
$num = pick($array, 1, 49); // get a random number between 1 and 49 that is not in $array
// $num will be a number between 1 and 49 that is not in $arrays
How the function works
Say you are getting a number between 1 and 10. And you have picked two numbers (e.g. 2 and 6). This will pick a number between 1 and (10 minus 2) using rand: rand(1, 8).
It will then go through each number that has been picked and check if the number is bigger.
For Example:
If rand(1, 8) returns 2.
It looks at 2 (it is >= then 2 so it increments and becomes 3)
It looks at 6 (it is not >= then 6 so it exits the loop)
The result is: 3
If rand(1, 8) returns 3
It looks at 2 (it is >= then 2 so it increments and becomes 4)
It looks at 6 (it is not >= then 6 so it exits the loop)
The result is 4
If rand(1, 8) returns 6
It looks at 2 (it is >= then 2 so it increments and becomes 7)
It looks at 6 (it is >= then 6 so it increments and becomes 8)
The result is: 8
If rand(1, 8) returns 8
It looks at 2 (it is >= then 2 so it increments and becomes 9)
It looks at 6 (it is >= then 6 so it increments and becomes 10)
The result is: 10
Therefore a random number between 1 and 10 is returned and it will not be 2 or 6.
I implemented this a long time ago to randomly place mines in a 2-dimensional array (because I wanted random mines, but I wanted to guarantee the number of mines on the field to be a certain number)
Why not just check your exceptions:
function getRand($min, $max) {
$exceptions = array(44, 23);
do {
$rand = mt_rand($min, $max);
} while (in_array($rand, $exceptions));
return $rand;
}
Note that this could result in an infinite loop if you provide a min and max that force mt_rand to return an exception character. So if you call getRand(44,44);, while meaningless, will result in an infinite loop... (And you can avoid the infinite loop with a bit of logic in the function (checking that there is at least one non-exception value in the range $min to $max)...
The other option, would be to build the array with a loop:
function getRand($min, $max) {
$actualMin = min($min, $max);
$actualMax = max($min, $max);
$values = array();
$exceptions = array(44, 23);
for ($i = $actualMin; $i <= $actualMax; $i++) {
if (in_array($i, $exceptions)) {
continue;
}
$values[] = $i;
}
return $values[array_rand($values)];
}
The simplest solution would be to just search for a random number from min to max - number of exceptions. Then just add 1 to the result for each exception lower than the result.
function getRandom($min, $max)
{
$exceptions = array(23, 44); // Keep them sorted or you have to do sort() every time
$random = rand($min, $max - count($exceptions));
foreach ($exceptions as $ex)
{
if ($ex > $random) break;
++$random;
}
return $random;
}
Runtime should be O(1+n) with n being the number of exceptions lower than the result.

Categories