# Element Counter, den510, 6/2/17
table = {"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",
	"Uut" => "Ununtrium",
	"Fl" => "Flerovium",
	"Uup" => "Ununpentium",
	"Lv" => "Livermorium",
	"Uus" => "Ununseptium",
	"Uuo" => "Ununoctium"
}

def count_elements(input)
    atoms, elements, e_num_scan, e_scan = {}, [], /([A-Z][a-z]{0,2})(\d?)/, /[A-Z][a-z]{0,2}\d?/
    input.scan(/\([\w\d]+\)?\d*/).each do | molecule | # scanning for molecules
        input.slice!(molecule) # Remove molecule from equation
        molecule.scan(/\)(\d)/) # looking for multiplier
        $1 == '' ? multiplier = 1 : multiplier = $1.to_i
        molecule.scan(e_scan).each do |ely| # looking for elements in molecule
            ely.scan(e_num_scan) # breaking up element into element and multiplier
            $2 == '' ? elements << $1 + multiplier.to_s : elements << $1 + ($2.to_i * multiplier).to_s
        end end
    elements.concat input.scan(e_scan) # adding in the remaining elements
    elements.each do | element |
        element.scan(e_num_scan) # breaking element into element and number
        $2 == '' ? num = 1 : num = $2.to_i
        atoms.key?($1) ? atoms[$1] = atoms[$1] + num : atoms[$1] = num
    end
    return atoms
end

["CCl2F2", "NaHCO3", "C4H8(OH)2", "PbCl(NH3)2(COOH)2"].each do |formula|
    puts '', formula, '-'*20
    count_elements(formula).each do |key, value|
        puts table[key].ljust(14) + ':' + value.to_s.rjust(5)
    end end