loading...

Job Application Code Challenge - a PHP solution

ripsup profile image Richard Orelup ・3 min read

Earlier today I read Ben Greenberg's job application challenge and thought it looked like a fun little challenge. I went to my "go to" language of PHP and knocked it out quick and noticed an error with the test string that was provided.

I didn't think to share my result until I saw another post by Ryan Palo who shared his Ruby solution to the problem. So here is my PHP solution to the problem.

The Challenge

The challenge is this (copied from the original post):

Sort the characters in the following string:
abcdefghijklmnopqrstuvwxyz_

by the number of times the character appears in the following text (descending):

… [String omitted for brevity]

Now take the sorted string, and drop all the characters after (and including) the _. The remaining word is the answer.

You can get the example string to run your code against here.

My Solution

So first I saw a need to get an array with a count of all each character. One of the nice things about PHP is that a string is an array of characters already so I didn't need to do any conversion of it. To do this I just ran it through a for loop and went through the entire array and counted each one.

<?php
$charCount = array();

for ($i=0; $i<strlen($longString); $i++) {
  if (!isset($charCount[$longString[$i]])) {
    $charCount[$longString[$i]] = 0;
  }
  $charCount[$longString[$i]]++;
}

Now that I have an array with the key being the character and the value containing the count, we need to sort the array. This is done simply the arsort().

<?php
arsort($charCount);
?>

Next we needed use implode() to concatenate all the items in the array into one string. Then it hit me that I needed to do this for the keys instead of the values of the array so I combined implode() with array_keys() to accomplish this.

<?php
$sortedString = implode(array_keys($charCount));
?>

The last step was to drop everything including the "_" so I used explode() and, since this returns an array of strings, returned only the first string in that array which will be the word we are looking for.

Final Solution

<?php
$charCount = array();

for ($i=0; $i<strlen($longString); $i++) {
  if (!isset($charCount[$longString[$i]])) {
    $charCount[$longString[$i]] = 0;
  }
  $charCount[$longString[$i]]++;
}

arsort($charCount);
$sortedString = implode(array_keys($charCount));
$theWord = explode("_",$sortedString)[0];
?>

I can think of other ways (like using a reduce similar to Ben's JS solution) to solve this in PHP but this was the first method that hit me. If you have a different version you like more please share it (and why) below cause I'd love to see it.

Another Solution

The second I hit publish I thought "I bet there is a PHP function that I could use instead of the for loop that would make this even cleaner" and 5 seconds later I had it - array_count_values()

The one issue I ran in to though with attempting to use this function though was that it would treat $longString as a String and not an Array. To fix that I combined it with str_split() and now we have the simpler solution below.

<?php
$charCount = array_count_values(str_split($longString));

arsort($charCount);
$sortedString = implode(array_keys($charCount));
$theWord = explode("_",$sortedString)[0];
?>

Performance Increase

As with most cases when using a built in PHP function over writing your own, there is a performance increase for doing this.

I threw together a quick test script where I ran each version 1000 times and the second solution was just over twice as fast as the original. So whenever possible, just use what PHP gives you. :)

Posted on Oct 17 '17 by:

Discussion

markdown guide
 

Awesome! implode and explode? I don't know PHP yet, but sounds like a violent language. :)

 
 

I'm just starting out with PHP, but I was surprised to see how much of a performance increase. Thanks for sharing!