How can I quickly calculate the shanten number in Mahjong?
If you're eyeballing it, then you go with counting three things:


the standard count from 8. (worst case scenario: 147m147p147s1234z or 13-sided kokushi)
the terminal count from 13. (worst case scenario: all simples is 13-shanten)
the seven pairs count from 6. (worst case scenario: anything without a pair)


Standard count from 8 is to identify up to 5 groupings. Groups of 3 (subtracting 2) are always better than 2 groups of 2 (subtracting 1 each), as there is always an extra tile to pick up a spare from overlapping groups. If #groupings >= 5, then verify if one of the groups is a pair. Otherwise, you only have 4 "legitimate" groups. Protogroups of 2 are called taatsu (t), pairs are counted separately (p). Generally, shanten = 8 - 2*g - t - p. My code extracts pairs before protogroups when counting. With no complete groups, the best you can achieve with the standard count is 3-shanten.

Terminal count is easy. How many terminals, and how many different terminals. For live play, just look for a pair and ignore counting them all. shanten = 13 - diffTerminals() - if(numTerminals() > diffTerminals;1;0).

Pair count is also easy. shanten = 6 - p. Whichever of the 3 is smallest is your shanten count. 



Now what the code does is that it can take a hand with size 1,2,4,5,7,8,10,11,13 or 14 and just break it down. When feeding less than 13 tiles, g can be pre-loaded with the number of melds formed. AFAIK, it won't count for self-walled protogroups if you feed it 45p55777z with 2 melds, and they happen to be two kans of 3333p and 6666p, it won't register that the hand is 1-shanten instead of tenpai... and same with 4578p if the 3 melds are 3333p6666p9999p, then the hand is 2-shanten, not 1 or 0. This is the edgiest of edge cases though.

What it does do though, is if it ends up tenpai, it will test adding every tile to get a complete hand (-1). However, it cannot add a tile already there. So even if one of the intermediate checks says it's fine, when a full hand is present, it will not validate. A hand with 4 of the same and 3 unrelated groups is by definition, not tenpai, as the only way it could "complete" is with a 5th copy of the same tile, which is not possible. 

As for what elements to take, it cycles through everything. Could a group like 34555p be better as 345 + 55 or 34 + 555, especially if you need a pair amoing the non-grouped items? Maybe, but it will still cycle through all possibilities. The line detecting three of a kind will just shift eveerything forward by two tiles as there's no point in detecting if in tiles ABCDEFGHIJKLM: DGH, EGH and FGH make runs if you know DEF are the same. Just do DEF at that point, jump, check FGH and move on. 

When I run this formula on cycles of random tile distributions, I get in the area of 220 tenhou hands per 100M, which is in line with Tenhou's monthly running stat pages.

  // INPUT: hand is a sorted array of tile values from 0-135 without repeating
  // INPUT: g is the number of groups. The function works recursively by extracting a group and calling itself with stc(smallerHand, g+1)
function stc(hand, g) {
  // INIT
  var retVal = 8; var t = 0; var p = 0;
  // KOKUSHI
  if (hand.length &gt;= 13) retVal = Math.min(retVal, 13 - diffTerminals(hand) - Math.max(Math.min(terminalPairs(hand), 1),0));
  // SUBHAND RECURSION: Sorted hands have relevant tiles spaced 4 apart or less. Order: O{4*4*(n-5)} instead of O{(n^3 / 6}
  if (hand.length &gt; 3) {
      for (i=0; i&lt;hand.length-2; i++) {
      for (j=i+1; j&lt;hand.length-1 &amp;&amp; (j-i&lt;5); j++) {
      for (k=j+1; k&lt;hand.length &amp;&amp; (k-j&lt;5); k++) {
          // Max subhands:: 14 tiles: 6635520; 13 tiles: 1351680.
          if (isGroup(hand[i], hand[j], hand[k])) {
              var subHand = [];
              for (var m in hand) {subHand[m] = hand[m];}
              subHand.splice(k,1); subHand.splice(j,1); subHand.splice(i,1);
              retVal = Math.min(retVal, this.stc(subHand, g+1));
          }
          if (isPair(hand[i],hand[j]) &amp;&amp; isPair(hand[i],hand[k])) i++; j=999; k=999;
      }}}
  }
  // PROTOGROUP COUNT
  if (hand.length &gt; 1) {
      // Priority: AB pair, AC pair, AB taatsu
      for (i = 0; i&lt;hand.length-1; i++) {
          if(isPair(hand[i], hand[i+1])) {p++;i++;}
          else if(i&lt;hand.length-2 &amp;&amp; isPair(hand[i], hand[i+2])) {p++;i=i+2;}
          else if(isTaatsu(hand[i], hand[i+1])) {t++;i++;}
      }
  }
  // 5 to 7 pairs, immeditate return on 7
  if (p==7) return -1; if (p&gt;4&amp;&amp;hand.length&gt;=13) retVal = Math.min(retVal, 6-p); 
  // Standard count: 8 - 2*g - max(4-g,p+t) - min(1,max(0,p+t-(4-g)))  
  if(p+t&gt;Math.floor(hand.length/3)) {
      if (p&gt;0) retVal = Math.min(retVal, 8 - 2*g - Math.floor(hand.length/3) - 1);  
      else retVal = Math.min(retVal, 8 - 2*g - Math.floor(hand.length/3) - 0);
  } else retVal = Math.min(retVal, 8 - 2*g - p - t, 6 - p);
  // Tenpai check for shanten == 0.
  if(retVal==0 &amp;&amp; hand.length==13) {
      for(var i=0;i&lt;136;i++){
        var checkHand = [];
        var checkRes = 0;
        for (var m in hand) {checkHand[m] = hand[m];}
        checkHand.push(i);
        for (var n = 0; n&lt;13;n++) {
            if (checkHand[n] == i) {n=999;}
            if (n == 12) {
              checkHand = checkHand.sort(doCompare);
              checkRes = stc(checkHand,0);
            }
        }
        retVal = Math.min(retVal, checkRes + 1); // checkRes would be -1 if legit tenpai, 0 if not. **EDIT2016: I think the +1 should be out of the parentheses**
      }
  } 
  return retVal;
}