How can I calculate the sum of "letter numbers" in a string? - php

Is there any built-in PHP function through which I can count the sum of indexes of letters of the alphabet found in a string?
<?php
$a = "testword";
echo "Count of Characters is: " . strlen($a);
?>
Now I want to get a cumulative "total" of this word.
e.g.
A is the first letter of the alphabet so it maps to 1
B is the second letter of the alphabet so it maps to 2
C is the third letter of the alphabet so it maps to 3
D is the fourth letter of the alphabet so it maps to 4
So the word ABCD gives 1+2+3+4=10
Similarly I need a function for "testword" or any word.

function WordSum($word)
{
$cnt = 0;
$word = strtoupper(trim($word));
$len = strlen($word);
for($i = 0; $i < $len; $i++)
{
$cnt += ord($word[$i]) - 64;
}
return $cnt;
}
var_dump(WordSum("testword"));

Just to show a totally different method, for the sheer pleasure of demonstrating some of PHP's array functions:
$data = "testword";
$testResult = array_values(array_merge(array_fill_keys(range('A','Z'),
0
),
array_count_values(str_split(strtoupper($data)
)
)
)
);
$wordCount = 0;
foreach($testResult as $letterValue => $letterCount) {
$wordCount += ++$letterValue * $letterCount;
}
var_dump($wordCount);

$a = "test";
$b = "word";
echo (strlen($a) + strlen($b));

Related

How can I grab the index of where the longest identical consecutive portion of a string begins

I'd like the code to output index 6 since d is the starting point in terms of the longest identical consecutive portion in the string.
Not sure what I'm doing wrong here but it's currently returning 3 instead. Seems like I'm going in the right direction but something is missing but I can't pinpoint what.
Any feedback is appreciated! :)
$str = "abbcccddddcccbba";
$array = preg_split('/(.)(?!\1|$)\K/', $str);
$lengths = array_map('strlen', $array);
$maxLength = max($lengths);
$ans = array_search($maxLength, $lengths); // returns 3 but need it to return 6
echo $ans;
$lengths = array_map('strlen', $array);
Above line has only lengths of adjacent similar characters. array_search on max of those lengths will only yield the index where the maximum length is stored. It is totally unrelated with getting the index 6 of your string. If you still wish to get it, you will have to array_sum till that index to get the start index in the actual string.
Snippet:
<?php
$str = "abbcccddddcccbba";
$array = preg_split('/(.)(?!\1|$)\K/', $str);
$lengths = array_map('strlen', $array);
$maxLength = max($lengths);
array_splice($lengths,array_search($maxLength, $lengths));
$ans = array_sum($lengths);
echo $ans;
Online Demo
Alternate Solution:
I would write a simple for loop that uses 2 pointers to keep track of start index of similar characters and record the frequency and start index whenever it is greater than max frequency.
Snippet:
<?php
$str = "abbcccddddcccbba";
$len = strlen($str);
$maxF = 1;
$maxIdx = $startIdx = 0;
for($i = 1; $i < $len; ++$i){
if($str[ $i ] != $str[ $i - 1] || $i === $len - 1){
if($str[ $i ] === $str[ $i - 1] && $i === $len - 1) $i++;
if($maxF < $i - $startIdx){
$maxF = $i - $startIdx;
$maxIdx = $startIdx;
}
$startIdx = $i;
}
}
echo $maxIdx;
Online Demo

Count consecutive occurence of specific, identical characters in a string - PHP

I am trying to calculate a few 'streaks', specifically the highest number of wins and losses in a row, but also most occurences of games without a win, games without a loss.
I have a string that looks like this; 'WWWDDWWWLLWLLLL'
For this I need to be able to return:
Longest consecutive run of W charector (i will then replicate for L)
Longest consecutive run without W charector (i will then replicate for L)
I have found and adapted the following which will go through my array and tell me the longest sequence, but I can't seem to adapt it to meet the criteria above.
All help and learning greatly appreciated :)
function getLongestSequence($sequence){
$sl = strlen($sequence);
$longest = 0;
for($i = 0; $i < $sl; )
{
$substr = substr($sequence, $i);
$len = strspn($substr, $substr{0});if($len > $longest)
$longest = $len;
$i += $len;
}
return $longest;
}
echo getLongestSequence($sequence);
You can use a regular expression to detect sequences of identical characters:
$string = 'WWWDDWWWLLWLLLL';
// The regex matches any character -> . in a capture group ()
// plus as much identical characters as possible following it -> \1+
$pattern = '/(.)\1+/';
preg_match_all($pattern, $string, $m);
// sort by their length
usort($m[0], function($a, $b) {
return (strlen($a) < strlen($b)) ? 1 : -1;
});
echo "Longest sequence: " . $m[0][0] . PHP_EOL;
You can achieve the maximum count of consecutive character in a particular string using the below code.
$string = "WWWDDWWWLLWLLLL";
function getLongestSequence($str,$c) {
$len = strlen($str);
$maximum=0;
$count=0;
for($i=0;$i<$len;$i++){
if(substr($str,$i,1)==$c){
$count++;
if($count>$maximum) $maximum=$count;
}else $count=0;
}
return $maximum;
}
$match="W";//change to L for lost count D for draw count
echo getLongestSequence($string,$match);

Counting possibilities in a char. combination using a consecutive repetition criterion

In PHP, given
the final string length
the range of characters it can use
min consecutive repetition count possible
how can you calculate the number of matches that fits these criteria?To draw a better picture…
$range = array('a','b','c');
$length = 2; // looking for 2 digit results
$minRep = 2; // with >=2 consecutive characters
// aa,bb,cc = 3 possibilities
another one:
$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 2; // with >=2 consecutive characters
// aaa,aab,aac,baa,caa
// bbb,bba,bbc,abb,cbb
// ccc,cca,ccb,acc,bcc
// 5 + 5 + 5 = 15 possibilities
// note that combos like aa,bb,cc are not included
// because their length is smaller than $length
last one:
$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 3; // with >=3 consecutive characters
// aaa,bbb,ccc = 3 possibilities
So basically, in the 2nd example the 3rd criterion made it catch e.g. [aa]b in aab because a was repeating consecutively more than once, whereas [a]b[a] wouldn't be a match because those a's are separate.
Needless to say, none of the variables is static.
Got it. All credit to leonbloy #mathexchange.com.
/* The main function computes the number of words that do NOT contain
* a character repetition of length $minRep (or more). */
function countStrings($rangeLength, $length, $minRep, &$results = array())
{
if (!isset($results[$length]))
{
$b = 0;
if ($length < $minRep)
$b = pow($rangeLength, $length);
else
{
for ($i = 1; $i < $minRep; $i++)
$b += countStrings($rangeLength, $length - $i, $minRep, $results);
$b *= $rangeLength - 1;
}
$results[$length] = $b;
}
return $results[$length];
}
/* This one answers directly the question. */
function printNumStringsRep($rangeLength, $length, $minRep)
{
$n = (pow($rangeLength, $length)
- countStrings($rangeLength, $length, $minRep));
echo "Size of alphabet : $rangeLength<br/>"
. "Size of string : $length<br/>"
. "Minimal repetition : $minRep<br/>"
. "<strong>Number of words : $n</strong>";
}
/* Prints :
*
Size of alphabet : 3
Size of string : 3
Minimal repetition : 2
Number of words : 15
*
*/
printNumStringsRep(3, 3, 2);
I think it is best to handle this with math.
$range = array('a','b','c');
$length = 3; // looking for 3 digit results
$minRep = 2; // with >=2 consecutive characters
$rangeLength = count($range);
$count = (pow($rangeLength,$length-$minRep+1) * ($length-$minRep+1)) - ($rangeLength * ($length-$minRep)); // is the result
Now, $count is getting true result for three situation. But it may not be general formula and need to improve.
Try to explain it:
pow($rangeLength,$length-$minRep+1)
in this, we count repetitive characters like as one. For instance, in second example that you gave, we think in aab, aa is a one character. Because, two characters need to change together. We think now there is two character like xy. So there is same possibilities for both character a, b, and c namely 3 ($rangeLength) possible value for two characters($length-$minRep+1). So 3^2=9 is possible situations for second example.
We calculate 9 is for just xy not yx. For this, we multiply length of xy ($length-$minRep+1). And then we have 18.
It can be seemed that we calculated the result, but there is a repeat in our calculation. We didn't reckon with this situation: xy => aaa and yx => aaa. For this, we calculate and substract repeated results
- ($rangeLength * ($length-$minRep))
So after this, we get result.
As i said begining of the description, this formula may need to improve.
With Math, work becomes really complex. But, there is always a way, even not beautiful as much as Math. We can create all possible strings with php and control them with regexp like below:
$range = array('a','b','c');
$length = 3;
$minRep = 2;
$rangeLength = count($range);
$createdStrings = array();
$matchedStrings = array();
function calcIndex(){
global $range;
global $length;
global $rangeLength;
static $ret;
$addTrigger = false;
// initial values
if(is_null($ret)){
$ret = array_fill(0, $length, 0);
return $ret;
}
for($i=$length-1;$i>=0;$i--){
if($ret[$i] == ($rangeLength-1)) {
if($i==0) return false;
$ret[$i] = 0;
}
else {
$ret[$i]++;
break;
}
}
return $ret;
}
function createPattern()
{
global $minRep;
$patt = '/(.)\\1{'.($minRep-1).'}/';
return $patt;
}
$pattern = createPattern();
while(1)
{
$index = calcIndex();
if($index === false) break;
$string = '';
for($i=0;$i<$length;$i++)
{
$string .= $range[$index[$i]];
}
if(!in_array($string, $createdStrings)){
$createdStrings[] = $string;
if(preg_match($pattern, $string)){
$matchedStrings[] = $string;
}
}
}
echo count($createdStrings).' is created:';
var_dump($createdStrings);
echo count($matchedStrings).'strings is matched:';
var_dump($matchedStrings);

How to loop char in php

i need to do a simple loop in php to get char from a to z.. something like:
for($i=0;$i<aNumber;$i++)
echo "char = ".intToChar($i)."<br>";
where aNumber is less then 20
You can create an array of characters easily with range [docs]:
$chars = range('a', 'z');
Or if you really only want to print them:
echo implode('<br />', range('a', 'z'));
You need understand ASCII table. See in this link. Codes for A - Z is 65 - 90 and a - z is 97 - 122.
for($i = 97; $i <= 122; $i++)
echo chr($i);
I SOLVED IN THIS WAY:
$i = 0;
$char = 'a';
$aNumber = xx;
while($i<$aNumber){
echo $char."<br>";
$char++;
$i++;
}
To return character specified by ASCII code/number use chr function. Since you want to loop from 0 to 20, then you need to add 97 to $i, 97 is ASCII code for letter a:
for($i=0;$i<$aNumber;$i++)
echo "char = ".chr($i+97)."<br>"; // + 97 because it is ASCII 'a'
If you just want to loop through those letters you can do it like this:
for($i = ord('a'); $i < ord('z'); $i++)
echo "char = ".chr($i)."<br>";
Additionally if you just want to get array of those characters you can use range function:
$chars = range('a', 'z');

PHP function to loop thru a string and replace characters for all possible combinations

I am trying to write a function that will replace characters in a string with their HTML entity encoded equivalent.
I want it to be able to go through all the possible combinations for the given string, for example:
go one-by-one
then combo i.e.. 2 at a time, then three at a time, till you get length at a time
then start in combo split, i.e.. first and last, then first and second to last
then first and last two, fist and second/third last
So for the characters "abcd" it would return:
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
etc.......... so on and so forth till there are no other combinations
Any ideas, or has anyone seen a function somewhere I could modify for this purpose?
loop from 0 to 2^length - 1. On each step, if Nth bit of the loop counter is 1, encode the Nth character
$str = 'abcd';
$len = strlen($str);
for($i = 0; $i < 1 << $len; $i++) {
$p = '';
for($j = 0; $j < $len; $j++)
$p .= ($i & 1 << $j) ? '&#' . ord($str[$j]) . ';' : $str[$j];
echo $p, "\n";
}
There are 2^n combinations, so this will get huge fast. This solution will only work as long as it fits into PHP's integer size. But really who cares? A string that big will print so many results you'll spend your entire life looking at them.
<?php
$input = 'abcd';
$len = strlen($input);
$stop = pow(2, $len);
for ($i = 0; $i < $stop; ++$i)
{
for ($m = 1, $j = 0; $j < $len; ++$j, $m <<= 1)
{
echo ($i & $m) ? '&#'.ord($input[$j]).';' : $input[$j];
}
echo "\n";
}
How about this?
<?php
function permutations($str, $n = 0, $prefix = "") {
if ($n == strlen($str)) {
echo "$prefix\n";
return;
}
permutations($str, $n + 1, $prefix . $str[$n]);
permutations($str, $n + 1, $prefix . '&#' . ord($str[$n]) . ';');
}
permutations("abcd");
?>

Categories