title: pronounceability algorithm
body: <p>I am struggling to find/create an algorithm that can determine the pronounceability of random 5 letter combinations.</p>
  
  <p>The closest thing I've found so far is from this 3 year old StackOverflow thread:</p>
  
  <p><a href="https://stackoverflow.com/questions/1186213/measure-the-pronounceability-of-a-word">Measure the pronounceability of a word?</a></p>
  
  <pre><code>&lt;?php
  // Score: 1
  echo pronounceability('namelet') . "\n";
  
  // Score: 0.71428571428571
  echo pronounceability('nameoic') . "\n";
  
  function pronounceability($word) {
      static $vowels = array
          (
          'a',
          'e',
          'i',
          'o',
          'u',
          'y'
          );
  
      static $composites = array
          (
          'mm',
          'll',
          'th',
          'ing'
          );
  
      if (!is_string($word)) return false;
  
      // Remove non letters and put in lowercase
      $word = preg_replace('/[^a-z]/i', '', $word);
      $word = strtolower($word);
  
      // Special case
      if ($word == 'a') return 1;
  
      $len = strlen($word);
  
      // Let's not parse an empty string
      if ($len == 0) return 0;
  
      $score = 0;
      $pos = 0;
  
      while ($pos &lt; $len) {
          // Check if is allowed composites
          foreach ($composites as $comp) {
                  $complen = strlen($comp);
  
                  if (($pos + $complen) &lt; $len) {
                          $check = substr($word, $pos, $complen);
  
                          if ($check == $comp) {
                                  $score += $complen;
                                  $pos += $complen;
                                  continue 2;
                          }
                  }
          }
  
          // Is it a vowel? If so, check if previous wasn't a vowel too.
          if (in_array($word[$pos], $vowels)) {
                  if (($pos - 1) &gt;= 0 &amp;&amp; !in_array($word[$pos - 1], $vowels)) {
                          $score += 1;
                          $pos += 1;
                          continue;
                  }
          } else { // Not a vowel, check if next one is, or if is end of word
                  if (($pos + 1) &lt; $len &amp;&amp; in_array($word[$pos + 1], $vowels)) {
                          $score += 2;
                          $pos += 2;
                          continue;
                  } elseif (($pos + 1) == $len) {
                          $score += 1;
                          break;
                  }
          }
  
          $pos += 1;
      }
  
      return $score / $len;
  }
  ?&gt;
  </code></pre>
  
  <p>... but it is far from perfect, giving some rather strange false positives:</p>
  
  <p>Using this function, all of the following rate as pronounceable, (above 7/10)</p>
  
  <ul>
  <li>ZTEDA</li>
  <li>LLFDA</li>
  <li>MMGDA</li>
  <li>THHDA</li>
  <li>RTHDA</li>
  <li>XYHDA</li>
  <li>VQIDA</li>
  </ul>
  
  <p>Can someone smarter than me tweek this algorithm perhaps so that:</p>
  
  <ul>
  <li>'MM', 'LL', and 'TH' are only valid when followed or preceeded by a
  vowel?</li>
  <li>3 or more consonants in a row is a no-no, (except when the first or
  last is an 'R' or 'L')</li>
  <li>any other refinements you can think of...</li>
  </ul>
  
  <p><em>(I have done a fair amount of research/googling, and this seems to be the main pronounceability function that everyone has been referencing/using for the last 3 years, so I'm sure an updated, more refined version would be appreciated by the wider community, not just me!).</em></p>