Sorry if a solution exists anywhere else, but I couldn't find one.
I have the following array:
$data = array(
array('a', 'b', 'c'),
array('e', 'f', 'g'),
array('w', 'x', 'y', 'z'),
);
I am trying hard to write a function that will give an array like:
a
e
w
x
y
z
f
w
x
y
z
g
w
x
y
z
b
e
w
x
y
z
f
w
x
y
z
g
w
x
y
z
c
e
w
x
y
z
f
w
x
y
z
g
w
x
y
z
The major problem here is that the number of source arrays and their lengths keep changing always. So a function should be capable of handling any data given to it.
I tried to come up with something like this:
function testfunc($data){
$arrayDepth = count($data);
foreach($data as $key=>$d){
foreach($d as $e){
echo $e . "\n";
if($key < $arrayDepth){
array_shift($data);
testfunc($data);
}
}
}
}
And the output I got was:
a
e
w
x
y
z
f
g
w
x
y
z
b
w
x
y
z
c
e
f
g
w
x
y
z
I am stuck for almost a day with no proper solution. Any help would be great! Thanks!
Recursion [Wikipedia] is your friend:
function product($arrays) {
if(count($arrays) === 1) {
return $arrays[0];
}
else {
$result = array();
foreach($arrays[0] as $value) {
$result[$value] = product(array_slice($arrays, 1));
}
return $result;
}
}
DEMO
Non-recursive version. This should run fast!
$result = end($data);
if ($result === false)
{
return false; // or Array or what makes sense for an empty array.
}
$higherArr = prev($data);
while ($higherArr !== false)
{
// Set the orignal array to be the one that you built previously.
$orig = $result;
$result = array();
foreach ($higherArr as $higherKey)
{
$result[$higherKey] = $orig;
}
$higherArr = prev($data);
}
echo 'Finished with: ' . var_export($result, true);
Related
I have problem and I hope you help me, please.
I have a code:
$a = 'A B C D E';
$b = '{A|a|AA}{B|b|BB} {E|e|EEE}';
And I want to use $b to random display $a like this:
A b C D EE
AA B C D e
A b C D EEE ...
This mean:
A replace to A, a or AA
B replace to B, b or BB
and
E replace to E, e or EEE
I hope you understand and help me, thankyou so much!!! <3
If you are not wedded to the format of $b, you could use arrays for substitutes, and pick a random item to replace.
$placeholders = 'A B C D E';
$substitutes = [
'A' => ['A','a','AA'],
'B' => ['B','b','BB'],
'E' => ['E','e','EE','EEE'],
];
$replacements = [];
foreach($substitutes as $key => $choices) {
$random_key = array_rand($choices);
$replacements[$key] = $choices[$random_key];
}
$spun = str_replace(
array_keys($replacements),
array_values($replacements),
$placeholders
);
echo $spun;
Example output:
AA b C D EE
Alternatively (if your substitutes are uniform):
function substitute($character) {
$random = rand(0,2);
$string = $random
? str_repeat($character, $random)
: strtolower($character);
return $string;
}
$spun = implode(
' ',
array_map(
'substitute',
['A','B','C','D','E']
)
);
echo $spun;
But the above will substitute for C and D also. You could easily adapt for exclusions.
I was asked to write a program in php where all the occurrences of palindromes in a given string need to be printed.
Example: For the string I O M K I L O L I K T C J I O P L L P O
The answer would be:
O P L L P O and
K I L O L I K
While doing this it should kept in mind that every palindrome that is more than 3 characters in length can be broken down into more palindromes but you just need to print out the longest size possible for each set (so, for the example string, you SHOULD NOT print LOL, LL , PLLP and ILOLI)
I tried it but could only manage to do this:
$data = 'I O M K I L O L I K T C J I O P L L P O';
$data = str_replace(' ', '', $data);
$palindromes = [];
for($i=0; $i<strlen($data); $i++ ) {
for($j=3; $j<=(strlen($data)-$i); $j++){
$word = substr($data, $i, $j);
$reverse_word = strrev($word);
if($word == $reverse_word){
print "Word: ".$word."<br/>";
}
}
}
Which gives me the following output:
Word: KILOLIK
Word: ILOLI
Word: LOL
Word: OPLLPO
Word: PLLP
Which is not the expected ouput. What should I to get rid of the strings like ILOLI, LOL PLLP because I am expected to get the longest palindrome.
According your example, you mention the answer would be O P L L P O (six characters long) and K I L O L I K (seven characters long), but later you imply only the longest palindrome should be returned?
Assuming you mean the later case, you can first assign all the palindromes to array and then sort the array, like this:
function str_length_sort($first, $second) {
return strlen($second) - strlen($first);
}
$data = 'I O M K I L O L I K T C J I O P L L P O';
$data = str_replace(' ', '', $data);
$palindromes = [];
for($i=0; $i<strlen($data); $i++ ) {
for($j=3; $j<=(strlen($data)-$i); $j++){
$word = substr($data, $i, $j);
$reverse_word = strrev($word);
if($word == $reverse_word){
$palindromes[] = $word;
}
}
}
usort($palindromes, 'str_length_sort');
$max = strlen($palindromes[0]);
foreach ($palindromes as $p) {
$length = strlen($p);
if ($length >= $max) {
echo $p;
}
}
Hope this helps.
I need to convert number in "Alphabetic" Counting System, similar to excel spreadsheets:
convert(1) == "A";
convert(2) == "B";
...
convert(26) == "Z";
convert(27) == "AA";
...
convert(52) == "AZ";
convert(53) == "BA";
...
convert(702 ) == "ZZ";
convert(703 ) == "AAA";
this is my code:
function convert($n){
if ($n> 26) {
$tmp = floor($n / 26);
$n= $n % 26;
$result = chr(($tmp - 1) + 65) . chr(($n - 1) + 65);
} else {
$result = chr(($n- 1) + 65);
}
return $result;
}
but the output is a bit off:
#, 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,
AA, AB, AC, AD, AE, AF, AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS, AT, AU, AV, AW, AX, AY,
B#, BA
I tried to tweak the numbers but I can not make it right, any suggestion for a better algorithm ?
Taking advantage of PHP's ability to increment strings as well as numbers:
function convert($number) {
$result = 'A';
for($i = 1; $i < $number; ++$i) {
++$result;
}
return $result;
}
Demo
Based on #NiettheDarkAbsol comment,
this is a quick solution if the expected calls are for small numbers:
function convert($n) {
for($out = 'A'; --$n > 0; $out++);
return $out;
}
From docs
PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's. For example, in PHP and Perl $a = 'Z'; $a++; turns $a into 'AA', while in C a = 'Z'; a++; turns a into '[' (ASCII value of 'Z' is 90, ASCII value of '[' is 91). Note that character variables can be incremented but not decremented and even so only plain ASCII alphabets and digits (a-z, A-Z and 0-9) are supported. Incrementing/decrementing other character variables has no effect, the original string is unchanged.
You can try something like this
function convert($n)
{
if ($n <= 0) return "";
$r = "";
$c = "abcdefghijklmnopqrstuvwxyz";
do {
$n -= 1;
$r = $c[$n % 26] . $r;
$n = intval($n / 26);
} while($n > 0);
return strtoupper($r);
}
var_dump(convert(703)); // AAA
var_dump(convert(52)); // AZ
The key is $n -= 1 in every loop because the number system you are using have no concept of zero (0).
Here is my code:
$answer = explode(" ", $row2['answer']);
foreach($tags as $i =>$key) {
$i >0;
echo $i.' '.$key .'</br>';
}
the output is
0 a
1 b
2 c
3 d
4 e
5 f
I'd like that the output be random, but doesn't repeat twice.
For example:
e 4
a 0
c 2
f 5
d 3
b 1
Any idea please ?
Thank you.
The simplest way I can think of to achieve this would be to use the shuffle method on an array collection. This however does not guarantee non-sequentialness:
$range = range(1,5);
shuffle($range);
foreach($range as $int){
echo $int;
}
I was trying to create a simple password generator and noted that array_rand() returns the same results. Here is the code:
<?php
function generatePass() {
$password = '';
$a = explode(' ', 'q w e r t y u i o p a s d f g h j k l z x c v b n m');
for($i=0; $i < rand(1,200); $i++) {
$password .= $a[array_rand($a)];
}
return $password;
}
$r = 0;
while ($r <= 10000) { #generating 10 000 passwords
$total[] = generatePass();
$r++;
}
echo '<pre>';
print_r($total);
echo '</pre>';
?>
The $total array basically contains the same results repeated over and over again; if I refresh the page, only the order of elements changes, and not their values.
The question is: is this an expected behaviour or am I doing something wrong?
Thak you for your attention.
Reseed the random number generator with srand() just prior to calling array_rand.
srand();
$password .= $a[array_rand($a)];
I think it should be your PHP version. I just copied your code into my localhost server and it worked fine. I'm using PHP 5.5.9-1ubuntu4.7, you should try it or a newer version.
By the way, if you can't update your PHP version, use this modified version of your code:
<?php
function generatePass() {
$password = '';
// Put all letters into an array.
$letters = array('q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m');
for($i=0; $i < rand(1,200); $i++) {
// Select a random letter with rand() command inside the brackets of the array.
$password .= $letters[rand(0,25)];
}
return $password;
}
$r = 0;
while ($r <= 10000) { #generating 10 000 passwords
$total[] = generatePass();
$r++;
}
echo '<pre>';
print_r($total);
echo '</pre>';
?>
Seeding the random generator isn't needed since version 4.2.0
Try using mt_rand() for a better generation.
http://php.net/manual/en/function.mt-rand.php
Edit:
I think you actually want
$a = explode(' ', 'q w e r t y u i o p a s d f g h j k l z x c v b n m');
$end = mt_rand(1,200);
$password = '';
for($i=0; $i < $end; $i++) {
$password .= $a[array_rand($a)];
}
I took the time for you and wrote the generator.
I got it to generate 10000 unique passwords and code is efficient:
<?php
function generatePass() {
$password = '';
$lib = 'q w e r t y u i o p a s d f g h j k l z x c v b n m';
$a = explode(' ', $lib);
//remove random char
for($i=0; $i < mt_rand(1,49); $i++) {
shuffle($a);
//get Random Char
$password .= $a[mt_rand(0,count($a)-1)];
}
return $password;
}
$len = 10000; // total number of numbers
$range = array();
foreach(range(0, $len - 1) as $i){
while(in_array($num = generatePass(), $range)){}
$range[] = $num;
}
echo '<pre>';
print_r($range);
echo '</pre>';