You and your friend want to send each other secret messages. However, because you are conspiracy theorists and think that the government has a quantum computer that can crack any standard encryption. Therefore, you are inventing one of your own. The first step of this is as follows: taking an input string, you check if all the letters can be represented by the symbols for the elements of the periodic table (case insensitive). If they can be, you replace each section with the name of the element the symbol represents. If all letters cannot be replaced in this way, you simply use the original string.

Your Task:

You are to write a program or function that encodes a message, as outlined previously. Remember that if your program fetches data from an outside source, the size of the outside source must be added to the byte count (this loophole). The elements and symbols used are here:

H   Hydrogen
He  Helium
Li  Lithium
Be  Beryllium
B   Boron
C   Carbon
N   Nitrogen
O   Oxygen
F   Fluorine
Ne  Neon
Na  Sodium
Mg  Magnesium
Al  Aluminum
Si  Silicon
P   Phosphorus
S   Sulfur
Cl  Chlorine
Ar  Argon
K   Potassium
Ca  Calcium
Sc  Scandium
Ti  Titanium
V   Vanadium
Cr  Chromium
Mn  Manganese
Fe  Iron
Co  Cobalt
Ni  Nickel
Cu  Copper
Zn  Zinc
Ga  Gallium
Ge  Germanium
As  Arsenic
Se  Selenium
Br  Bromine
Kr  Krypton
Rb  Rubidium
Sr  Strontium
Y   Yttrium
Zr  Zirconium
Nb  Niobium
Mo  Molybdenum
Tc  Technetium
Ru  Ruthenium
Rh  Rhodium
Pd  Palladium
Ag  Silver
Cd  Cadmium
In  Indium
Sn  Tin
Sb  Antimony
Te  Tellurium
I   Iodine
Xe  Xenon
Cs  Cesium
Ba  Barium
La  Lanthanum
Ce  Cerium
Pr  Praseodymium
Nd  Neodymium
Pm  Promethium
Sm  Samarium
Eu  Europium
Gd  Gadolinium
Tb  Terbium
Dy  Dysprosium
Ho  Holmium
Er  Erbium
Tm  Thulium
Yb  Ytterbium
Lu  Lutetium
Hf  Hafnium
Ta  Tantalum
W   Tungsten
Re  Rhenium
Os  Osmium
Ir  Iridium
Pt  Platinum
Au  Gold
Hg  Mercury
Tl  Thallium
Pb  Lead
Bi  Bismuth
Po  Polonium
At  Astatine
Rn  Radon
Fr  Francium
Ra  Radium
Ac  Actinium
Th  Thorium
Pa  Protactinium
U   Uranium
Np  Neptunium
Pu  Plutonium
Am  Americium
Cm  Curium
Bk  Berkelium
Cf  Californium
Es  Einsteinium
Fm  Fermium
Md  Mendelevium
No  Nobelium
Lr  Lawrencium
Rf  Rutherfordium
Db  Dubnium
Sg  Seaborgium
Bh  Bohrium
Hs  Hassium
Mt  Meitnerium
Ds  Darmstadtium
Rg  Roentgenium
Cn  Copernicium
Nh  Nihonium
Fl  Flerovium
Mc  Moscovium
Lv  Livermorium
Ts  Tennessine
Og  Oganesson


A string to be encoded. You may take this in all caps or lowercase if you wish, as long as you specify that requirement in your answer.


The string, encoded as outlined previously if possible.


Hi!                --> HydrogenIodine!
This is an example --> This is an example
Neon               --> NeonOxygenNitrogen
Snip               --> SulfurNitrogenIodinePhosphorus OR TinIodinePhosphorus
Nag                --> NitrogenSilver


This is , shortest code in bytes wins!

  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – Dennis
    Commented Jul 28, 2017 at 16:17
  • \$\begingroup\$ Can everyone just take the elements and symbols as a dictionary as input because as of now, this challenge is basically all about compressing that? \$\endgroup\$
    – Daniel
    Commented Jul 29, 2017 at 0:00
  • \$\begingroup\$ @Dopapp, no, as that would make the answers that have already been submitted, and that people have worked very hard on, completely uncompetitive. Compressing the elements was always going to be most of the challenge anyway. \$\endgroup\$
    – Gryphon
    Commented Jul 29, 2017 at 11:10

3 Answers 3


JavaScript (ES6), 881 871 bytes

Takes the input string in all caps.


Extended test cases

Because this challenge is also a variant of the exact cover set problem, I've added the following test cases:

  • "NA" → "Sodium"
  • "NAG" → "N" + "AG" → "NitrogenSilver"
  • "NAP" → "NA" + "P" → "SodiumPhosphorus"

let f =


console.log(f('THIS IS AN EXAMPLE'))


Preliminary optimization

We ignore the following 26 elements entirely, because they can safely be replaced with two symbols of one character among BCFHIKNOPSUVWY:

Bh, Bi, Bk, Cf, Cn, Co, Cs, Cu, Hf, Ho, Hs, In, Nb,
Nh, Ni, No, Np, Os, Pb, Po, Pu, Sb, Sc, Si, Sn, Yb

Encoding and decoding the elements

We use an interlaced list of element symbols in upper case and element names in lower case. Symbols are always stored as-is, while names are shortened according to the following rules:

  1. If the first letter of the name matches the first letter of the symbol, we omit it.
  2. If the element passes rule #1 and its name ends in "ium", we omit this suffix.


  • Ag / Silver: "AGsilver"
  • K / Potassium: "Kpotassium"
  • Zn / Zinc: "ZNinc"
  • He / Helium: "HEel"

The 58 elements that trigger both rules are stored at the beginning of the list, followed by the 27 elements that trigger rule #1 only, followed by the 7 elements that do not trigger any rule.

We decode this list to populate the lookup table o, where the keys are the symbols and the values are the decoded element names:

"HEelLIith[...]HGmercury"       // encoded list
.split(/([A-Z]+|[a-z]+)/)       // split it by character case, which gives:
                                // [ '', 'HE', '', 'el', '', 'LI', '', 'ith', etc. ]
.map((r, i, a) =>               // for each item 'r' at position 'i' in this array 'a':
  i % 4 - 3 ?                   //   if we're not currently pointing to an element name:
    0                           //     do nothing
  :                             //   else:
    o[e = a[i - 2]] =           //     save o[e], where e = element symbol
      i > 339 ?                 //     if symbol/name first letters do not match:
        r[0].toUpperCase() +    //       we need to capitalize the first letter of the name
        r.slice(1)              //       and keep the rest unchanged
      :                         //     else:
        e[0] +                  //       we use the first letter of the symbol,
        r +                     //       followed by the name,
        (i < 235 ? 'ium' : '')  //       followed by the 'ium' suffix when appropriate
)                               // end of map()

Covering the input string

We try to replace all upper-case letters in the input string with element symbols, using the recursive function g() which eventually returns a replacement string or undefined if no exact cover is found:

g = ([c,                                  // c = next character
         ...s],                           // s = array of remaining characters
                r) =>                     // r = replacement string
  c ?                                     // if there's still at least one character:
    c < 'A' | c > 'Z' ?                   //   if it's not an upper-case letter:
      g(s, r + c)                         //     just append it to 'r'
    :                                     //   else:
      o[c] && g(s, r + o[c]) ||           //     try to find a symbol matching 'c'
      o[c += s.shift()] && g(s, r + o[c]) //     or a symbol matching 'c' + the next char.
  :                                       // else:
    r                                     //   success: return 'r'

Mathematica, 404 (239) bytes


Using Mathematica's built-in database to fetch element names and their abbreviation. Input can be mixed lower and upper case and is stored in the variable S. The output is the expression's result, it is not explicitly printed.

The at this time fully working code takes up 404 bytes, as Mathematica's built-in chemical database is a bit behind. ElementData[118, "Name"] returns ununoctium instead of oganesson (the super-heavy elements where only recently properly named, ununoctium was a placeholder name for element 118).
To update ElementData, I unprotect it and fix the values for elements Nihonium (113), Moscovium (115), Tennessine (118) and Oganesson (118).

If Mathematica's database were up to date, I would only require 239 bytes.


Javascript, 1487 1351 1246 1170 1243 1245 bytes

saved 234 bytes thanks to @musicman523

saved 174 bytes thanks to @ovs

saved 7 bytes thanks to @Shaggy

added 75 bytes to make it work for 2 letter elements


(Slightly more) readable version:

  • \$\begingroup\$ "readable version", yeah, totally readable. Nice job though. This is going to be a byte-intensive challenge for any lang that doesn't have a built-in for elements (anything that isn't Mathematica). \$\endgroup\$
    – Gryphon
    Commented Jul 23, 2017 at 20:41
  • 1
    \$\begingroup\$ Can you factor out "ium" to save bytes? \$\endgroup\$ Commented Jul 23, 2017 at 20:42
  • \$\begingroup\$ That's a good idea, @musicman523 \$\endgroup\$
    – Gryphon
    Commented Jul 23, 2017 at 20:42
  • \$\begingroup\$ @Gryphon You could also try factoring out on. Also, if you want to make it more human readable, use more readable delineators than 0 and 1. E.g. any of ,;.!/-_:~ *|=+'". \$\endgroup\$
    – DanTheMan
    Commented Jul 24, 2017 at 1:01
  • 1
    \$\begingroup\$ This fails to identify 2-character elements in the input string. \$\endgroup\$
    – Arnauld
    Commented Jul 25, 2017 at 8:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.