Check if a String of Text can be Composed Entirely of Chemical Element Symbols
Dec 27, 2022Now here's smartly fun nonsense in script you can play with that's super neat. It's a small javascript function that takes an input string and determines whether or not it can be reproduced entirely using chemical element symbols. You know the ones. The one and two letter codes from the Periodic Table of the Elements.
Paste a Sentence
The periodicSentence()
function will return an object with three properties. The html
property will be the original text but with <span>
elements wrapping each one and two letter chemical element symbols that were found (with the title
attribute set to the name of the element), and <del>
elements wrapping letter characters that couldn't be matched with a chemical element symbol. The result above is this first type of output.
The flags
property will be an array of numbers indicating which characters in the input sentence were matched. You can then use that array to manipulate the input text character by character however you like! Example output of this second kind may look like the following.
If the original input text is "Candy Mountain" then the output array would be:
[1, 2, 1, 2, 1, 0, 1, 2, 1, 1, 1, 2, 1, 2]
Each 1
indicates that the first letter of either a one or two letter chemical element symbol was found for this letter. If the next number in the array is a 2
then the two letters together make up a two letter chemical element symbol. If instead the next number is a 1
or 0
, then the the first letter is only a single letter chemical element symbol. Array elements of 0
are either letters that could not be matched, or non-letter characters that were passed through unchecked.
The final property is the elements
property which is an object where the keys are all the elements used by the output, and the values associated with each key are the counts for each time those elements are used. So if the input string is "Candy Mountain" the output elements
property will be:
{ "Ca": 1, "Nd": 1, "Y": 1, "Mo": 1, "U": 1, "N": 1, "Ta": 1, "In": 1 }
function periodicSentence(text) { let output = { 'html': '', 'flags': Array(text.length).fill(0, 0), 'elements': {} }; let Elements = { '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': 'Aluminium', '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' }; for (let x = 0, bit1, bit2; x < text.length; x++) { bit1 = text.substring(x, x + 1).toUpperCase(); // If first character is not a letter, skip if (!bit1.match(/[A-Z]/)) continue; bit2 = text.substring(x + 1, x + 2).toLowerCase(); // Check if next two letters are an element if (typeof Elements[bit1 + bit2] != 'undefined') { // If we are backtracking, the previous element letter must // succeed as a single letter element if (output['flags'][x]) { let bit0 = text.substring(x - 1, x).toUpperCase(); if (typeof Elements[bit0] == 'undefined') { x++; continue; } } output['flags'][x] = 1; output['flags'][x + 1] = 2; x++; // We are currently backtracking and didn't find a match } else if (output['flags'][x]) { x++; // Else check if next single letter is an element } else if (typeof Elements[bit1] != 'undefined') { output['flags'][x] = 1; // An element was not found; if the previous symbol was a two // character match, backtrack to see if breaking it up will help } else if (x > 1 && output['flags'][x - 1] == 2) { x -= 2; } } for (let x = 0, bit1, bit2; x < text.length; x++) { bit1 = text.substring(x, x + 1).toUpperCase(); bit2 = text.substring(x + 1, x + 2).toLowerCase(); // Two character elements if (output['flags'][x] == 1 && x < text.length - 1 && output['flags'][x + 1] == 2) { output['html'] += '<span title="' + Elements[bit1 + bit2] + '">'; output['html'] += text.substring(x, x + 2); output['html'] += '</span>'; if (typeof output['elements'][bit1 + bit2] == 'undefined') { output['elements'][bit1 + bit2] = 1; } else output['elements'][bit1 + bit2]++; x++; // Single character elements } else if (output['flags'][x] == 1) { output['html'] += '<span title="' + Elements[bit1] + '">'; output['html'] += text.substring(x, x + 1); output['html'] += '</span>'; if (typeof output['elements'][bit1] == 'undefined') { output['elements'][bit1] = 1; } else output['elements'][bit1]++; // Non-matching letter characters } else if (bit1.match(/[a-zA-Z]/)) { output['html'] += '<del>' + text.substring(x, x + 1) + '</del>'; // Sanitise, but otherwise ignore all other output } else output['html'] += text.substring(x, x + 1).replace(/</g, '<').replace(/>/g, '>'); } return output; }
Errors while running this script are still possible. If you don't get any output for your input, check your console output, and please let me know via comment or my contact form!
What's the longest sentence you can come up with that can be fully written in chemical element symbols?
⇐ Choosing High-Contrast Text Colour Based on Background Colour | Dr. Presto - Now with MUSIC! ⇒ |