You are given an array in PHP, which contains positive integers and/or recursively nested arrays of positive integers. It may, for example, be initialized as:
$arr = array(array(141,151,161), 2, 3, array(101, 202, array(303,404)));
Write a function "function MaxArray($arr)" which returns the maximum value contained in $arr or some array nested within $arr. In the example, the returned value should be 404.
function MaxArray($arr){
static $x = 0;
foreach($arr as $array){
if(is_array($array)) $x = MaxArray($array);
else if($array > $x) $x = $array;
}
return $x;
}
//additional output just for testing
$arr = array(array(141,5651,161), 2, 45446, array(101, 202, array(303,4)));
//additional output just for testing
print MaxArray($arr);
It works every time I run it but the online code generator would not accept. Is this an error on there part or is it me...?
Also on a personal note I would like to say thank you to everyone on stackoverflow, such an amazing site. Four years ago I knew nothing about programming and now I have built this from scratch audio visual reviews and I am writing android apps in java!
Update:
This question was taken from an online test that I sat. No error information was displayed, however the code generator just gave the response of wrong answer. Thus, I was not marked for the question.
I wanted to check my solution before appealing the decision.
# so... this works well enough
$arr = array(array(141,5651,161), 2, 45446, array(101, 202, array(303,4)));
print MaxArray($arr); // outputs 45446
print "\n";
# but now...let's try it again. In the same script. *gasp!*
$arr2 = array(42);
print MaxArray($arr2); // outputs 45446 (!!!)
The problem is that static variable; it isn't getting cleared between calls to the function. So previous results affect future ones. This is almost certainly incorrect, and would certainly cause a knowledgeable human judge to reject your code.
Get rid of the static variable. You can pass it as an argument, you can simply compare with subresults like the other answer here was suggesting... or you could show off with a closure and array_walk_recursive. :)
function MaxArray($arr) {
$max = -1;
array_walk_recursive($arr, function($x) use (&$max) {
if ($x > $max) $max = $x;
});
return $max;
}
<?php
$arr = [[141, 151, 161], 2, 3, [101, 202, [303, 404]]]
/**
* #param $input
* #return int
*/
function getActMax($input)
{
if ( ! is_array($input))
{
return $input;
} else
{
return findMax($input);
}
}
/**
* #param array $inputs
* #return int
*/
function findMax(array $inputs)
{
//Maybe the first item in the list is the biggest, this is our current max value
$max = getActMax(current($inputs));
foreach ($inputs as $v)
{
//If we found a bigger, change our max value
if (getActMax($v) > $max)
{
$max = getActMax($v);
}
}
return (int)$max;
}
var_dump(findMax($arr));
Related
I am trying to figure out how to count a number that I pull from query string and push each into an array. so if the number is 3, I want to push 1, 2 and 3 as separate numbers into the array. The below code does not work:
$number = $_GET['tics'];
$items = array();
for($numbers = 0; $numbers<$number; $numbers++) {
$items[] = $numbers;
}
var_dump shows an empty array with this code. any idea how to make this work?
I want the key to be "numbers" and the values to be 1, 2, 3 etc..
I am sure this is explained many times already on stack, but when searching I found only examples that was way to advanced for someone like me
you can use range()
Returns an array of elements from start to end, inclusive.
$number = (int) $_GET['tics'];
$items = range(1, $number);
You can use http://php.net/manual/en/function.range.php to generate a list of numbers from min to max.
<?php
$number = 5;
// Do validation on $number before passing it to range.
$result = range(1, $number);
print_r($result);
For starters, your loop is incorrect.
If you pass $number = 3
for ($numbers = 0; $numbers < $number; $numbers++) {
Will give you 0, 1, 2. You need to change it to the following:
for ($numbers = 1; $numbers <= $number; $numbers++) {
This will give you 1, 2, 3.
Anyway, entertaining another idea here, if range() as mentioned by the other answers is not what you require.
I want the key to be "numbers" and the values to be 1, 2, 3 etc..
It's not exactly clear what you mean by this, but I'm guessing you might want the array keys to be the value of $numbers? In which case, you can modify your code as follows:
$number = (int)$_GET['tics'];
$items = array();
for ($numbers = 1; $numbers <= $number; $numbers++) {
$items[$numbers] = $numbers;
}
Your code should somewhat work as intended anyway (the numbers will be incorrect). The reason it doesn't is probably that $_GET['tics'] has no value. Ensure that you do indeed have tics in the $_GET array, and that you aren't actually POSTing (in which case you need $_POST['tics'] instead).
If you change $_GET in your code to $_POST and it still doesn't work, then tics is either not set or does not have a value greater than 0.
So I'm really not good with math, formula's and the like. This is a little bit above my head.
I basically have an array, or a database with about 30 emoji's in it. I want to basically enter in a number into a form, lets say 3, then hit submit. the php script will then make as many unique combinations of 3 emoji's as possible, and then place them back into an array, or even just output right onto the screen separated by a new line.
I know how to code the form, i know out to output things to the screen and place items back into the array, etc etc... I have some good experience coding, but i'm not sure how to go about creating the unqiue combinations of the emoji's based upon user input.
any help is appreciated. if any clarification is needed let me know.
The number of combinations for 3 would be 30*29*28 = 24360 for 4 you would add *27 so the total would be 657720 so this probably isn't the best idea to build as you may run out of storage space or cause a stack overflow, but for fun you could use a recursive script to build it.
$emojis = range(1, 30);
$combos = makeCombos($emojis, 3);
echo json_encode($combos);
function makeCombos($emojis, $depth, $now = []) {
$results = [];
$depth--;
foreach ($emojis as $key => $value) {
$current = $now;
$current[] = $value;
$emojisNew = $emojis;
unset($emojisNew[$key]);
if ($depth > 0) {
$results = array_merge(
$results,
makeCombos($emojisNew, $depth, $current)
);
} else {
$results[] = $current;
}
}
return $results;
}
Using a range of (1, 3) so there are only 3*2*1 = 6 results yields the following result:
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
Note: Use $combos = makeCombos($emojis, 4); for combos of 4 emojis.
Because the Bitbucket API doesn't provide a method to get the latest tag for a repository I find myself having to get it from an array of all tags.
How do you do it?
I have tried max but it doesn't work for certain numbers e.g.
max(['1.0.8', '1.0.9', '1.0.10']);
returns '1.0.9'.
I know the tags will only ever be three numbers a.b.c they won't have other semver accepted strings like alpha etc. because of the way we do tags for our repos.
So how do you do it?
$versions = ['1.0.8', '1.0.9', '1.0.10'];
usort($versions, 'version_compare');
echo end($versions);
See http://php.net/version_compare
If you don't feel like modifying the array:
echo array_reduce($versions, function ($highest, $current) {
return version_compare($highest, $current, '>') ? $highest : $current;
});
By using the version_compare function:
function maxVersion($array)
{
$max = null;
foreach ($array as $version) {
if (version_compare($max, $version) === -1) {
$max = $version;
}
}
return $max;
}
print(maxVersion(['1.0.8', '1.0.9', '1.0.10']));
// returns "1.0.10"
Because you are dealing with Strings here rather than numbers, you will not get the result you require. You could try the following:
$version_numbers = str_replace(".","",['1.0.8', '1.0.9', '1.0.10']);
$max = max($version_numbers);
If you are always dealing with a fixed a.b.c structure then by replacing the decimal point you will get a series of integers that will let you determine the maximum relatively easily
I'm trying to make a simple PHP script for school. I need to output 2 random students from the array $leerlingen (Leerlingen = students).
It work's fine when I use echo $leerlingen within the foreach loop, but when I use the return statement it stops executing, because when return is used, it ends the function.
Code:
$leerlingen = array("tobias", "hasna", "aukje", "fred", "sep", "koen", "wahed", "anna", "jackie", "rashida", "winston", "sammy", "manon", "ben", "karim", "bart", "lisa", "lieke");
shuffle($leerlingen);
function maakGroepjes($leerlingen) {
$begin = 1;
foreach ($leerlingen as $leerling) {
if ($begin <= 2) {
echo $leerling;
$begin++;
}
}
}
echo maakGroepjes($leerlingen);
Can anyone tell me how to solve this problem?
You can return only one value inside a function, in this case is an array. I assume that the array have at least two values.
<?php
$leerlingen = array(
"tobias", "hasna", "aukje", "fred", "sep", "koen", "wahed", "anna", "jackie", "rashida", "winston", "sammy", "manon", "ben", "karim", "bart", "lisa", "lieke"
);
shuffle($leerlingen);
function maakGroepjes($leerlingen) {
//your result array
$result = array();
//Picking 2 random entries out of an array to $keys
$keys = array_rand($leerlingen, 2);
//Returning the array with two values
return array($leerlingen[$keys[0]], $leerlingen[$keys[1]]);
}
//assign the values to the vars
list($one, $two) = maakGroepjes($leerlingen);
//printing
echo $one . "<br>\n";
echo $two . "<br>\n";
?>
array_rand and other functions (rand) that rely on libc have a bad standard distribution. I'd always recommend using mt_rand() if you need it to be equally distributed, otherwise some entries will be heavily favored.
This is a good easy replacement for numerical arrays:
function array_mt_rand($array) {
return $array[ mt_rand( 0, count($array)-1 ) ];
}
$one = array_mt_rand($array);
$two = array_mt_rand($array);
You may need some extra checks if you have a small array and always want two distinct values though.
You could always try something like this.
function maakGroepjes($leerlingen) {
do {
$first_student = array_rand($leerlingen);
$second_student = array_rand($leerlingen);
} while ($leerlingen[$first_student] == $leerlingen[$second_student]);
return [$leerlingen[$first_studen], $leerlingen[$second_student]];
}
Which returns this.
Array
(
[0] => manon
[1] => winston
)
Also, the difference between a function printing/echo'ing information and returning information is pretty big.
You can't assign a variable to the echo statement inside of a function, whereas you could assign a variable to the return statement.
I would approach this a little differently.
function maakGroepjes($leerlingen) {
shuffle($leerlingen); // randomize the list of students
return array_chunk($leerlingen, 2); // break in into groups of two and return it
}
Then with
$groepjes = maakGroepjes($leerlingen);
you can generate all of the groups at once. No worries about repetition. This way if you need multiple groups, you can loop over the list of groups. If you really only need one group of two, then that will be
$groepjes[0];
which you can ouptut however you like. A very simple example:
foreach ($groepjes[0] as $student) echo "$student<br>";
Try this:
if ($begin <= 2) {
echo $leerling;
$begin++;
} else {
return
}
What this does is: every time through the loop, it looks at $begin. If it's less than or equal to two, it echoes that student and increments $begin. Otherwise, if it's greater than two, it returns, ending the function (and thus, the loop).
A perhaps better way to do it would be to just look at the ordinal directly:
foreach ($leerlingen as $ord => $leerling) {
echo $leerling;
if ($ord == 1) return;
}
Note the syntax in the loop definition. The "old =>" part sets the ordinal value as a variable as you loop through, letting you see which entry in the array you are currently on. So, this just loops through printing students. When it has printed the second student (remember, arrays are counted 0, 1, 2...) it returns.
Also, you probably don't want to echo maakGroepjes(). That function is what is echoing the student names. You probably don't want to echo the function result unless the function compiles the names into a string and returns the string or something.
I'm not sure if this is possible, but I can't figure out how to do it if it is...
I want to get a specific element out of an array that is returned by a function, without first passing it into an array... like this...
$item = getSomeArray()[1];
function getSomeArray(){
$ret = Array();
$ret[0] = 0;
$ret[1] = 100;
return $ret;
}
What's the correct syntax for this?
PHP cannot do this yet, it's a well-known limitation. You have every right to be wondering "are you kidding me?". Sorry.
If you don't mind generating an E_STRICT warning you can always pull out the first and last elements of an array with reset and end respectively -- this means that you can also pull out any element since array_slice can arrange for the one you want to remain first or last, but that's perhaps taking things too far.
But despair not: the (at this time upcoming) PHP 5.4 release will include exactly this feature (under the name array dereferencing).
Update: I just thought of another technique which would work. There's probably good reason that I 've never used this or seen it used, but technically it does the job.
// To pull out Nth item of array:
list($item) = array_slice(getSomeArray(), N - 1, 1);
PHP 5.4 has added Array Dereferencing,
here's the example from PHP's Array documentation:
Example #7 Array dereferencing
function getArray() {
return ['a', 'b', 'c'];
}
// PHP 5.4
$secondElement = getArray()[0]; // output = a
// Previously
$tmp = getArray();
$secondElement = $tmp[0]; // output = a
The syntax you're referring to is known as function array dereferencing. It's not yet implemented and there's an RFC for it.
The generally accepted syntax is to assign the return value of the function to an array and access the value from that with the $array[1]syntax.
That said, however you could also pass the key you want as an argument to your function.
function getSomeArray( $key = null ) {
$array = array(
0 => "cheddar",
1 => "wensleydale"
);
return is_null($key) ? $array : isset( $array[$key] ) ? $array[$key] : false;
}
echo getSomeArray(0); // only key 0
echo getSomeArray(); // entire array
Yes, php can't do that. Bat you can use ArrayObect, like so:
$item = getSomeArray()->{1};
// Credits for curly braces for Bracketworks
function getSomeArray(){
$ret = Array();
$ret[0] = 0;
$ret[1] = 100;
return new ArrayObject($ret, ArrayObject::ARRAY_AS_PROPS);
}
Okay, maybe not working with numeric keys, but i'm not sure.
I know this is an old question, but, in your example, you could also use array_pop() to get the last element of the array, (or array_shift() to get the first).
<?php
$item = array_pop(getSomeArray());
function getSomeArray(){
$ret = Array();
$ret[0] = 0;
$ret[1] = 100;
return $ret;
}
As the others says, there is no direct way to do this, I usually just assign it to a variable like so:
$items = getSomeArray();
$item = $items[1];
function getSomeArray(){
$ret = Array();
$ret[0] = 0;
$ret[1] = 100;
return $ret;
}
I am fairly certain that is not possible to do in PHP. You have to assign the returned array to another array before you can access the elements within or use it directly in some other function that will iterate though the returned array (i.e. var_dump(getSomeArray()) ).