Increment letters by 2 - php

I would like to increment a letter by 2. This way, A will become C, Z will become AB.
It works well when I increment by 1 with $letter++ but I can't find a way to do it.
Thanks for any help

You could use a function like this one to increment variable as many time as wished :
function increment($val, $increment = 2)
{
for ($i = 1; $i <= $increment; $i++) {
$val++;
}
return $val;
}
Usage :
$var = increment('a', 2);
var_dump($var);

You should use the functions chr(); and ord(); to get the ASCII value and return it. Example code:
$letter = 'A';
//catch Y to add a letter + reset to A
if(strtoupper(substr($letter,-1)) == 'Y'{
$letter = 'A'.substr($letter,0,strlen($letter)-1).'A';
}
//catch Z to add a letter + reset to B
else if(strtoupper(substr($letter,-1)) == 'Z'){
$letter = 'A'.substr($letter,0,strlen($letter)-1).'B';
}
//nothing to catch here
else{
$letter = substr($letter,0,strlen($letter)-1).(chr(ord(substr($letter,-1))+2));
}
// $letter = chr(ord($letter) + 2); //returns C
You should build in a function to make the jump from Z to AB and from Y to AA.

for ($i=A;$i<Z;$i++){
echo ++$i." ";
}
Try this.

Related

Number to Excel column name conversion

In Excel, column names are characters from A to Z, if there are more columns needed, it continues with AA, AB ...
I want to write a function, that converts integers to those excel column names.
0 .... A
25 ... Z
26 ... AA
702 ... AAA
.
.
.
The solution I came up with is working up to AZ, but I want it to work further.
function indexToXlxsColumn($index, $prefix="")
{
if($index < 26)
{
return $prefix.chr($index+65);
}else{
return indexToXlxsColumn($index % 26, "A");
}
}
How to adapt this function to work for every index without producing spaghetti code?
Here is the probleme
return indexToXlxsColumn($index % 26, "A");
You away set the next floor prefix to A , what happends when u have
input = 53 , the resultat should be "BB"
Code on paper
function indexToXlxsColumn($index, $prefix="")
{
if($index < 26) // 53 isnt less then 26
// second loop , 1 is less then 26
{
return $prefix.chr($index+65);
// $prefix = A
// chr($index+65) = B
// return "A"."B" ;
}else{
return indexToXlxsColumn($index % 26, "A");
// indexToXlxsColumn(53 % 26, "A") -> (1, "A")
}
}
---UPDATE---
Follow the ask here is the answer
function indexToXlxsColumn($index, $suffix ="")
{
if($index < 26){
return chr($index+65).$suffix ;
}
return indexToXlxsColumn(($index - $index%26)/26-1, chr($index%26+65).$suffix );
}
One of the implementations:
function indexToXlxsColumn($index)
{
$name = '';
while($index > 0) {
$mod = ($index - 1) % 26;
$name = chr(65 + $mod).$name;
$index = (int)(($index - $mod) / 26);
}
return $name;
}
// echo indexToXlxsColumn(26); // Z
echo indexToXlxsColumn(33); // AG
// echo indexToXlxsColumn(800); // ADT
I would do it a little differently. It bothered me to work with chr(). So I once stored the alphabet in a string and iterated over it until the index was successfully resolved.
max "zz"
<?php
function getIn($i) {
$str = 'abcdefghijklmnopqrstuvwxyz';
$r = (int) floor($i / 26) ;
$c = $i % 26;
return ($r) < 1 ? $str[$c] : $str[$r-1] . $str[$c];
}
echo getIn(52); // output: "ba"
Update with max "zzz"
function getIn($i) {
$str = 'abcdefghijklmnopqrstuvwxyz';
$r = (int) floor($i / 26);
$rr = $r >= 27 ? $r - 27 : null;
$c = $i % 26;
if ( $rr !== null) {
return $str[$c] : $str[$r-1] . $str[$c];
}
return ($r) < 1 ? $str[$c] : $str[$r-1] . $str[$c];
}
echo getIn(800); // ddu
echo getIn(1377); // zzz
PLACEHOLDER parts of the code return squiffy values! Needs review before using in the wild!!
In case anyone wants a utility function that does this, here's a python implementation:
n2AA performs the calculation from numeric to "AA" format.
def n2AA(n):
n=n-1
alphabet=["_"] + [chr(c+65) for c in range(0,26)]
w=len(alphabet)-1
accum=[]
for e in range(5,-1,-1):
expon=w**e
s=(n//expon)
r=n%expon
n=n-(s*expon)
if e>0:
accum.append(alphabet[s])
else:
accum.append(alphabet[s+1])
return "".join([a for a in accum if a != "_"])
And AA2n performs the inverse function, starting with "AA" format and returning the column number (starting at 1).
def AA2n(AA):
alphabet=["_"] + [chr(c+65) for c in range(0,26)]
w=len(alphabet)-1
accum=[]
for c in range(0,len(AA)):
expon=w**(len(AA)-1-c)
accum.append((alphabet.index(AA[c]))*expon)
return sum(accum)

How I can create my own pow function using PHP?

I want to create a function in which I put two values (value and its power - Example function: multiply(3, 3) result 27). I have tried so far but failed, I have searched using Google but I have been unable to find any result because I don't know the name of this function.
What I want exactly:
3,3 => 3 x 3 x 3 = 27
4,4 => 4 x 4 x 4 x 4 = 256
What I tried:
function multiply($value,$power){
for($x = 1; $x <= $value; $x++ ){
return $c = $value * $power;
}
}
echo multiply(3,3);
The answer has already been accepted, but I had to come here and say that all answers here use a bad algorithm. There are better ones. Including very simple ones, like exponentiation by squaring that reduces the complexity from O(power) to O(log(power)).
The idea is to square the base while dividing the exponent by 2. For example
3^8 = 9^4 = 81^2 = 6561
There is a special case when the exponent is odd. In this case, you must store a separate variable to represent this factor:
2^10 = 4^5 = 16^2 * 4 = 256 * 4 = 1024
PHP isn't one of my strong skills, but the final algorithm is as simple as:
function multiply($value, $power){
$free = 1;
while ($power > 1) {
if ($power % 2 == 1)
$free *= $value;
$value *= $value;
$power >>= 1; //integer divison by 2
}
return $value*$free;
}
echo multiply(3, 3) . "\n";
echo multiply(2, 10) . "\n";
echo multiply(3, 8) . "\n";
Oopsika, couldn't have asked a more obvious question. Use the built-in function named pow (as in a lot of languages)
echo pow(3, 3);
Edit
Let's create our own function.
function raiseToPower($base,$exponent)
{
// multiply the base to itself exponent number of times
$result=1;
for($i=1;$i<=$exponent;$i++)
{
$result = $result * $base;
}
return $result;
}
function exponent($value,$power)
{
$c=1;
for($x = 1; $x <= $power; $x++ )
{
$c = $value * $c;
}
return $c;
}
If you have PHP >= 5.6 you can use the ** operator
$a ** $b Exponentiation Result of raising $a to the $b'th power.
echo 2 ** 3;
If you have PHP < 5.6 you can use pow:
number pow ( number $base , number $exp )
echo pow(2, 3);
Your own function is:
function multiply($value, $power) {
$result = 1;
for($x = 1; $x <= $power; $x++){
$result *= $value;
}
return $result;
}
echo multiply(3,3);
Read more at:
http://php.net/manual/en/language.operators.arithmetic.php
http://php.net/manual/en/function.pow.php
Just try to run this code I hope your problem will be solved.
If you defining any function then you have to call it return value.
<?php
function multiply($value,$exp)
{ $temp=1;
if($exp==0)
return $temp;
else
{
for($i=1;$i<=$exp;$i++)
$temp=$temp*$value;
return $temp;
}
}
echo multiply(5,6);
?>
echo "Enter number (will be mutiplied):".PHP_EOL;
$value = (int) readline("> ");
echo "Enter number for multiplier:".PHP_EOL;
$multiplier = (int) readline("> ");
function power(int $i, int $n):int {
$result =1;
for ($int = 1; $int < $n; $int++){
$result *= $i;
}
return $result;
}
echo power($value,$multiplier);

How to dynamically generate Excel column numbers in php?

I'm writing an export to excel & have a dynamic number of columns, i.e. I won't know how many columns will be needed before I run the query so I need to dynamically assign the column numbers like below:
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'value')
->setCellValue('A2', 'value')
->setCellValue('B2', 'value')
->setCellValue('C2', 'value')
//...etc...
->setCellValue('AA2', 'value')
->setCellValue('AB2', 'value')
->setCellValue('AC2', 'value')
//...etc...
how can I do this with php?
UPDATE
sorry, the column naming pattern is:
A, B, C, .. AA, AB, AC ... BA, BB, BC... etc, the number suffix is actually the row. and no, the 'value would actually be populated from some query data setting my values would look more like:
$i=1;
while($result= $query->fetch_assoc()){
->setCellValue($col.$i, $result['whatever'])
$i++;
}
I just don't know how to get the column letters to increment in that pattern.
Simplest answer is
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
echo Coordinate::stringFromColumnIndex(5) // return E
echo Coordinate::columnIndexFromString('AA') // returns 27
Optimized Function
function columnFromIndex($number){
if($number === 0)
return "A";
$name='';
while($number>0){
$name=chr(65+$number%26).$name;
$number=intval($number/26)-1;
if($number === 0){
$name="A".$name;
break;
}
}
return $name;
}
If you don't know how many columns/rows you're going to be working with in advance, how can you expect to use the fluent interface in this way?
Following your edit of the question, you might do something like:
$i = 1;
while($result = $query->fetch_assoc()){
$col = 'A';
foreach($result as $value) {
$objPHPExcel->getActiveSheet()->setCellValue($col++.$i, $value);
}
$i++;
}
However, you might consider taking another approach, and using the fromArray() method to populate your data
$i = 1;
while($result = $query->fetch_assoc()){
$objPHPExcel->getActiveSheet()->fromArray('A'.$i++, $result);
}
Maybe so late, and i dont know if there's a better solution but, i make this recursive function to solve this problem
private function getLastColumn($last){ //last represent how mouch X axis spaces
//you want to jump
$max = 26; //Max characters (in number) that you cant jump, ('z´)
$inicial = 'A';
$col = '';
if ($last > $max) //if last is bigger than last you should recall the function
{
$last = $last - $max; //discount the max to the last
$letterAscii = ord($inicial); //tansform the charcter to to number
$letterAscii += ($last - 1); // add last -1(-1 to stay in A to keep the
//base 1)
$col = chr($letterAscii); // int to ascci
$col = $col.$this->getLastColumn($last); // recall the funcion and concat
//the result
}else{
$letterAscii = ord($inicial); // same as adove
$letterAscii += ($last - 1);
$col = chr($letterAscii); //only pass the result to col
}
return $col; //return coll
}
and with this if you need 27 spaces to de right you will get 'AA'
if there is a better solution teld me :)
i think is too late, but for my snippet
i make this function,
function number_to_column($num) {
$column_name = array();
for($i=0;$i<=$num;$i++) {
$numeric = $i % 26;
$letter = chr(65 + $numeric);
$num2 = intval($num / 26);
if ($num2 > 0) {
if($i<26) {
$v_column = $letter;
}
if($i>25 && $i<52) {
$v_column = 'A'.$letter;
}
if($i>51) {
$v_column = 'B'.$letter;
}
$column_name[] = $v_column;
} else {
$v_column = $letter;
$column_name[] = $v_column;
}
}
return $column_name;
}
then we can use it like this
$column_name = number_to_column(count($array[0])-1);
the $column_name will result excel row name,

Calculating Nth root with bcmath in PHP

We are looking for the Nth root in PHP. We need to do this with a very large number, and the windows calculator returns 2. With the following code we are getting 1. Does anybody have an idea how this works?
echo bcpow(18446744073709551616, 1/64);
Well it seems that PHP and the BC lib has some limits, and after searching on the internet i found this interesting article/code:
So you should use this function:
<?php
function NRoot($num, $n) {
if ($n<1) return 0; // we want positive exponents
if ($num<=0) return 0; // we want positive numbers
if ($num<2) return 1; // n-th root of 1 or 2 give 1
// g is our guess number
$g=2;
// while (g^n < num) g=g*2
while (bccomp(bcpow($g,$n),$num)==-1) {
$g=bcmul($g,"2");
}
// if (g^n==num) num is a power of 2, we're lucky, end of job
if (bccomp(bcpow($g,$n),$num)==0) {
return $g;
}
// if we're here num wasn't a power of 2 :(
$og=$g; // og means original guess and here is our upper bound
$g=bcdiv($g,"2"); // g is set to be our lower bound
$step=bcdiv(bcsub($og,$g),"2"); // step is the half of upper bound - lower bound
$g=bcadd($g,$step); // we start at lower bound + step , basically in the middle of our interval
// while step!=1
while (bccomp($step,"1")==1) {
$guess=bcpow($g,$n);
$step=bcdiv($step,"2");
$comp=bccomp($guess,$num); // compare our guess with real number
if ($comp==-1) { // if guess is lower we add the new step
$g=bcadd($g,$step);
} else if ($comp==1) { // if guess is higher we sub the new step
$g=bcsub($g,$step);
} else { // if guess is exactly the num we're done, we return the value
return $g;
}
}
// whatever happened, g is the closest guess we can make so return it
return $g;
}
echo NRoot("18446744073709551616","64");
?>
Hope this was helpful ...
I had problems with HamZa's solution getting to work with arbitrary precission, so i adopted it a little.
<?php
function NthRoot($Base, $NthRoot, $Precision = 100) {
if ($NthRoot < 1) return 0;
if ($Base <= 0) return 0;
if ($Base < 2) return 1;
$retVal = 0;
$guess = bcdiv($Base, 2, $Precision);
$continue = true;
$step = bcdiv(bcsub($Base, $guess, $Precision), 2, $Precision);
while ($continue) {
$test = bccomp($Base, bcpow($guess, $NthRoot, $Precision), $Precision);
if ($test == 0) {
$continue = false;
$retVal = $guess;
}
else if ($test > 0) {
$step = bcdiv($step, 2, $Precision);
$guess = bcadd($guess, $step, $Precision);
}
else if ($test < 0) {
$guess = bcsub($guess, $step, $Precision);
}
if (bccomp($step, 0, $Precision) == 0) {
$continue = false;
$retVal = $guess;
}
}
return $retVal;
}

IMEI validation function

Does anybody know a PHP function for IMEI validation?
Short solution
You can use this (witchcraft!) solution, and simply check the string length:
function is_luhn($n) {
$str = '';
foreach (str_split(strrev((string) $n)) as $i => $d) {
$str .= $i %2 !== 0 ? $d * 2 : $d;
}
return array_sum(str_split($str)) % 10 === 0;
}
function is_imei($n){
return is_luhn($n) && strlen($n) == 15;
}
Detailed solution
Here's my original function that explains each step:
function is_imei($imei){
// Should be 15 digits
if(strlen($imei) != 15 || !ctype_digit($imei))
return false;
// Get digits
$digits = str_split($imei);
// Remove last digit, and store it
$imei_last = array_pop($digits);
// Create log
$log = array();
// Loop through digits
foreach($digits as $key => $n){
// If key is odd, then count is even
if($key & 1){
// Get double digits
$double = str_split($n * 2);
// Sum double digits
$n = array_sum($double);
}
// Append log
$log[] = $n;
}
// Sum log & multiply by 9
$sum = array_sum($log) * 9;
// Compare the last digit with $imei_last
return substr($sum, -1) == $imei_last;
}
Maybe can help you :
This IMEI number is something like this: ABCDEF-GH-IJKLMNO-X (without “-” characters)
For example: 350077523237513
In our example ABCDEF-GH-IJKLMNO-X:
AB is Reporting Body Identifier such as 35 = “British Approvals Board of Telecommunications (BABT)”
ABCDEF is Type Approval Code
GH is Final Assembly Code
IJKLMNO is Serial Number
X is Check Digit
Also this can help you : http://en.wikipedia.org/wiki/IMEI#Check_digit_computation
If i don't misunderstood, IMEI numbers using Luhn algorithm . So you can google this :) Or you can search IMEI algorithm
Maybe your good with the imei validator in the comments here:
http://www.php.net/manual/en/function.ctype-digit.php#77718
But I haven't tested it
Check this solution
<?php
function validate_imei($imei)
{
if (!preg_match('/^[0-9]{15}$/', $imei)) return false;
$sum = 0;
for ($i = 0; $i < 14; $i++)
{
$num = $imei[$i];
if (($i % 2) != 0)
{
$num = $imei[$i] * 2;
if ($num > 9)
{
$num = (string) $num;
$num = $num[0] + $num[1];
}
}
$sum += $num;
}
if ((($sum + $imei[14]) % 10) != 0) return false;
return true;
}
$imei = '868932036356090';
var_dump(validate_imei($imei));
?>
IMEI validation uses Luhn check algorithm. I found a link to a page where you can validate your IMEI. Furthermore, at the bottom of this page is a piece of code written in JavaScript to show how to calculate the 15th digit of IMEI and to valid IMEI. I might give you some ideas. You can check it out here http://imei.sms.eu.sk/index.html
Here is a jQuery solution which may be of use: https://github.com/madeinstefano/imei-validator
good fun from kasperhartwich
function validateImei($imei, $use_checksum = true) {
if (is_string($imei)) {
if (ereg('^[0-9]{15}$', $imei)) {
if (!$use_checksum) return true;
for ($i = 0, $sum = 0; $i < 14; $i++) {
$tmp = $imei[$i] * (($i%2) + 1 );
$sum += ($tmp%10) + intval($tmp/10);
}
return (((10 - ($sum%10)) %10) == $imei[14]);
}
}
return false;
}

Categories