Loops mixed alphabet and number to have 3 characters string - php

I would like to loop alphabet and number in sequence to have 3 characters string until the result is true.
The sequence should be A00, A01....A99, B00, B01....Z99 then AA1, AA2...and the last is ZZ9
I tried using this; it's able to generate A01 to Z99
$success = false;
foreach (range('A', 'Z') as $x)
{
if ($success === false)
{
for ($y = 0;$y < 100;$y++)
{
if ($success === false)
{
$serialNo = $x . sprintf("%02d", $y);
}
else
{
break;
}
}
}
}
Using this, I managed to get AA9 to ZZ9
$success = false;
foreach (range('A', 'Z') as $x)
{
if ($success === false)
{
foreach (range('A', 'Z') as $y)
{
for ($z = 0;$z < 10;$z++)
{
if ($success === false)
{
$serialNo = $x . $y . $z;
}
else
{
break;
}
}
}
}
else
{
break;
}
}
If I just want to start the looping from a certain position, for example start from A99 or BB1, how can I do this? This is because I need to send the serialNo to a shared API which I don't know the last increment.

Example start from BB1.
foreach (range('B', 'Z') as $x)
foreach (range('B', 'Z') as $y)
for ($z = 1;$z < 10;$z++)
You simply to modify the start of the range to the character you are starting from.

Related

Recursive function to find the number of ways a number can be generated out of a set of numbers

I had a job interview test and the question I got was about making a function which would return the number of ways a number could be generated by using numbers from a certain set and any number in the set can be used N times.
It is like if I have the number 10 and I want to find out how many ways 10 can be generated using [2,3,5]
2+2+2+2+2 = 10
5+3+2 = 10
2+2+3+3 = 10
5+5 = 10
to solve it I made this function:
function getNumberOfWays($money, $coins) {
static $level = 0;
if (!$level) {
sort($coins);
}
if ($level && !$money) {
return 1;
} elseif (!$level && !$money) {
return 0;
}
if ($money === 1 && array_search(1, $coins) !== false) {
return 1;
} elseif ($money === 1 && array_search(1, $coins) === false) {
return 0;
}
$r = 0;
$tmpCoins = $coins;
foreach ($coins as $index => $coin) {
if (!$coin || $coin > $money) {
continue;
}
$tmpCoins[$index] = 0;
$tmpMoney = $money;
do {
$tmpMoney -= $coin;
if ($tmpMoney >= 0) {
$level++;
$r += getNumberOfWays($tmpMoney, $tmpCoins);
$level--;
} elseif (!$tmpMoney) {
$r++;
}
} while ($tmpMoney >= 0);
}
return $r;
}
This function works ok and returns the right value.
My question is if there is a better way for it.
Thanks

PHP: Sort array according to another array of different length

I have two arrays of different length:
$paths_table = array("TS-0007_a.jpg", "TS-0040_a.JPG", "TS-0040_b.JPG", "TS-0040_f.JPG", "TS-0041_a.JPG", "TS-0041_b.JPG");
$order_table = array("TS-0040","TS-0007","TS-0041");
and I want to sort the first one using the second so that the output will be the array
$final_table = array("TS-0040_a.JPG", "TS-0040_b.JPG", "TS-0040_f.JPG", "TS-0007_a.jpg", TS-0041_a.JPG", "TS-0041_b.JPG")
Assuming that I'm going to use
strpos($paths_table[$i], $order_table[$j]);
to check if the string of $order_table is included in any of the $paths_table.
How can I accomplish this?
Preprocess the array so that each item contains an index of its prefix (that is, turn 'TS-0007_a.jpg' into [1,'TS-0007_a.jpg']):
foreach($paths_table as &$v) {
foreach($order_table as $n => $o)
if(strpos($v, $o) === 0) {
$v = [$n, $v];
break;
}
}
sort the array:
sort($paths_table);
and remove indexes:
foreach($paths_table as &$v)
$v = $v[1];
The following piece of code can off course be optimized in several ways, but for the sake of clarity I didnt.
$paths_table = array("TS-0007_a.jpg", "TS-0040_a.JPG", "TS-0040_b.JPG", "TS-0040_f.JPG", "TS-0041_a.JPG", "TS-0041_b.JPG");
$order_table = array("TS-0040","TS-0007","TS-0041");
$sorter = new PrefixSorter($order_table);
$output = usort($paths_table, array($sorter, 'sort'));
var_dump($paths_table);
class PrefixSorter {
private $prefixes;
function __construct($prefixes) {
$this->prefixes = $prefixes;
}
function sort($path1, $path2) {
$prefix1 = -1;
$prefix2 = -1;
foreach($this->prefixes as $index=>$prefix) {
if (substr($path1, 0, strlen($prefix)) == $prefix) $prefix1 = $index;
if (substr($path2, 0, strlen($prefix)) == $prefix) $prefix2 = $index;
}
if (($prefix1 == -1 && $prefix2 == -1) || $prefix1 == $prefix2) {
return 0;
}
else if ($prefix1 == -1 || $prefix1 > $prefix2) {
return 1;
}
else if ($prefix2 == -1 || $prefix1 < $prefix2) {
return -1;
}
}
}
I made a few assumptions:
You want to sort on the prefixes given in order_table
Prefixes not given are put at the back unordered.
You can off course change the code to match on string containment instead of prefixing

foreach() every 4 change output

I have an issue where I don't know for a foreach() loop to change the output on every(x) amount of results.
Here is my foreach() code:
$dir_handle = 'assets/icons/';
foreach(array_diff(scandir($dir_handle), array('.', '..')) as $file) {
$cut = substr($file, -4);
echo '<img id="preload_header" src="assets/icons/' . $file . '" /><br />';
}
How would I get it for that 1-4 have the same result, but then 5-8 have a different result, and then back to 1-4?
You want to do a count in your foreach loop
$count = 1;
foreach(array_diff(scandir($dir_handle), array('.', '..')) as $file) {
//Check if count is between 1 and 4
if($count >= 1 && $count <= 4) {
//Do something
} else { //Otherwise it must be between 5 and 8
//Do something else
//If we are at 8 go back to one otherwise just increase the count by 1
if($count == 8) {
$count = 1;
} else {
$count++;
}
}
}
You can use the % operator, combined with a division by 4:
foreach ($a as $key => $val) {
$phase = $key / 4 % 2;
if ($phase === 0) {
echo 'here';
}
elseif ($phase === 1) {
echo 'there';
}
}
This switches between the two branches every 4 iterations of your loop.
As pointed out in the comments, the above method assumes that the keys of your array are in order. If not, you can add a counter variable in the loop, like:
$c = 0;
foreach ($a as $val) {
$phase = $c++ / 4 % 2;
if ($phase === 0) {
echo 'here';
}
elseif ($phase === 1) {
echo 'there';
}
}

What is wrong with my code - circularly sorted array does not show any results

I had an interview today and the person asked me this question:
How do you find easily an item in a circularly sorted array
Since I didn't know the answer, I tried to find a solution. Here's what I have:
Thanks
<?php
function searchincircularsorterlist($a, $len, $num) {
$start=0;
$end=$len-1;
$mid = 0;
while($start<$end) {
$mid=$start+$end/2;
if ($num == $a[$mid]) {
return $num;
}
if($num<$a[$mid]) {
if($num<$a[$start] && $a[$start]<=$a[$start+1])
$start=$mid++;
else
$end=$mid--;
}
else {
if($num>$a[$end] && $a[$end-1]<=$a[end])
$end=$mid--;
else
$start=$mid++;
}
}
if ($start == $end && $num == $a[$start]) {
return $num;
}
return -1;
}
$array = array(7,8,9,0,1,2,3,4,5,6);
var_dump(searchincircularsorterlist($array,sizeof($array),4));
I am trying to work with a circularly sorted array but for some reason it does not work. What's wrong with my code?
1) learn priority of operations. You should have: $mid=($start+$end)/2; which you ended up dividing $end by 2 and then $start - the result. This is why you got an infinite loop.
2) use: $start=$mid+1; and not $start=$mid++; that will help reducing the number of loops
<?php
function searchincircularsorterlist($a, $len, $num) {
$start=0;
$end=$len-1;
$mid = 0;
while($start<$end) {
$mid=($start+$end)/2;
if ($num == $a[$mid]) {
return $num;
}
if($num<$a[$mid]) {
if($num<$a[$start] && $a[$start]<=$a[$start+1])
$start=$mid+1;
else
$end=$mid-1;
}
else {
if($num>$a[$end] && $a[$end-1]<=$a[end])
$end=$mid-1;
else
$start=$mid+1;
}
}
if ($start == $end && $num == $a[$start]) {
return $num;
}
return -1;
}
$array = array(7,8,9,0,1,2,3,4,5,6);
var_dump(searchincircularsorterlist($array,sizeof($array),4));

Pseudo-code for shelf-stacking

Suppose I have some serially numbered items that are 1-n units wide, that need to be displayed in rows. Each row is m units wide. I need some pseudo-code that will output the rows, for me, so that the m-width limit is kept. This is not a knapsack problem, as the items must remain in serial number order - empty spaces at the end of rows are fine.
I've been chasing my tail over this, partly because I need it in both PHP and jQuery/javascript, hence the request for pseudo-code....
while (!items.isEmpty()) {
rowRemain = m;
rowContents = [];
while (!items.isEmpty() && rowRemain > items[0].width) {
i = items.shift();
rowRemain -= i.width
rowContents.push(i);
}
rows.push(rowContents);
}
Running time is Θ(number of items)
Modulus is your friend. I would do something like:
$items = array(/* Your list of stuff */);
$count = 0;
$maxUnitsPerRow = 4; // Your "m" above
while ($item = $items[$count]) {
if ($count % $maxUnitsPerRow == 0) {
$row = new row();
}
$row->addItemToRow($item);
$count++;
}
Here is an alternative php code ...
function arrayMaxWidthString($items, $maxWidth) {
$out = array();
if (empty($items)) {
return $out;
}
$row = $maxWidth;
$i = 0;
$item = array_shift($items);
$row -= strlen($item);
$out[0] = $item;
foreach ($items as $item) {
$l = strlen($item);
$tmp = ($l + 1);
if ($row >= $tmp) {
$row -= $tmp;
$out[$i] = (($row !== $maxWidth) ? $out[$i] . ' ' : '') . $item;
} elseif ($row === $maxWidth) {
$out[$i] = $item;
++$i;
} else {
++$i;
$row = $maxWidth - $l;
$out[$i] = $item;
}
}
return $out;
}
For what it's worth, I think I have what I was looking for, for PHP - but not sure if there is a simpler way...
<?php
// working with just a simple array of widths...
$items = array(1,1,1,2,1,1,2,1);
$row_width = 0;
$max_width = 2;
echo "Begin\n"; // begin first row
foreach($items as $item=>$item_width) {
// can we add item_width to row without going over?
$row_width += $item_width;
if($row_width < $max_width) {
echo "$item_width ";
} else if($row_width == $max_width) {
echo "$item_width";
echo "\nEnd\nBegin\n"; // end last row, begin new row
$row_width = 0;
} else if($row_width == 2* $max_width) {
echo "\nEnd\nBegin\n"; // end last row, begin new row
echo "$item_width";
echo "\nEnd\n"; // end new row
$row_width = 0;
if($item < count($items)) echo "Begin\n"; // new row
} else if($row_width > $max_width) {
echo "\nEnd\nBegin\n"; // end last row, begin new row
echo "$item_width";
$row_width = $item_width;
}
}
echo "\nEnd\n"; // end last row
?>

Categories