Periodic Table of Elements - Code Golf Based on Practical Golf - US States

Your task is to find the abbreviation (symbol) of an element given the element name, up to and including ununoctium (118). Use the periodic table on Wikipedia.

Thanks to squeamish ossifrage, you can find a full list of elements to abbreviations at http://pastebin.com/DNZMWmuf.

You may not use any external resources. In addition, you may not use any built-in data specifically about the elements of the periodic table. Standard loopholes apply.

Input

Input may be from stdin, file, prompt, input etc.

Input Format:

All of the following are valid inputs:

Carbon
carbon
CARBON
cArBOn


Essentially, the element name - case insensitive.

You do not have to handle misspellings or any invalid element name. Invalid input is undefined behavior.

Output:

The symbol for the element. The first character must be capitalized and the rest
must be lowercase.

Example output: C

Test cases:

Carbon -&gt; C
NiTROGen -&gt; N
Sodium -&gt; Na
Gold -&gt; Au
Silver -&gt; Ag
Tin -&gt; Sn


There are many more elements than states, so I expect it to be harder to find a general rule for these.

This is code golf. Shortest code wins!
C, 452
A good hash function helps. There may be better ones. (Improvements suggested by @ugoren et al.)
h;main(c){char*p=&quot;Sn)Cu&amp;V$U#Mo#Rf#Sg&amp;Cs#Y+FTa%Rb)S'Nd#GaK&amp;Mg'Zr$PtPm%ReUuo#SmDy(Ac$Lu%W&amp;CaRa(Cf)EuB#Ds%Md$Uus*NpIn$H&amp;YbIr*BeEs*Tc#I(FlRuC#ThSrBh/NaCoLrKr&amp;Nb$CePb$Ne'Am)At*PdLa#Tl%HgMt,CrTbBk$Rh&amp;Rn4TeZn$HfAg%Fm)Xe$AlScFePo$As'HeO#LvN&amp;DbGe#Ho&amp;Mn$Cd+Ni$Rg$HsBr$AuSi#Pr&amp;Uup#Se*Ti#Tm$Er$Sb&amp;PPu&amp;Cm$GdBa'Cn&amp;UutLiFr#Ar#Bi#NoOs%Pa4Cl&quot;;while((c=getchar())&gt;64)h=(h+c%32+74)*311%441;while(h)if(*p&lt;65?h-=*p++-34,0:1)for(h--;*++p&gt;96;);do putchar(*p++);while(*p&gt;96);}

Ungolfed with comments:
int h;
main(c) {
  
  /* Hashed element symbols. Characters #$% etc. are used as padding: */
  char *p=&quot;Sn)Cu&amp;V$U#Mo#Rf#Sg&amp;Cs#Y+FTa%Rb)S'Nd#GaK&amp;Mg'Zr$PtPm%ReUuo#SmDy(Ac$Lu%W&amp;C&quot;
          &quot;aRa(Cf)EuB#Ds%Md$Uus*NpIn$H&amp;YbIr*BeEs*Tc#I(FlRuC#ThSrBh/NaCoLrKr&amp;Nb$CeP&quot;
          &quot;b$Ne'Am)At*PdLa#Tl%HgMt,CrTbBk$Rh&amp;Rn4TeZn$HfAg%Fm)Xe$AlScFePo$As'HeO#Lv&quot;
          &quot;N&amp;DbGe#Ho&amp;Mn$Cd+Ni$Rg$HsBr$AuSi#Pr&amp;Uup#Se*Ti#Tm$Er$Sb&amp;PPu&amp;Cm$GdBa'Cn&amp;Uu&quot;
          &quot;tLiFr#Ar#Bi#NoOs%Pa4Cl&quot;;
  
  /* This hash function gives a unique result for each element: */
  while((c=getchar())&gt;64) h=(h+c%32+74)*311%441;
  
  /* Find the corresponding position in the hashed data */
  while(h) {
    if(*p&lt;65?h-=*p++-34,0:1) {      /* Step over an abbreviation */
      for(h--;*++p&gt;96;);            /* Skip padding */
    }
  }
  
  /* Output first uppercase character and all following lowercase characters: */
  do {
    putchar(*p++);
  } while(*p&gt;96);
}

I used brute force to find this hash; This was the only one with a hash size of ≤512 that had no collisions. I didn't check alternative spellings though, and there might be better functions with different algorithms (e.g. using XOR instead of addition).
The hash function maps text strings to values from 0 to 440. &quot;Tin&quot; hashes to zero, so &quot;Sn&quot; is at the start of the table. The next 7 positions are empty. To keep the code compact, this is indicated by the ASCII value 34+7=41 (&quot;)&quot;). Next comes &quot;Copper&quot; (8), four empty cells (34+4=38=&quot;&amp;&quot;), and &quot;Vanadium&quot; (13). After calculating a hash, the program steps through the table, subtracting 1 for every capital letter followed by 0 or more lowercase letters, and subtracting (ASCII VALUE)-34 for every non-alphabet character. When the value reaches zero, we have found the correct result.