Printing pattern sequence of 3 characters - php

I would like to print pattern of 3 characters using PHP. Like aaa, aab, aac .... zzz.
Now, I am using these PHP code but it is printing randomly instead sequence.
$i = 1;
$chars = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
while($i > 0){ $current = $chars[rand(0,25)].$chars[rand(0,25)].$chars[rand(0,25)]; }

Quick but sloppy
$i=0;
$j=0;
$k=0;
while($i<26){
while($j<26){
while($k<26){
echo $chars[$i] . $chars[$j] . $chars[$k];
$k++;
}
$j++;
$k=0;
}
$i++;
$j=0;
$k=0;
}

Count from 0 to 26^3 -1. Then convert your numbers to base 26 , replace numbers by letters as needed, and prefix with "a" or "aa" if the converted result is single or double digit.
Use this function: string base_convert ( string $number , int $frombase , int $tobase )
I am not going to code it all out for you. You need to learn from it.

I got it in c#.
string sample = "AAA";
char[] chars = sample.ToCharArray();
char first = chars[0];
char second = chars[1];
char third = chars[2];
if (first == second && first == third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
return $"empty";
}
if (first == second && first != third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
else
{
second++;
third = 'A';
return $"{first}{second}{third}";
}
}//"ABA";
if (first != second && first == third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
else
{
second++;
third = 'A';
return $"{first}{second}{third}";
}
}
if (first != second && first != third && second != third)
{
third++;
bool isAlphaBet = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBet)
{
return $"{first}{second}{third}";
}
else
{
second++;
third = 'A';
bool isAlphaBetSecond = Regex.IsMatch(second.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetSecond)
{
return $"{first}{second}{third}";
}
else
{
second = 'A';
first++;
bool isAlphaBetFirst = Regex.IsMatch(first.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetFirst)
{
return $"{first}{second}{third}";
}
else
{
return $"empty";
}
}
}
}
if (first != second && second == third)
{
third++;
bool isAlphaBetThird = Regex.IsMatch(third.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetThird)
{
return $"{first}{second}{third}";
}
else
{
third = 'A';
second++;
bool isAlphaBetSecond = Regex.IsMatch(second.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetSecond)
{
return $"{first}{second}{third}";
}
else
{
second = 'A';
first++;
bool isAlphaBetFirst = Regex.IsMatch(first.ToString(), "[a-z]", RegexOptions.IgnoreCase);
if (isAlphaBetFirst)
{
return $"{first}{second}{third}";
}
else
{
return $"empty";
}
}
}
}
return $"{first}{second}{third}";

If you need to print random - like 'aaa' or 'vvv' or 'ddd' - try to use
$char = $chars[rand(0,25)];
echo $current = $char.$char.$char;
If you want to print 'aaa','bbb','ccc',...- use
for ($i = 0; $i < 26; $i++) {
$char = $chars[$i];
echo $current = $char.$char.$char;
}

Related

How to take a single record from an array

I have a function that counts the number of points for each letter. I want her to count the points for each word. See this is my code:
function getValue() {
$letter = $this->getName(); // String from FORM
// Switch looks at a letter and assigns the value points for that letter
switch(true){
case($letter == 'a'||$letter == 'e'||$letter == 'i'||$letter == 'o'||$letter == 'u'||$letter == 'l'||$letter == 'n'||$letter == 's'||$letter == 't'||$letter == 'r'):
return 1;
case($letter == 'd'||$letter == 'g'):
return 2;
case($letter == 'b'||$letter == 'c'||$letter == 'm'||$letter == 'p'):
return 3;
case($letter == 'f'||$letter == 'h'||$letter == 'v'||$letter == 'w'||$letter == 'y'):
return 4;
case($letter == 'k'):
return 5;
case($letter == 'j'||$letter == 'x'):
return 8;
case($letter == 'q'||$letter == 'z'):
return 10;
default:
return 0;
}
}
function makeWordsPoint() {
$total_word_points = 0;
$words = $this->word_for_letters;
foreach ($words as $word) {
$total_word_points = $word->getValue();
}
echo $word . "=" . $total_word_points
}
How I can do it? Thanks for help
EDIT:
Okey, look now. There is my two classes Word and Letter
<?php
class Word
{
private $word;
private $words_with_points = array();
function __construct($user_letters)
{
$this->word = $user_letters;
// creates array of object word for letters
$this->word_for_letters = $this->makeWordForLetters();
// creates array of letter objects for the word
$this->words_with_points = $this->makeWordsWithPoints();
}
function makeWordForLetters()
{
$word_objects = array();
$word = $this->getWord();
$file = file_get_contents( __DIR__."/../src/dictionary.txt");
$items = explode("\n", $file);
$letters = str_split($word);
foreach ($items as $item) {
$list = $letters;
// remove the original word (once)
$thisItem = preg_replace("/$word/", '', $item, 1);
for ($i = 0; $i < strlen($thisItem); $i++) {
$index = array_search($thisItem[$i], $list);
if ($index === false) {
continue 2; // letter not available
}
unset($list[$index]); // remove the letter from the list
}
array_push($word_objects, $item);
}
return $word_objects; // passed!
}
function makeWordsWithPoints()
{
$word = $this->makeWordForLetters();
$letter_objects = array();
foreach ($word as $character) {
array_push($letter_objects, new Letter($character));
}
return $letter_objects;
}
function getWord()
{
return $this->word;
}
function getWordForLetters()
{
return $this->word_for_letters;
}
function getWordsWithPoints()
{
return $this->words_with_points;
}
}
?>
<?php
class Letter
{
private $name;
private $value;
function __construct($letter)
{
$letter = strtolower($letter);
$this->name = $letter;
$this->value = $this->setValue();
}
function getName()
{
return $this->name;
}
function getValue()
{
return $this->value;
}
function setValue()
{
$letter = $this->getName();
switch(true){
case($letter == 'a'||$letter == 'e'||$letter == 'i'||$letter == 'o'||$letter == 'u'||$letter == 'l'||$letter == 'n'||$letter == 's'||$letter == 't'||$letter == 'r'):
return 1;
case($letter == 'd'||$letter == 'g'):
return 2;
case($letter == 'b'||$letter == 'c'||$letter == 'm'||$letter == 'p'):
return 3;
case($letter == 'f'||$letter == 'h'||$letter == 'v'||$letter == 'w'||$letter == 'y'):
return 4;
case($letter == 'k'):
return 5;
case($letter == 'j'||$letter == 'x'):
return 8;
case($letter == 'q'||$letter == 'z'):
return 10;
default:
return 0;
}
}
}
?>
And now when I write in now letters like this: loso function makeWordForLetters() search in my array correctly words for this letters and I display this words with points by makeWordsWithPoint like this:
l - 1
lo - 0
loo - 0
loos - 0
los - 0
oslo - 0
s - 1
solo - 0
But as you can see the score is incorrect because it displays the result for a single letter and not for a word.
How can I solve this problem?
take it as string, then use preg_split function, count new array length.eg:
$string="php教程#php入门:教程#字符串:多分隔符#字符串:拆分#数组";
$arr = preg_split("/(#|:)/",$string);
print_r($arr);
Try this code instead. I think it's cleaner.
<?php
// set the score of each char into array
const SCORES = [
// 1
'a'=> 1,
'e' => 1,
'i' => 1,
'o' => 1,
'u' => 1,
'l' => 1,
'n' => 1,
's' => 1,
't' => 1,
'r' => 1,
// 2
'd'=> 2,
'g'=> 2,
// 3
'b'=> 3,
'c'=> 3,
'm'=> 3,
'p'=> 3,
// 4
'f'=> 4,
'h'=> 4,
'v'=> 4,
'w'=> 4,
'y'=> 4,
// 5
'k'=> 5,
// 8
'j'=> 8,
'x'=> 8,
// 10
'q'=> 10,
'z'=> 10,
];
$word = 'abcdef'; // get the string from the request here
# print_r($word);
$chars = str_split($word); // split string into array of chars
# print_r($chars);
$scores = array_map(function($char) { // create a scores array that convert char into value
return SCORES[strtolower($char)] ?? 0; // get the score of each char and set to the array, if not exist set to 0
}, $chars);
# print_r($scores);
$totalScore = array_sum($scores); // get the sum of the scores
echo $word . "=" . $totalScore;
Let me know if you have any question.

PHP - Check if a string is a rotation of another string

Need to write a code block which check is one string is a rotation of another.
Looked at loads of posts on here and it is all in Java or C++ but I need to do it in PHP.
I have tried a few different things, trying to work from the C++ and Java examples but I am not having any luck, here is my current code:
<?php
function isSubstring($s1, $s2) {
if(strlen($s1) != strlen($s2)) {
return false;
}
if(WHAT TO PUT HERE) {
echo "it is!";
} else {
echo "nope";
}
}
isSubstring("hello", "helol");
?>
Many ways available. Here one more using built-in function count_chars on both strings, and then comparing both resulting arrays :
function isSubstring($s1, $s2) {
if (strlen($s1) != strlen($s2)) {
echo "nope";
return;
}
$s1cnt = count_chars($s1, 1);
$s2cnt = count_chars($s2, 1);
if($s1cnt === $s2cnt) {
echo "it is!";
} else {
echo "nope";
}
}
Edit : as MonkeyZeus pointed out, beware of comparison with multibyte characters. It may bite a little bit :
isSubstring('crढap', 'paࢤrc');
will give true as answer. ढ is UTF-8 indian devanagari three byte char : E0 A2 A4 and ࢤ is also three byte chars (arabic) : E0 A4 A2, and the count_chars function counts the individual bytes. So it would be safe to use if chars are from only one language, else get some headache pills...
It seems to me that to manage this kind of things we need to have chars that are made of 3 bytes.
I would go for something like this:
function isSubstring($s1, $s2)
{
// If the strings match exactly then no need to proceed
if($s1 === $s2)
{
echo "it is!";
return;
}
elseif(strlen($s1) !== strlen($s2))
{
// Strings must be of equal length or else no need to proceed
echo "nope";
return;
}
// Put each character into an array
$s1 = str_split($s1);
$s2 = str_split($s2);
// Sort alphabetically based on value
sort($s1);
sort($s2);
// Triple check the arrays against one-another
if($s1 === $s2)
{
echo "it is!";
}
else
{
echo "nope";
}
}
Here is a multibyte safe function to compare the two strings:
function mb_isAnagram($s1, $s2) {
if (strlen($s1) != strlen($s2)) {
return false;
} else {
$c1 = preg_split('//u', $s1, null, PREG_SPLIT_NO_EMPTY);
$c2 = preg_split('//u', $s2, null, PREG_SPLIT_NO_EMPTY);
sort($c1);
sort($c2);
if ($c1 === $c2) {
return true;
} else {
return false;
}
}
}
You could split each string and sort it, like this:
$split1 = unpack("C*",$s1);
asort($split1);
Then you can traverse both arrays comparing the values.
<?php
function isRotationalString($str1,$str2){
$len = strlen($str1);
if($str1 === $str2){
return true;
}else{
if($len == strlen($str2)){
$flag = true;
for($i=0;$i<$len;$i++){
if($str1[0]==$str2[$i]){
$tst = $i;$start = true;break;
}
}
if($start){
for($j=0;$j<$len;$j++){
$m = $j+$tst;
if($m < $len){
if($str1[$j] != $str2[$m]){
$flag = false;break;
}
}else{
if($m>=$len)
{
$k = $m - $len;
if($str1[$j] != $str2[$k]){
$flag = false;break;
}
}
}
}
}else{
$flag = false;
}
return $flag;
}
}
}
echo isRotationalString("abcd","bcda")?'It is':'It is not';
?>
above script will check whether a string is a rotation of another string or not?
isRotationalString("abcd","bcda") => It is
isRotationalString("abcd","cbda") => It is Not
This is the function for string rotation.
echo isRotationalString("abcdef","efabcd")?'It is':'It is not';
function isRotationalString($str1,$str2){
$len = strlen($str1);
if($str1 === $str2){
return true;
} else {
if($len == strlen($str2)) {
$stringMatchedArr1 = $stringMatchedArr2 = [];
for($i=0; $i<$len; $i++) {
$substr = substr($str1,$i );
$pos = strpos($str2, $substr);
if($pos !== false) {
$stringMatchedArr1[] = $substr;
}
}
for($j=1; $j <= $len; $j++) {
$substr = substr($str1, 0, $j );
$pos = strpos($str2, $substr);
if($pos !== false) {
$stringMatchedArr2[] = $substr;
}
}
foreach($stringMatchedArr2 as $string1) {
foreach($stringMatchedArr1 as $string2) {
if($string1.$string2 == $str1)
return true;
}
}
}
}
}
I would sort the characters in the strings by making it an array and then imploding them to a string again.
if (sort(str_split($s1)) == sort(str_split($s2))) {
That would do the trick in one line.
Edit: Thanks Don't Panic, edited my answer!

Is there anyway to repeat the biggest segment of continuous segment of repeat using php?

I want to put the input like "RKKRRRRK" and try to get the output like largest continuous segment.. Suppose my input may be "RKKKR" then my program will display 'KKK' is the largest continuous segment.. and then it also display the count is 3..
I've already write the code for counting 'R' values.. now i want this program also... need help anyone help me.. thanks in advance.
Here the code:-
<?php
function numberOfR($string1)
{
for($i=0;$i <strlen($string1);$i++)
{
if($string1[$i]!='K')
{
$count++;
}
}
return $count;
}
$return_value= numberOfR("RKKRK");
echo "R's count is:";
echo $return_value;
?>
<?php
function getLongetSegment($string) {
$currentSegmentChar='';
$currentSegment="";
$biggestSegment="";
$current_length=0;
$biggest_length=0;
for($i=0;$i<strlen($string);$i++) {
$char = $string[$i];
if($char != $currentSegmentChar || $currentSegmentChar == '') {
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
$biggest_length = $current_length;
}
$currentSegmentChar = $char;
$currentSegment = $char;
$current_length = 1;
}
elseif($currentSegmentChar != '') {
$currentSegment .= $char;
$current_length++;
}
}
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
}
return array("string" => $biggestSegment,"length" => $biggest_length);
}
print_r(getLongetSegment("RKKRGGG"));
?>
Result: GGG
You can use preg_match_all over here as
preg_match_all('/(.)\1+/i','RKKRRRRK',$res);
usort($res[0],function($a,$b){
return strlen($b) - strlen($a);
});
echo $res[0][0];
Not sure if I understood this quite right. Something like this:
function maxCharSequece($string1)
{
$maxSeq = $seq = 0;
$maxChar = $lastChar = null;
for( $i = 0; $i < strlen($string1); $i++ )
{
$c = $string1[$i];
if (!$lastChar) $lastChar = $c;
if ( $lastChar == $c ){
if ( ++$seq > $maxSeq ) $maxChar = $lastChar;
}
else {
$maxSeq = $seq;
$seq = 0;
}
}
return $maxChar;
}
You can use preg_replace_callback to receive all continuous segments and select the longest
$sq = '';
preg_replace_callback('/(.)\1+/',
function ($i) use (&$sq) {
if(strlen($i[0]) > strlen($sq)) $sq = $i[0];
}, $str);
echo $sq . " " . strlen($sq);

Does a PHP function exist where I can transform a number into a smaller string?

Lets say I have a function named transform and I run the following:
echo transform(1);
Would output "a"
echo transform(26);
Would output "z"
echo transform(27);
Would output "A"
echo transform(345345);
Would output a string combined with both letters (upper and lower case) and numbers that is shorter than 6 characters.
Does such a function exist?
Simple use a base conversion.
<?php
function convBase($numberInput, $fromBaseInput, $toBaseInput)
{
if ($fromBaseInput==$toBaseInput) return $numberInput;
$fromBase = str_split($fromBaseInput,1);
$toBase = str_split($toBaseInput,1);
$number = str_split($numberInput,1);
$fromLen=strlen($fromBaseInput);
$toLen=strlen($toBaseInput);
$numberLen=strlen($numberInput);
$retval='';
if ($toBaseInput == '0123456789')
{
$retval=0;
for ($i = 1;$i <= $numberLen; $i++)
$retval = bcadd($retval, bcmul(array_search($number[$i-1], $fromBase),bcpow($fromLen,$numberLen-$i)));
return $retval;
}
if ($fromBaseInput != '0123456789')
$base10=convBase($numberInput, $fromBaseInput, '0123456789');
else
$base10 = $numberInput;
if ($base10<strlen($toBaseInput))
return $toBase[$base10];
while($base10 != '0')
{
$retval = $toBase[bcmod($base10,$toLen)].$retval;
$base10 = bcdiv($base10,$toLen,0);
}
return $retval;
}
echo convBase('345345','0123456789','0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789');
?>

PHP URL Shortener error

I have this PHP code which is supposed to increase a URL shortener mask on each new entry.
My problem is that it dosen't append a new char when it hits the last one (z).
(I know incrementing is a safety issue since you can guess earlier entries, but this is not a problem in this instance)
If i add 00, it can figure out 01 and so on... but is there a simple fix to why it won't do it on its own?
(The param is the last entry)
<?php
class shortener
{
public function ShortURL($str = null)
{
if (!is_null($str))
{
for($i = (strlen($str) - 1);$i >= 0;$i--)
{
if($str[$i] != 'Z')
{
$str[$i] = $this->_increase($str[$i]);
#var_dump($str[$i]);
break;
}
else
{
$str[$i] = '0';
if($i == 0)
{
$str = '0'.$str;
}
}
}
return $str;
}
else {
return '0';
}
}
private function _increase($letter)
{
//Lowercase: 97 - 122
//Uppercase: 65 - 90
// 0 - 9 : 48 - 57
$ord = ord($letter);
if($ord == 122)
{
$ord = 65;
}
elseif ($ord == 57)
{
$ord = 97;
}
else
{
$ord++;
}
return chr($ord);
}
}
?>
Effectively, all you are doing is encoding a number into Base62. So if we take the string, decode it into base 10, increment it, and reencode it into Base62, it will be much easier to know what we are doing, and the length of the string will take care of itself.
class shortener
{
public function ShortURL($str = null)
{
if ($str==null) return 0;
$int_val = $this->toBase10($str);
$int_val++;
return $this->toBase62($int_val);
}
public function toBase62($num, $b=62) {
$base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$r = $num % $b ;
$res = $base[$r];
$q = floor($num/$b);
while ($q) {
$r = $q % $b;
$q =floor($q/$b);
$res = $base[$r].$res;
}
return $res;
}
function toBase10( $num, $b=62) {
$base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$limit = strlen($num);
$res=strpos($base,$num[0]);
for($i=1;$i<$limit;$i++) {
$res = $b * $res + strpos($base,$num[$i]);
}
return $res;
}
}

Categories