There are more than 100 elements in the modern periodic table. You challenge is to output the rounded mass of an element with respect to the input given.

Input

  • Input will contain an abbreviation of an element.
  • Input can be taken from any one of the following:

    • stdin
    • command-line arguments
    • function arguments
  • Input will contain a one or two letter abbreviation of an element. The first character is always an uppercase letter and the second character, if any, will be a lowercase letter.

Output

  • Output the mass of the element entered
  • Output must be in the stdout or closest equivalent.
  • Output may contain a trailing newline character

Elements and their masses

Here is the list of abbreviation of elements and their masses:

Sl.No     Elements     Abbreviation     Mass     

1         Hydrogen     H                1        
2         Helium       He               4        
3         Lithium      Li               7        
4         Beryllium    Be               9        
5         Boron        B                11       
6         Carbon       C                12       
7         Nitrogen     N                14       
8         Oxygen       O                16       
9         Fluorine     F                19       
10        Neon         Ne               20       
11        Sodium       Na               23       
12        Magnesium    Mg               24       
13        Aluminium    Al               27       
14        Silicon      Si               28       
15        Phosphorus   P                31       
16        Sulfur       S                32       
17        Chlorine     Cl               35       
18        Argon        Ar               40       
19        Potassium    K                39       
20        Calcium      Ca               40       
21        Scandium     Sc               45       
22        Titanium     Ti               48       
23        Vanadium     V                51       
24        Chromium     Cr               52       
25        Manganese    Mn               55       
26        Iron         Fe               56       
27        Cobalt       Co               59       
28        Nickel       Ni               59       
29        Copper       Cu               64       
30        Zinc         Zn               65       
31        Gallium      Ga               70       
32        Germanium    Ge               73       
33        Arsenic      As               75       
34        Selenium     Se               79       
35        Bromine      Br               80       
36        Krypton      Kr               84       
37        Rubidium     Rb               85       
38        Strontium    Sr               88       
39        Yttrium      Y                89       
40        Zirconium    Zr               91       
41        Niobium      Nb               93       
42        Molybdenum   Mo               96       
43        Technetium   Tc               98       
44        Ruthenium    Ru               101      
45        Rhodium      Rh               103      
46        Palladium    Pd               106      
47        Silver       Ag               108      
48        Cadmium      Cd               112      
49        Indium       In               115      
50        Tin          Sn               119      
51        Antimony     Sb               122      
52        Tellurium    Te               128      
53        Iodine       I                127      
54        Xenon        Xe               131      
55        Cesium       Cs               133      
56        Barium       Ba               137      
57        Lanthanum    La               139      
58        Cerium       Ce               140      
59        Praseodymium Pr               141      
60        Neodymium    Nd               144      
61        Promethium   Pm               145      
62        Samarium     Sm               150      
63        Europium     Eu               152      
64        Gadolinium   Gd               157      
65        Terbium      Tb               159      
66        Dysprosium   Dy               163      
67        Holmium      Ho               165      
68        Erbium       Er               167      
69        Thulium      Tm               169      
70        Ytterbium    Yb               173      
71        Lutetium     Lu               175      
72        Hafnium      Hf               178      
73        Tantalum     Ta               181      
74        Tungsten     W                184      
75        Rhenium      Re               186      
76        Osmium       Os               190      
77        Iridium      Ir               192      
78        Platinum     Pt               195      
79        Gold         Au               197      
80        Mercury      Hg               201      
81        Thallium     Tl               204      
82        Lead         Pb               207      
83        Bismuth      Bi               209      
84        Polonium     Po               209      
85        Astatine     At               210      
86        Radon        Rn               222      
87        Francium     Fr               223      
88        Radium       Ra               226      
89        Actinium     Ac               227      
90        Thorium      Th               232      
91        Protactinium Pa               231      
92        Uranium      U                238      
93        Neptunium    Np               237      
94        Plutonium    Pu               244      
95        Americium    Am               243      
96        Curium       Cm               247      
97        Berkelium    Bk               247      
98        Californium  Cf               251      
99        Einsteinium  Es               252      
100       Fermium      Fm               257 

Yes. Your code only needs to deal with elements having atomic number 0-100 as seen in the table above.

Rules

Test Cases

O    --> 16
Sn   --> 119
H    --> 1
Fm   --> 257

Scoring

This is , so the shortest submission (in bytes) wins.

  • Is suppressing errors allowed? – Voitcus Jun 26 '15 at 9:36
  • @Voitcus What do you mean? – Cool Guy Jun 26 '15 at 9:39
  • @CoolGuy I made it with PHP and wanted to ignore E_NOTICE errors – Voitcus Jun 26 '15 at 9:53
  • 2
    Are we allowed to fetch the data from built-ins? (At +45/-36 this standard loophole is too disputed to be valid.) – Martin Ender Jun 26 '15 at 11:38
  • 1
    NVM, I gotcha: pastebin.com/rm0VgFsx – vijrox Jun 26 '15 at 22:06

29 Answers 29

CJam, 219 213 211 bytes

"
b$2#ÐÇ°aë#ëG0ÚÛ;½_+â¨9¨%ôº¯ó¾Ù""ÏѯÀcKÌA6ïõÃVå%x²XßM³0øUà°ÅæM¨Ã([©bþÚðÐÔ×¼&Và«òð×øùÚ¼5·¹IõÉðѧé°i9õÛ[&i÷jͶû_<-c-uîá¹¹»D+èF"]256fb~26b'Af+2/'Jf-reua#__.0042*2.2+*i4-@Ab@=+

Try it online. Because of unprintables, the permalink might not work in all browsers. For the two long strings the code points are

[10 98 36 50 159 35 208 199 176 24 134 97 15 235 35 235 71 7 48 218 17 219 59 189 95 43 226 168 57 168 20 37 244 29 186 142 175 243 190 134 140 217]
[4 207 209 175 192 99 75 204 65 54 239 140 245 195 17 86 229 19 37 120 178 88 223 77 179 147 48 20 248 85 224 176 197 230 77 168 195 8 154 40 143 91 169 129 98 19 254 218 240 208 212 215 147 188 38 5 86 224 129 171 242 240 215 248 249 26 218 137 188 53 183 185 73 245 135 4 201 240 209 167 157 19 233 176 105 57 245 219 91 159 38 105 247 106 205 128 182 251 95 60 132 45 31 99 45 117 238 225 128 185 185 187 146 68 43 232 8 70]

respectively.

The program uses the quadratic regression mass ~ floor(2.2(a-1) + 0.0042(a-1)^2), where a is atomic number. The reason for the a-1 is because of 0-indexing. This regression gives an error range of [-4, 5], which allows a base 10 encoding of the offsets.

Mathematica code for the regression:

data = {{0, 1}, {1, 4}, {2, 7}, {3, 9}, {4, 11}, {5, 12}, {6, 14}, {7, 16}, {8, 19}, {9, 20}, {10, 23}, {11, 24}, {12, 27}, {13, 28}, {14, 31}, {15, 32}, {16, 35}, {17, 40}, {18, 39}, {19, 40}, {20, 45}, {21, 48}, {22, 51}, {23, 52}, {24, 55}, {25, 56}, {26, 59}, {27, 59}, {28, 64}, {29, 65}, {30, 70}, {31, 73}, {32, 75}, {33, 79}, {34, 80}, {35, 84}, {36, 85}, {37, 88}, {38, 89}, {39, 91}, {40, 93}, {41, 96}, {42, 98}, {43, 101}, {44, 103}, {45, 106}, {46, 108}, {47, 112}, {48, 115}, {49, 119}, {50, 122}, {51, 128}, {52, 127}, {53, 131}, {54, 133}, {55, 137}, {56, 139}, {57, 140}, {58, 141}, {59, 144}, {60, 145}, {61, 150}, {62, 152}, {63, 157}, {64, 159}, {65, 163}, {66, 165}, {67, 167}, {68, 169}, {69, 173}, {70, 175}, {71, 178}, {72, 181}, {73, 184}, {74, 186}, {75, 190}, {76, 192}, {77, 195}, {78, 197}, {79, 201}, {80, 204}, {81, 207}, {82, 209}, {83, 209}, {84, 210}, {85, 222}, {86, 223}, {87, 226}, {88, 227}, {89, 232}, {90, 231}, {91, 238}, {92, 237}, {93, 244}, {94, 243}, {95, 247}, {96, 247}, {97, 251}, {98, 252}, {99, 257}};
parabola = Fit[data, {1, x, x^2}, x]
Show[ListPlot[data, PlotMarkers -> {Automatic, Tiny}], Plot[parabola, {x, 0, 100}], Frame -> True]

Which gives:

-0.019569 + 2.20617 x + 0.00417056 x^2

enter image description here

CJam, 175 174 bytes

0000000: 7232316222faaf6c3e227b693138302b257d2f296322  r21b"..l>"{i180+%}/)c"
0000016: 0221dce3cc4eb9561f953aaf640771c048ca3b9926c1  .!...N.V..:.d.q.H.;.&.
000002c: 4d033768588e2545069a202e128f0e238546134bdb31  M.7hX.%E.. ....#.F.K.1
0000042: c2e9e6924a7a8642dab33d6b789009112b5a8a652dd3  ....Jz.B..=kx...+Z.e-.
0000058: 7dbf0f0b27eb18e52808e857967bd7be4ce2545181b8  }...'...(..W.{..L.TQ..
000006e: 01101447504f4443c6392449222322f43a606ce335e0  ...GPODC.9$I"#".:`l.5.
0000084: 4356e76914357218e3942869eb8ab3f97e2e161ef061  CV.i.5r...(i....~....a
000009a: 59c310c6cbe922323538623762364365723e3a2b      Y....."258b7b6Cer>:+

The above is a reversible xxd dump. You can try the code online in the CJam interpreter.

If the permalink doesn't work in your browser, you can copy the code from this paste.

In supported browsers, you can verify all test cases at once.

Idea

The actual weights are encoded in the same fashion as in Martin Büttner's answer, with three minor modifications:

  • 12's are replaced with 6's instead of 7's.
  • The encoding is done in base 7 instead of base 8.
  • The order of the elements is reversed.

The difference between our answers lies in how the element abbreviations are stored.

In this approach, we hash all 100 element abbreviations into 8-bit characters, by doing the following:

  • Take the element name (treated as the array of its code points) and apply base 21 conversion.

    Examples: "H"21b yields 72, "He"21b yields 1613 = 21 × 72 + 101.

  • Successively compute the residue of the division by 430, 355, 288 and 242.

    Example: 1613 430% 355% 288% 242% yields 35.

  • Increment and cast to character.

    Example: 35)c yields $.

Code

r         e# Read a whitespace-separated token from STDIN.
21b       e# Convert to intger, using base 21 conversion.
"ú¯l>"    e# Push that string.
{i180+%}/ e# Cast each char to integer, add 180 and apply modular division.
)c        e# Add 1 and cast to character.

"!ÜãÌN¹V:¯dqÀHÊ;&ÁM7hX%E .#FKÛ1ÂéæJzBÚ³=kx  +Ze-Ó}¿'ëå(èW{×¾LâTQ¸GPODCÆ9$I"

          e# Push that string.
          e# "He", e.g., is hashed to '$', which is the second char from the right.

#         e# Compute the index of the character hash in the string.

"ô:`lã5àCVçi5rã(ië³ù~.ðaYÃÆËé"

          e# Push that string.

 258b7b   e# Convert from base 258 to base 7.
 6Cer     e# Replace 6's with 12's.
 >        e# Keep only weight differences before the hashes occurrence.
 :+       e# Push the sum of the weight differences.
  • 2
    Brings a tear to the eye. – Darren Ringer Jun 27 '15 at 21:01

CJam, 201 195 bytes

"üæ1Îe3©ü^<ùÉkIxX¯þÄäj¤ý¨,N8jËäVªw{®Ö_<U
Zká++ØÙ/ªQÒ?»<yÙ>K_þÉ«2´EªÄ¡8ÕþÀ!-,ñ©ZÒàF"256b26b2/Gf-qeu'Af-a#)"#ØmÔwXÍÒA5(Wâ£ogg5ÂßòtwÆÚ^ØW¶°¥"258b8b7Cer<:+

I'm sure there are a bunch of unprintable characters in there, so use this permalink for testing.

I used this script to encode the abbreviations and masses as two numbers, and this script to generate the base encoding. (These are mostly for myself if I need to change anything.)

Explanation

Of course, the main compression comes from base encoding: to compress any array, interpret it as digits in some sufficiently large base to get a single number - then get the base-256 (or similar) digits of that number and turn them into characters. That process is reversible, such that we can recover the array from that string.

The above code contains two such base encodings: one for the abbreviations, and one for the masses. To make those two arrays more amenable to base encoding (i.e. to lower the base, as that makes the overall number and string significantly shorter), I did some preprocessing on the table.

First, I sorted the entire table by masses to get a non-decreasing sequence. Then I computed the successive differences between those, because the sequence is rising rather slowly. In fact, the steps are always less than 13. That allows me to use base 13 (and then recover the masses by truncating that array to the correct length and summing all elements). However, we can do better: there is only a single 12, and the next smaller step is 6. So we can replace that 12 by a 7 and use base 8, which saves quite a bit.

To encode the abbreviations, we pad the single-character elements with Q (which doesn't appear in any abbreviation), join them all together and take the difference with A or a (such that each letter becomes a number between 0 and 25 inclusive). This is then encoded in base 26. The abbreviations can be recovered by splitting the base-26 digits into pairs of 2 and removing all 16s (which correspond to the Qs).

Here is the code:

e# Decode the abbreviations

"gibberish"256b26b
     e# Get the base-26 digits representing the letters.
2/   e# Split into pairs.
Gf-  e# Remove 16s (Qs).

e# Process the input

qeu  e# Read input and convert to upper case.
'Af- e# Subtract the characters from 'A' to get numbers.
a#)  e# Find the position in the decoded array.

e# Find the mass

"gibberish"258b8b
     e# Get the base-8 digits representing the mass increments.
7Cer e# Replace the 7 by a 12.
<    e# Truncate, based on the position of the input in the abbreviations.
:+   e# Sum all the increments.

Bash + coreutils, 381

base64 -d<<<H4sICPGCjVUAA3B0LnR4dABNUMuShCAMvPcveQIEoUaQAtzdmf//kO2Ol7GKEJP0I2QAOTKcBfBMPALQgIu1hKZWc6gHb3dicgodkzGcDHjBjS04pZhEYmniB2Hwqg1JBOHaWrGRcOPTLDuEOdh107ARfhjhwPAqDLyBD2tNv5V+lvjHzZPlYif2MFJmKEY7Fac3hYIl8T+GYBqekqdDiOiSajt6fYzzivdji1zL8DvlM1UjZ5fNvVk/NZaTFtUCvzQjEVxUKGLti7aMK8vc0it1An3Z+gW38PUNvo8ww8FpN3SHla3VOh5DrqIrC3XzL9s2Ido6SBX/wOjUg78BAAA=|zcat|sed -n "/\b$1\b/I="

This is simply the elements represented in a file thus:

H


HE


LI

BE
...

Note the line number of the element corresponds with the mass. In cases where there are multiple elements with the same mass, the line looks like:

AR;CA

The file is gzipped and base64 encoded. Note the element names are all in upper case to improve compression. Interestingly gzip and bzip2 had identical compressed lengths, and xz was a little bit longer.

The base64 -d and zcat simply convert the base64 stream back to this original file. The sed then simply searches (case insensitively) for the input string and outputs its line number.

Test output:

$ for e in O Sn H Fm Ni Co; do ./pt.sh $e; done
16
119
1
257
59
59
$ 

Marbelous, 1426 bytes

}0}1
LNLn
=A
RLSS
=G=M=T=C=U=L=R=S
P1P2P2P2P1P2P4P7
P0P4P1P2P9P7P0P5
P8P3P0P7//PNPNPN
PNPNPNPN
}0}1
LNLn
=B
RLSS
=I=A=K=R=EP1
P2P1P2P8P9P1
P0P3P4P0PNPN
P9P7//PN
PNPN
}0}1
LNLn
=C
RLSS
=D=E=F=M=S=A=L=O=R=U
P1P1P2P2P1P4P3P5P5P6P1
P1P4P5P4P3P0P5P9P2P4P2
P2P0P1P7P3PNPNPNPNPNPN
PNPNPNPNPN
}0}1
LNLn
=E
RLSS
=R=S=U
P1P2P1
P6P5//
P7P2
PNPN
}0}1
LNLn
=F
RLSS
=M=R=E
P2P2P5P1
P5P2P6P9
P7P3PNPN
PNPN
}0}1
LNLn
=G
RLSS
=D=A=E
P1P7P7
P5P0P3
P7PNPN
PN
}0}1
LNLn
=H
RLSS
=F=G=O=E
P1P2P1P4P1
P7P0P6PNPN
P8P1P5
PNPNPN
}0}1
LNLn
=I
RLSS
P1
=N=R
P1P9P2
P5P2P7
PNPNPN
}0}1
LNLn
>J
<N
RLSS
=A=U=N=O=R=G=IP3
P1P1P5P9P8P2P7P9
P3P7P5P6P4//PNPN
P9P5PNPNPN
PNPN
}0}1
LNLn
=N
RLSS
=P=D=I=E=B=AP1
P2P1P5P2P9P2P4
P3P4P9P0P3//PN
P7P4PNPNPN
PNPN
}0}1
LNLn
=O
RLSS
P1
=S
P9P6
P0PN
PN
}0}1
LNLn
=P
RLSS
=U=A=O=B=T=M=D=R
P2P2P2P2P1P1P1P1
P4P3P0P0P9P4P0P4P3
P4P1P9P7P5P5P6P1//
PNPNPNPNPNPNPNPN
}0}1
LNLn
=R
RLSS
=N=H=U=A=E=B
P2P1P1P2P1P8
P2P0P0P2P8P5
P2P3P1P6//PN
PNPNPNPN
}0}1
LNLn
=S
RLSS
=M=B=N=E=C=R=IP3
P1P1P1P7P4P8P2P2
P5P2P1P9P5P8//PN
P0P2P9PNPNPN
PNPNPN
}0}1
LNLn
=T
RLSS
=H=L=A=E=B=M=C=I
P2P2P1P1P1P1P9P4
P3P0P8P2P5P6P8//
P2P4P1P8P9//PN
PNPNPNPNPN
}0}1
LNLn
>X
RLSS
=B=R=N
P1P9P6
P7P1P5
P3PNPN
PN
}0
LN
=Y=X=W=V=U=D
P8P1P1P5P2P1
P9P3P8P1P3P6
..P1P4..P8P3
PNPNPNPNPNPN
:P0
}0
{030
:P1
}0
{031
:P2
}0
{032
:P3
}0
{033
:P4
}0
{034
:P5
}0
{035
:P6
}0
{036
:P7
}0
{037
:P8
}0
{038
:P9
}0
{039
:PN
}0
\/0A
:LN
}0
-Z
-K
{0
:Ln
}0
-W
-Z
-K
{0
:RLSS
}1}0
{0\/

Input is provided as two command line parameters. Marbelous does not currently have a way to handle variable length input and halt, so the second parameter is required. For one-letter symbols, just pass in any character as the second parameter, as long as it doesn't make a valid two-letter symbol. I hope to improve the language in the future to remove this limitation.

Also, a bug in the python interpreter currently requires the -m 0 parameter, as stdout is not being memoized correctly for functions.

# marbelous.py -m 0 mass.mbl H e
4

# marbelous.py -m 0 mass.mbl T a
181
  • +1 I never expected Marbelous to be good at data encoding – Nathan Merrill Jun 26 '15 at 19:21
  • @NathanMerrill I mean, 1426 bytes isn't exactly "good". Even with a bunch of helper functions it still takes 8-11 bytes to print "157\n". I do plan to add some explicit stdout devices to marbelous eventually to make this better. – Sparr Jun 26 '15 at 19:42

Excel VBA, 1587 bytes

So it isn't really a good golf attempt, I used a standard CASE statement, which looks like:

n = InputBox("n")
Select Case n
Case "H"
m = 1
Case "He"
m = 4
Case "Li"
m = 7
......
End Select

For all 100 elements specified in the question, it will read in the abbreviation and then display its weight in a message box.
But what was interesting is instead of spending ages typing it all out, I used another bit of VBA to generate the CASE statement:

FilePath = Application.DefaultFilePath & "\code.txt"
Open FilePath For Output As #2

For i = 3 To UsedRange.Rows.Count
sentence = sentence + "Case " & Chr(34) & Cells(i, 3) & Chr(34) & vbNewLine & "m = " & Cells(i, 4) & vbNewLine
Next i

Print #2, sentence
Close #2

I copy and pasted the helpful table used in the question, the macro then reads the needed columns and pieces together the entire CASE statement used above.

I used this guide to work out how to output to a text file: http://www.homeandlearn.org/write_to_a_text_file.html

JavaScript ES6, 326

s=>eval(`/${s}(\\d+)/.exec(btoa\`QÞ฻ïA×PµØÝx;^×Ó^ÛCZÛs Û%Û´¢ÛÃ÷Õ-ö
]ù¾4+BksSçP«çc'ç^ç ¨çÓbçЮëgëïAïp,ïïÐkóB«ó[ó«óÆ<õýÔÖýÜÊ=é7=ñµÓTa×MÏw]:
tð'u×b'×^R]}I½vÙ7µÛÂ5ÛµÞ×}B³]÷­w춵ßÐׯ^55Ýxàùµã¦×»^vÝyí6õçÐò×­Ç£^¹½zí9µëÖ׽˻^ùý{ñ6µóUµó^×γ_t"½}Øûu÷.×ÞÇm5N]´àööÓ°bÛOO£m=ݵÑöÛakÛmÑkmºÍ¶í8vßcÚÛ}TÛ
§mû>í¸à ¶ãp¦ÛÁn;    ý¹ÔK6çafÛ\`)`)[1]

JSFiddle, the special charecters keep having issues

I hate to use an object and then search through it but I'll try to golf this more when I get access to a computer. Updated

Template Strings are the same length as regular strings so it doesn't matter. .exec actually stores the capture groups starting in [1] which adds another unavoidable 3 bytes, JavaScript's RegEx also doesn't support lookbehind but that wouldn't matter because that would be longer

I'm using atob which is used to convert from Base64 but if you use it the other way, you can chop off about a hundred bytes

  • 1
    I just get TypeError: null has no properties on Firefox... there doesn't seem to be any opening bracket for btoa either. This isn't working unless you've had some issue with encoding pasting it in. – George Reith Jun 28 '15 at 10:30
  • @GeorgeReith It seems that SO has some complications with some characters. I had to use jsfiddle to upload my code because SO removed some characters. – Stefnotch Jun 28 '15 at 10:57
  • @GeorgeReith Yeah, Stefnotch is right, they're problems with the characters, I'll add a JSFiddle – Downgoat Jun 28 '15 at 13:11
  • @vihan1086 Thought that might be the case, yeah good to post a Fiddle too so it can be verified. – George Reith Jun 28 '15 at 13:53

Python 2, 405 401 bytes

Call w(e) to print the weight of element e:

def w(e):import re;print reduce(lambda c,(_,d):c+int(d)-1,re.findall(r"(\D+)(\d+)",re.match(".*%s\d"%e,"H2He4Li4Be3B3C2N3O3F4Ne2Na4Mg2Al4Si2P4S2Cl4Ar6K0Ca2Sc6Ti4V4Cr2Mn4Fe2Co4Ni1Cu6Zn2Ga6Ge4As3Se5Br2Kr5Rb2Sr4Y2Zr3Nb3Mo4Tc3Ru4Rh3Pd4Ag3Cd5In4Sn5Sb4Te7I0Xe5Cs3Ba5La3Ce2Pr2Nd4Pm2Sm6Eu3Gd6Tb3Dy5Ho3Er3Tm3Yb5Lu3Hf4Ta4W4Re3Os5Ir3Pt4Au3Hg5Tl4Pb4Bi3Po1At2Rn13Fr2Ra4Ac2Th6Pa0U8Np0Pu8Am0Cm5Bk1Cf5Es2Fm6").group()),0)

Tests:

w("O")
w("Sn")
w("H")
w("Fm")

Output:

16
119
1
257

Updated - now 401 bytes

I was sure those nested regexs were too wordy, so I've managed to drop one of them, and put in a beautifully convoluted lambda instead :-)

def w(e):import re;print reduce(lambda(r,m),(l,d):(r+m*(int(d)-1),m*(l!=e)),re.findall(r"(\D+)(\d+)","H2He4Li4Be3B3C2N3O3F4Ne2Na4Mg2Al4Si2P4S2Cl4Ar6K0Ca2Sc6Ti4V4Cr2Mn4Fe2Co4Ni1Cu6Zn2Ga6Ge4As3Se5Br2Kr5Rb2Sr4Y2Zr3Nb3Mo4Tc3Ru4Rh3Pd4Ag3Cd5In4Sn5Sb4Te7I0Xe5Cs3Ba5La3Ce2Pr2Nd4Pm2Sm6Eu3Gd6Tb3Dy5Ho3Er3Tm3Yb5Lu3Hf4Ta4W4Re3Os5Ir3Pt4Au3Hg5Tl4Pb4Bi3Po1At2Rn13Fr2Ra4Ac2Th6Pa0U8Np0Pu8Am0Cm5Bk1Cf5Es2Fm6"),(0,1))[0]
  • I do not think that the string raw prefix is necessary. – Jonathan Frech Sep 27 at 3:27

Python 2 364, 335, 324 bytes

3rd attempt

Last program, which beats all non cjam entries.

#coding:latin1
c="ôÜÅÌ¿ß*[h̹IÊALu>-\ÏÃnay,ÃU[ŠáŠJðûC¢\rýÑÏR¬\0W¶°ò£w¿<M¹KŸ0I\fî1Ž[b¥!iÖœ­C>÷©€)rë>:öæö\nœèãbXñ0Èéà8J¯6sõ'ìA±+yï#»ÀÙ<Š=Ùï"
n=sum([ord(c[i])*256**i for i in range(145)])
w=raw_input()+'q'
s=1
while n and n%541!=ord(w[0])*21+ord(w[1])-1464:
    n/=541;s+=n%6;n/=6
print(s,s+7)[s>210]

2nd attempt

Here's a second tentative, but it's still not very statisfactory. I can get 335 bytes by first building a table 676 bits, then get the position of a pair of letters by counting the elements preceding it int the table, and finally get the mass using a 100 bytes table. Both tables are specified in latin1 in order to get values over 128.

#coding:latin1
w=raw_input()+'`'
o=ord
print(o("ájñ&IÐà    ÏõN\n&nù!õ92>¡¥ú6ÿÝDG°Ç£}qŸ%R­5^[9ëŒåÍhÏÁòàSžeÜcx+MuV³`~æ.ʧì1¶W«?Y"[''.join(['{:08b}'.format(o(k))for k in "îóÃçuûüÇË/ÿÿÿßÿüŸ÷÷¿ìÿÿûÇ÷ÿýßÿÿÿýÿÿßßýÿïÏþ'~ÿßÿûø¿Öÿÿÿóo¿}.çÅÿ÷ÿÿþÿÿÿßÿÿÿßÿÿ_ÿÿÿÿ»ÿ"])[:o(w[0])*27+o(w[1])-1851].count('0')])+2,1)[w=='H`']

1st attempt 364

I think Python is a pretty good challenge for this game. I've tried to encode the different strings, but my decoder is always too big. And since python is very verbose and all characters appearing in the file have to be printable, it's pretty hard to get a small program. Here's my best solution so far:

w=raw_input()
x='HqHeLiBeBqCqNqOqFqNeNaMgAlSiPqSqClKqCaArScTiVqCrMnFeNiCoCuZnGaGeAsSeBrKrRbSrYqZrNbMoTcRuRhPdAgCdInSnSbIqTeXeCsBaLaCePrNdPmSmEuGdTbDyHoErTmYbLuHfTaWqReOsIrPtAuHgTlPbBiPoAtRnFrRaAcPaThNpUqAmPuBkCmCfEsFm'.find((w,w+'q')[len(w)<2])/2
print (1,8)[x>84]+sum(map(int,str(int('2zbca9fh3fq7op0ta54q928z3xc5l7hp7yyu1in8al1iis2fkjt91pxi0kkgw94f',36)))[:x])

which does not use big ideas, just the differences are encoded in base 6, then base 36, the maximum of int build-in.

  • Good first attempt. In fact, 364 bytes for Python2 is really awesome! – Cool Guy Jul 1 '15 at 6:47

Python3, 856 660 bytes

print(dict(H=1,He=4,Li=7,Be=9,B=11,C=12,N=14,O=16,F=19,Ne=20,Na=23,Mg=24,Al=27,Si=28,P=31,S=32,Cl=35,Ar=40,K=30,Ca=40,Sc=45,Ti=48,V=51,Cr=52,Mn=55,Fe=56,Co=58,Ni=58,Cu=64,Zn=65,Ga=70,Ge=73,As=75,Se=79,Br=80,Kr=84,Rb=85,Sr=88,Y=89,Zr=91,Nb=93,Mo=96,Tc=98,Ru=101,Rh=103,Pd=106,Ag=108,Cd=112,In=115,Sn=119,Sb=122,Te=128,I=127,Xe=131,Cs=133,Ba=137,La=139,Ce=140,Pr=141,Nd=144,Pm=145,Sm=150,Eu=152,Gd=157,Tb=159,Dy=163,Ho=165,Er=167,Tm=169,Yb=173,Lu=175,Hf=178,Ta=181,W=184,Re=186,Os=190,Ir=192,Pt=195,Au=197,Hg=201,Tl=204,Pb=207,Bi=209,Po=209,At=210,Rn=222,Fr=223,Ra=226,Ac=227,Th=232,Pa=231,U=238,Np=237,Pu=244,Am=243,Cm=247,Bk=247,Cf=251,Es=252,Fm=257)[input()])

Thanks to @Sp3000, I could save a whopping 196 bytes!

Test it here


Old version (856 bytes):

print({"H":1,"He":4,"Li":7,"Be":9,"B":11,"C":12,"N":14,"O":16,"F":19,"Ne":20,"Na":23,"Mg":24,"Al":27,"Si":28,"P":31,"S":32,"Cl":35,"Ar":40,"K":39,"Ca":40,"Sc":45,"Ti":48,"V":51,"Cr":52,"Mn":55,"Fe":56,"Co":59,"Ni":59,"Cu":64,"Zn":65,"Ga":70,"Ge":73,"As":75,"Se":79,"Br":80,"Kr":84,"Rb":85,"Sr":88,"Y":89,"Zr":91,"Nb":93,"Mo":96,"Tc":98,"Ru":101,"Rh":103,"Pd":106,"Ag":108,"Cd":112,"In":115,"Sn":119,"Sb":122,"Te":128,"I":127,"Xe":131,"Cs":133,"Ba":137,"La":139,"Ce":140,"Pr":141,"Nd":144,"Pm":145,"Sm":150,"Eu":152,"Gd":157,"Tb":159,"Dy":163,"Ho":165,"Er":167,"Tm":169,"Yb":173,"Lu":175,"Hf":178,"Ta":181,"W":184,"Re":186,"Os":190,"Ir":192,"Pt":195,"Au":197,"Hg":201,"Tl":204,"Pb":207,"Bi":209,"Po":209,"At":210,"Rn":222,"Fr":223,"Ra":226,"Ac":227,"Th":232,"Pa":231,"U":238,"Np":237,"Pu":244,"Am":243,"Cm":247,"Bk":247,"Cf":251,"Es":252,"Fm":257}[input()])

JavaScript 344 337 chars

Code:
Since it has some special chars and will not work when adding to to SO as a snippet, here is a link: https://jsfiddle.net/stefnotch/gz3hu8bq/2/

Hexdump:

0000000: 733d 3e61 6c65 7274 2852 6567 4578 7028  s=>alert(RegExp(
0000010: 6024 7b73 7d28 5c5c 5729 6029 2e65 7865  `${s}(\\W)`).exe
0000020: 6328 2248 7b48 657e 4c69 c281 4265 c283  c("H{He~Li..Be..
0000030: 42c2 8543 c286 4ec2 884f c28a 46c2 8d4e  B..C..N..O..F..N
0000040: 65c2 8e4e 61c2 914d 67c2 9241 6cc2 9553  e..Na..Mg..Al..S
0000050: 69c2 9650 c299 53c2 9a43 6cc2 9d41 72c2  i..P..S..Cl..Ar.
0000060: a24b c2a1 4361 c2a2 5363 c2a7 5469 c2aa  .K..Ca..Sc..Ti..
0000070: 56c2 ad43 72c2 ae4d 6ec2 b146 65c2 b243  V..Cr..Mn..Fe..C
0000080: 6fc2 b54e 69c2 b543 75c2 ba5a 6ec2 bb47  o..Ni..Cu..Zn..G
0000090: 61c3 8047 65c3 8341 73c3 8553 65c3 8942  a..Ge..As..Se..B
00000a0: 72c3 8a4b 72c3 8e52 62c3 8f53 72c3 9259  r..Kr..Rb..Sr..Y
00000b0: c393 5a72 c395 4e62 c397 4d6f c39a 5463  ..Zr..Nb..Mo..Tc
00000c0: c39c 5275 c39f 5268 c3a1 5064 c3a4 4167  ..Ru..Rh..Pd..Ag
00000d0: c3a6 4364 c3aa 496e c3ad 536e c3b1 5362  ..Cd..In..Sn..Sb
00000e0: c3b4 5465 c3ba 49c3 b958 65c3 bd43 73c3  ..Te..I..Xe..Cs.
00000f0: bf42 61c4 834c 61c4 8543 65c4 8650 72c4  .Ba..La..Ce..Pr.
0000100: 874e 64c4 8a50 6dc4 8b53 6dc4 9045 75c4  .Nd..Pm..Sm..Eu.
0000110: 9247 64c4 9754 62c4 9944 79c4 9d48 6fc4  .Gd..Tb..Dy..Ho.
0000120: 9f45 72c4 a154 6dc4 a359 62c4 a74c 75c4  .Er..Tm..Yb..Lu.
0000130: a948 66c4 ac54 61c4 af57 c4b2 5265 c4b4  .Hf..Ta..W..Re..
0000140: 4f73 c4b8 4972 c4ba 5074 c4bd 4175 c4bf  Os..Ir..Pt..Au..
0000150: 4867 c583 546c c586 5062 c589 4269 c58b  Hg..Tl..Pb..Bi..
0000160: 506f c58b 4174 c58c 526e c598 4672 c599  Po..At..Rn..Fr..
0000170: 5261 c59c 4163 c59d 5468 c5a2 5061 c5a1  Ra..Ac..Th..Pa..
0000180: 55c5 a84e 70c5 a750 75c5 ae41 6dc5 ad43  U..Np..Pu..Am..C
0000190: 6dc5 b142 6bc5 b143 66c5 b545 73c5 b646  m..Bk..Cf..Es..F
00001a0: 6dc5 bb22 295b 315d 2e63 6861 7243 6f64  m..")[1].charCod
00001b0: 6541 7428 292d 3132 3229 0a              eAt()-122).

Even more golfed: https://jsfiddle.net/stefnotch/gz3hu8bq/4/

Hexdump:

0000000: 733d 3e65 7661 6c28 602f 247b 737d 285c  s=>eval(`/${s}(\
0000010: 5c57 292f 2e65 7865 6328 2248 7b48 657e  \W)/.exec("H{He~
0000020: 4c69 c281 4265 c283 42c2 8543 c286 4ec2  Li..Be..B..C..N.
0000030: 884f c28a 46c2 8d4e 65c2 8e4e 61c2 914d  .O..F..Ne..Na..M
0000040: 67c2 9241 6cc2 9553 69c2 9650 c299 53c2  g..Al..Si..P..S.
0000050: 9a43 6cc2 9d41 72c2 a24b c2a1 4361 c2a2  .Cl..Ar..K..Ca..
0000060: 5363 c2a7 5469 c2aa 56c2 ad43 72c2 ae4d  Sc..Ti..V..Cr..M
0000070: 6ec2 b146 65c2 b243 6fc2 b54e 69c2 b543  n..Fe..Co..Ni..C
0000080: 75c2 ba5a 6ec2 bb47 61c3 8047 65c3 8341  u..Zn..Ga..Ge..A
0000090: 73c3 8553 65c3 8942 72c3 8a4b 72c3 8e52  s..Se..Br..Kr..R
00000a0: 62c3 8f53 72c3 9259 c393 5a72 c395 4e62  b..Sr..Y..Zr..Nb
00000b0: c397 4d6f c39a 5463 c39c 5275 c39f 5268  ..Mo..Tc..Ru..Rh
00000c0: c3a1 5064 c3a4 4167 c3a6 4364 c3aa 496e  ..Pd..Ag..Cd..In
00000d0: c3ad 536e c3b1 5362 c3b4 5465 c3ba 49c3  ..Sn..Sb..Te..I.
00000e0: b958 65c3 bd43 73c3 bf42 61c4 834c 61c4  .Xe..Cs..Ba..La.
00000f0: 8543 65c4 8650 72c4 874e 64c4 8a50 6dc4  .Ce..Pr..Nd..Pm.
0000100: 8b53 6dc4 9045 75c4 9247 64c4 9754 62c4  .Sm..Eu..Gd..Tb.
0000110: 9944 79c4 9d48 6fc4 9f45 72c4 a154 6dc4  .Dy..Ho..Er..Tm.
0000120: a359 62c4 a74c 75c4 a948 66c4 ac54 61c4  .Yb..Lu..Hf..Ta.
0000130: af57 c4b2 5265 c4b4 4f73 c4b8 4972 c4ba  .W..Re..Os..Ir..
0000140: 5074 c4bd 4175 c4bf 4867 c583 546c c586  Pt..Au..Hg..Tl..
0000150: 5062 c589 4269 c58b 506f c58b 4174 c58c  Pb..Bi..Po..At..
0000160: 526e c598 4672 c599 5261 c59c 4163 c59d  Rn..Fr..Ra..Ac..
0000170: 5468 c5a2 5061 c5a1 55c5 a84e 70c5 a750  Th..Pa..U..Np..P
0000180: 75c5 ae41 6dc5 ad43 6dc5 b142 6bc5 b143  u..Am..Cm..Bk..C
0000190: 66c5 b545 73c5 b646 6dc5 bb22 295b 315d  f..Es..Fm..")[1]
00001a0: 2e63 6861 7243 6f64 6541 7428 292d 3132  .charCodeAt()-12
00001b0: 3260 290a                                2`).

It uses RegExp to find the appropriate char from the string then it converts to it's Unicode value and subtracts something.
I wonder if this can be shortened even further.
Credits: manatwork, vihan1086 (Mass of elements)

  • Why the negative look-ahead? Just make at least on digit mandatory (I mean \d*\d+, then you can be sure ”H1” will not be picked when “He4” is needed. – manatwork Jun 26 '15 at 10:32

Rev 1, Ruby, 327

I'm fairly new to Ruby, so thanks to ManAtWork for refactoring and massively improving the code part of my program, for a saving of 42 bytes.

"1H3He3Li2Be2B1C2N2O3F1Ne3Na1Mg3Al1Si3P1S3Cl4K1Ar0Ca5Sc3Ti3V1Cr3Mn1Fe3Co0Ni5Cu1Zn5Ga3Ge2As4Se1Br4Kr1Rb3Sr1Y2Zr2Nb3Mo2Tc3Ru2Rh3Pd2Ag4Cd3In4Sn3Sb5I1Te3Xe2Cs4Ba2La1Ce1Pr3Nd1Pm5Sm2Eu5Gd2Tb4Dy2Ho2Er2Tm4Yb2Lu3Hf3Ta3W2Re4Os2Ir3Pt2Au4Hg3Tl3Pb2Bi0Po1At12Rn1Fr3Ra1Ac4Pa1Th5Np1U5Am1Pu3Cm0Bk4Cf1Es5Fm0"=~/#{gets}\d/
p eval($`.gsub /\D/,?+)

As far as I can tell, it works like this:

the =~ ("match") operator searches the data for an incidence of a string of type /#{gets}\d/ where #{gets} is an element input by the user and \d can be any number. This returns the position/index where the element occurs in the big string, but the return value is thrown away.

$' (not used here) is a special global variable which contains the part of the string to the right of the last match. $` is the complementary special global variable which contains the part of the string to the left of the last match. This is basically the truncated string from my rev 0.

The remaining code to subsitute all the letters for +symbols and evaluate the expression formed works in the same way as my original answer, except that ManAtWork has improved my original .gsub(/[A-z]/,'+') to .gsub /\D/,?+

Rev 0, Ruby, 369

s="1H3He3Li2Be2B1C2N2O3F1Ne3Na1Mg3Al1Si3P1S3Cl4K1Ar0Ca5Sc3Ti3V1Cr3Mn1Fe3Co0Ni5Cu1Zn5Ga3Ge2As4Se1Br4Kr1Rb3Sr1Y2Zr2Nb3Mo2Tc3Ru2Rh3Pd2Ag4Cd3In4Sn3Sb5I1Te3Xe2Cs4Ba2La1Ce1Pr3Nd1Pm5Sm2Eu5Gd2Tb4Dy2Ho2Er2Tm4Yb2Lu3Hf3Ta3W2Re4Os2Ir3Pt2Au4Hg3Tl3Pb2Bi0Po1At12Rn1Fr3Ra1Ac4Pa1Th5Np1U5Am1Pu3Cm0Bk4Cf1Es5Fm0"
e=gets
puts eval(s[0..s.gsub(/[0-9]/,'*').index(e+'*')-1].gsub(/[A-z]/,'+'))

The numbers in the string correspond to the difference between an element and the previous one (elements are in atomic mass order, not atomic number order, so the difference is always positive.)

The first gsub replaces all numbers with *. Then we search for <element name>+"*" to find the index of the element (the appended * is necessary to avoid confusing for example, Be and B because one is a substring of the other.)

The second gsub replaces all letters with +. This produces an expression that gives the mass of the element: 1+3++3++2... (Ruby does not care about the duplicate +, presumably it considers the second + to be a unary +.) All that remains is to truncate the expression at the index mentioned above, and evaluate it.

  • May I suggest a couple of small changes for line 2 and 3? p eval(s[0...s.gsub(/\d/,?*).index(gets+?*)].gsub /\D/,?+) – manatwork Jun 26 '15 at 10:14
  • Actually your compression method allows even more code size reduction: pastebin.com/aifCChWf – manatwork Jun 26 '15 at 11:13
  • @manatwork Wow, you've literally halved my code length (not including data.) Thanks. I've posted an explanation of what you've done, feel free to edit if you see anything wrong. Thanks again! – Level River St Jun 27 '15 at 10:45
  • Just replaced the $` with proper markdown. (Inline code can be delimited either with `..` or ``..``. In this case the literal code ending in a ` itself, a space is needed before the ``: ``$` ``. Which in comments isn't working the same way. Here you simply escape the literal ` inside the code with a \ .) – manatwork Jun 27 '15 at 11:28

PHP 4.1, 645 643 641 bytes

This is not the best idea, it may be possible to minimize a little more.

<?$V=split(A,A1A4A7A9AbAcAeAgAjAkAnAoArAsAvAwAzA14A13A14A19A1cA1fA1gA1jA1kA1nA1nA1sA1tA1yA21A23A27A28A2cA2dA2gA2hA2jA2lA2oA2qA2tA2vA2yA30A34A37A3bA3eA3kA3jA3nA3pA3tA3vA3wA3xA40A41A46A48A4dA4fA4jA4lA4nA4pA4tA4vA4yA51A54A56A5aA5cA5fA5hA5lA5oA5rA5tA5tA5uA66A67A6aA6bA6gA6fA6mA6lA6sA6rA6vA6vA6zA70A75);echo base_convert($V[array_search($E,array(H,He,Li,Be,B,C,N,O,F,Ne,Na,Mg,Al,Si,P,S,Cl,Ar,K,Ca,Sc,Ti,V,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,'As',Se,Br,Kr,Rb,Sr,Y,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U,Np,Pu,Am,Cm,Bk,Cf,Es,Fm))+1],36,10);

Sadly, I've seen myself forced to use Base36 instead of Base96.

To use it, simply set the key E in POST/GET/SESSION with the name of the element.

To emulate it in newer versions, simply add $E=<element name>; before $V.

You can test it on http://rextester.com/OMAA85454

PHP, 893 695 bytes

function a($e,$m=[H,1,He,4,Li,7,Be,9,B,11,C,12,N,14,O,16,F,19,Ne,20,Na,23,Mg,24,Al,27,Si,28,P,31,S,32,Cl,35,Ar,40,K,39,Ca,40,Sc,45,Ti,48,V,51,Cr,52,Mn,55,Fe,56,Co,59,Ni,59,Cu,64,Zn,65,Ga,70,Ge,73,'As',75,Se,79,Br,80,Kr,84,Rb,85,Sr,88,Y,89,Zr,91,Nb,93,Mo,96,Tc,98,Ru,101,Rh,103,Pd,106,Ag,108,Cd,112,In,115,Sn,119,Sb,122,Te,128,I,127,Xe,131,Cs,133,Ba,137,La,139,Ce,140,Pr,141,Nd,144,Pm,145,Sm,150,Eu,152,Gd,157,Tb,159,Dy,163,Ho,165,Er,167,Tm,169,Yb,173,Lu,175,Hf,178,Ta,181,W,184,Re,186,Os,190,Ir,192,Pt,195,Au,197,Hg,201,Tl,204,Pb,207,Bi,209,Po,209,At,210,Rn,222,Fr,223,Ra,226,Ac,227,Th,232,Pa,231,U,238,Np,237,Pu,244,Am,243,Cm,247,Bk,247,Cf,251,Es,252,Fm,257]){return $m[array_search($e,$m)+1];}

The usage of the function is to omit the 2nd argument, eg

echo a('Ra'); // returns 226

Requires PHP >=5.4 to allow [...] for array declaration and suppressing errors (at least error_reporting(~E_NOTICE) is given or there is the same clause in the php.ini file).

The As needs to be in quotes because it is considered as a reserved keyword.

  • 1
    You can ignore warnings. As long as it produces the desired result, it's valid. – Ismael Miguel Jun 26 '15 at 9:52
  • Instead of return $m[array_search($e,$m)+1];, use echo$m[array_search($e,$m)+1];, which saves a few bytes. – Ismael Miguel Jun 26 '15 at 10:11
  • @IsmaelMiguel Thanks. I was thinking die() would also do the trick, it's one character more than echo. – Voitcus Jun 26 '15 at 10:59

Ruby: 474 468 characters

f=->e{"H1He4Li7Be9B11C12N14O16F19Ne20Na23Mg24Al27Si28P31S32Cl35Ar40K39Ca40Sc45Ti48V51Cr52Mn55Fe56Co59Ni59Cu64Zn65Ga70Ge73As75Se79Br80Kr84Rb85Sr88Y89Zr91Nb93Mo96Tc98Ru101Rh103Pd106Ag108Cd112In115Sn119Sb122Te128I127Xe131Cs133Ba137La139Ce140Pr141Nd144Pm145Sm150Eu152Gd157Tb159Dy163Ho165Er167Tm169Yb173Lu175Hf178Ta181W184Re186Os190Ir192Pt195Au197Hg201Tl204Pb207Bi209Po209At210Rn222Fr223Ra226Ac227Th232Pa231U238Np237Pu244Am243Cm247Bk247Cf251Es252Fm257"=~/#{e}(\d+)/;$><<$1}

Sample run:

irb(main):001:0> f=->e{"H1He4Li7Be9B11C12N14O16F19Ne20Na23Mg24Al27Si28P31S32Cl35Ar40K39Ca40Sc45Ti48V51Cr52Mn55Fe56Co59Ni59Cu64Zn65Ga70Ge73As75Se79Br80Kr84Rb85Sr88Y89Zr91Nb93Mo96Tc98Ru101Rh103Pd106Ag108Cd112In115Sn119Sb122Te128I127Xe131Cs133Ba137La139Ce140Pr141Nd144Pm145Sm150Eu152Gd157Tb159Dy163Ho165Er167Tm169Yb173Lu175Hf178Ta181W184Re186Os190Ir192Pt195Au197Hg201Tl204Pb207Bi209Po209At210Rn222Fr223Ra226Ac227Th232Pa231U238Np237Pu244Am243Cm247Bk247Cf251Es252Fm257"=~/#{e}(\d+)/;$><<$1}
=> #<Proc:0x00000001e59d08@(irb):2 (lambda)>
irb(main):002:0> f["K"]
39=> #<IO:<STDOUT>>

Online run:

http://rextester.com/edit/UMNY88866

SAS, 351 (chars) 791 (bytes) 454 bytes

Borrowing from the concept posted by Sp3000, using a quadratic regression to model the positional offsets mass = floor(o*0.715+0.00031*o*o+1.7)+e where o represents the offset and e is the known error from actual.

%macro m(e);data;s='H-1He0Li1Be1B0C0N1O1F3Ne2Na3Mg2Al3Si01P1S01Cl2Ar5K01Ca0Sc2Ti3V4Cr3Mn4Fe2Co3Ni01Cu3Zn01Ga3Ge4As4Se6Br4Kr6Rb5Sr5Y04Zr3Nb03Mo03Tc02Ru02Rh00Pd00Ag-1Cd00In0Sn1Sb2Te5I2Xe4Cs4Ba5La5Ce3Pr02Nd02Pm-1Sm1Eu00Gd2Tb2Dy3Ho3Er2Tm01Yb2Lu1Hf2Ta2W3Re3Os5Ir4Pt4Au4Hg5Tl6Pb6Bi5Po03At00Rn9Fr7Ra7Ac6Th8Pa04U8Np5Pu9Am6Cm7Bk04Cf05Es02Fm03';o=prxmatch("#(?<=&e)[-\d]#",s)-1;a=floor(o*.715+.00031*o*o+1.7)+prxchange("s#.*&e(-?\d+).*#\1#",1,s);put a;run;%mend;

Javascript ES6 354 bytes

p=e=>+'1H2He1LiBeBC1N1O2FNe1Na-Mg1Al-Si1PS2Cl2KAr--Ca3Sc1Ti1VCr1Mn-Fe1Co--Ni3Cu-Zn3Ga1GeAs2Se-Br2Kr-Rb1Sr-Y1ZrNb1MoTc1RuRh1PdAg2Cd1In2Sn1Sb3ITe1XeCs2BaLa-Ce-Pr1Nd-Pm3SmEu3GdTb2DyHoErTm2YbLu1Hf1Ta1W1Re2OsIr1PtAu2Hg1Tl1PbBi--Po-At19Rn-Fr1Ra-Ac2Pa-Th3Np-U4Am-Pu1Cm--Bk2Cf-Es1Fm'.split(RegExp(e+'[^a-z].*'))[0].split('').reduce((o,n)=>+n?+n+o:n=='-'?--o:++o)

Ungolfed:

function p(e) {
  return "1H2He1LiBeBC1N1O2FNe1Na-Mg1Al-Si1PS2Cl2KAr--Ca3Sc1Ti1VCr1Mn-Fe1Co--Ni3Cu-Zn3Ga1GeAs2Se-Br2Kr-Rb1Sr-Y1ZrNb1MoTc1RuRh1PdAg2Cd1In2Sn1Sb3ITe1XeCs2BaLa-Ce-Pr1Nd-Pm3SmEu3GdTb2DyHoErTm2YbLu1Hf1Ta1W1Re2OsIr1PtAu2Hg1Tl1PbBi--Po-At19Rn-Fr1Ra-Ac2Pa-Th3Np-U4Am-Pu1Cm--Bk2Cf-Es1Fm"
  .split(RegExp(e+'[^a-z].*'))[0]
  .split('')
  .reduce(function(o,n) {
    return +n ? +n+o : n=='-' ? --o : ++o;
  })
}

The elements are stored in a string of numbers symbols and minus characters. The mass of any given element is the number of letter characters preceding it, plus the sum of digits subtracted by the occurrences of -.

Tests:

var a = [
  'H', 1,
  'He', 4,
  'Li', 7,
  'Be', 9,
  'B', 11,
  'C', 12,
  'N', 14,
  'O', 16,
  'F', 19,
  'Ne', 20,
  'Na', 23,
  'Mg', 24,
  'Al', 27,
  'Si', 28,
  'P', 31,
  'S', 32,
  'Cl', 35,
  'Ar', 40,
  'K', 39,
  'Ca', 40,
  'Sc', 45,
  'Ti', 48,
  'V', 51,
  'Cr', 52,
  'Mn', 55,
  'Fe', 56,
  'Co', 59,
  'Ni', 59,
  'Cu', 64,
  'Zn', 65,
  'Ga', 70,
  'Ge', 73,
  'As', 75,
  'Se', 79,
  'Br', 80,
  'Kr', 84,
  'Rb', 85,
  'Sr', 88,
  'Y', 89,
  'Zr', 91,
  'Nb', 93,
  'Mo', 96,
  'Tc', 98,
  'Ru', 101,
  'Rh', 103,
  'Pd', 106,
  'Ag', 108,
  'Cd', 112,
  'In', 115,
  'Sn', 119,
  'Sb', 122,
  'I', 127,
  'Te', 128,
  'Xe', 131,
  'Cs', 133,
  'Ba', 137,
  'La', 139,
  'Ce', 140,
  'Pr', 141,
  'Nd', 144,
  'Pm', 145,
  'Sm', 150,
  'Eu', 152,
  'Gd', 157,
  'Tb', 159,
  'Dy', 163,
  'Ho', 165,
  'Er', 167,
  'Tm', 169,
  'Yb', 173,
  'Lu', 175,
  'Hf', 178,
  'Ta', 181,
  'W', 184,
  'Re', 186,
  'Os', 190,
  'Ir', 192,
  'Pt', 195,
  'Au', 197,
  'Hg', 201,
  'Tl', 204,
  'Pb', 207,
  'Bi', 209,
  'Po', 209,
  'At', 210,
  'Rn', 222,
  'Fr', 223,
  'Ra', 226,
  'Ac', 227,
  'Pa', 231,
  'Th', 232,
  'U', 238,
  'Np', 237,
  'Pu', 244,
  'Am', 243,
  'Cm', 247,
  'Bk', 247,
  'Cf', 251,
  'Es', 252,
  'Fm', 257
];

function p(e) {
  return "1H2He1LiBeBC1N1O2FNe1Na-Mg1Al-Si1PS2Cl2KAr--Ca3Sc1Ti1VCr1Mn-Fe1Co--Ni3Cu-Zn3Ga1GeAs2Se-Br2Kr-Rb1Sr-Y1ZrNb1MoTc1RuRh1PdAg2Cd1In2Sn1Sb3ITe1XeCs2BaLa-Ce-Pr1Nd-Pm3SmEu3GdTb2DyHoErTm2YbLu1Hf1Ta1W1Re2OsIr1PtAu2Hg1Tl1PbBi--Po-At19Rn-Fr1Ra-Ac2Pa-Th3Np-U4Am-Pu1Cm--Bk2Cf-Es1Fm"
    .split(RegExp(e + '[^a-z].*'))[0]
    .split('')
    .reduce(function(o, n) {
      return +n ? +n + o : n == '-' ? --o : ++o;
    })
}
var $elementList = $('#elements');
for (var i = 0; i < a.length; i++) {
  var symbol = a[i];
  var mass = a[++i];
  var result = p(symbol);
  var resultString = "<li><b>" + symbol + "</b>";
  if (symbol.length === 1) resultString += "&nbsp;";
  resultString += " expected <b>" + mass + "</b>";
  if (mass < 10) resultString += "&nbsp;";
  if (mass < 100) resultString += "&nbsp;";
  resultString += " got <b>" + result + "</b></li>";
  $elementList.append(resultString);
}
#elements li {
  font-family: "Consolas", monospace;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="elements">
</ul>

Python 3, 560 bytes

import functools as f
n="HᱨἬᨊBCNOFỆᶎỻ᭬∋PS᱄ᳲKᥣ’≴Vᷖ№ᮞᴍ῾ẟ⚬᫧ᰃᴳ₿ᵤⅦὤ⓶Y⠔ᷜⅣ⁼╺⅐ὀᨧᨬ὞⎪ῆℤI⊸ḙᤂ᳌ᩯ⎠Ṹ∐⍗ᾉᮼ
․ἸẺ⏄−⊼Ჰ῔W⁚⍽₂⑀ᶵ᳸⍰Ạᬒ⊰ᵴ⌼Ἤἒᤣ∠ṐU∠⒐ᮭᲇᮖ᪲ỿ᷎"
m="!$')+,.03478;<?@CHGHMPSTWX[[`afikoptuxy{}€‚…‡ŠŒ“—š Ÿ£¥©«¬­°±¶¸½¿ÃÅÇÉÍÏÒÕØÚÞàãåéìïññòþÿĂăĈćĎčĔēėėěĜġ"
i=lambda w:f.reduce(lambda l,c:l*ord(c),list(w),1)
print(str(ord(m[n.find(chr(i(input())))])-32))

Try it online!

Explanation: So 2 variables, n and m are used to hold the abbreviations (more described below) and the elements atomic mass as strings. The input is then encrypted into a character to match to some character in n, using the string.find, an index of where the character is can be used to find the respective atomic mass in m. Due to shifting the mass values by 32 previously, they must be unshifted, then this number is output.

Each character of n is the ascii of the product of the ascii values of the characters in the name Each character of m is the ascii of mass + 32

Below is the setup code for m and n

obfNames=""
for name in names:
    prod=1
    for c in name:
        prod*=ord(c)
    obfNames+=chr(prod)
obfMass=""
for m in mass:
    obfMass+=chr(int(m)+32)
for c in obfNames:
    print(c,end="")
print()
for c in obfMass:
    print(c,end="")

Try it online!

  • Welcome to PPCG! I attempted to format your code a little nicer (Stack Exchange's Markdown formatting uses four spaces at the beginning of each line for code formatting, instead of three backticks surrounding the code block like GitHub), but something about the second line of your code severely breaks the rendering, so I left it alone. – Mego Sep 13 at 5:01
  • 1
    I got it to work by wrapping it in <pre><code> (which is what Try It Online does, apparently). I've also updated your score, as it should be 560 bytes in UTF-8 by my count (and TIO agrees). Very nice answer, and nice job breaking the Markdown rendering! – Mego Sep 13 at 5:06
  • Thank you for cleaning up my code example and updating my bytes; I simply used the 'll chem.py' in bash to find the size which was off I guess. – Josh B. Sep 13 at 5:33
  • Suggest inlining i, m and n into the last line. – ceilingcat Sep 18 at 6:06

R, 301 289 287 273 bytes

Explanation.

Look up the index of the mass sorted atomic number in a UTF8 encoded hash string s. The hash is taken by taking the element name, encoding it as ASCII, multiplying by a 2-vector encoded with UTF-8 and modding three times in succession. The operator + is used for the UTF8 to integer vector conversion.

Encode the masses of the elements as a UTF8 encoded string of differences, packing 2 differences into each byte as 9*d1 + d2 where d1 is the difference of the nth element and d2 is the successive mass difference of the n+50th element. Then to retrieve the mass, take the corresponding position at the cumulative sum of the differences. This is shorter than a quadratic formula.

function(x)sum(c(o%%9,o%/%9)[1:match(sum(+x*+"")%%740%%623%%278,+'{ćWZ}èċæŸ+Ó>qÿƒ!2Eo&ē_u½8`h›’Hb‰¹ĎŽ‹@-if9ÃÛ%ù]V‚:LkXlÙDRŠ•˜OU·m,Sµ5TËt6cC7#­/ąz1A')])
"+"=utf8ToInt
o=+"0%..%$%% 
p

&00(1"

Try it online!

A mention to this 275 byte solution which nearly beats the R record by encoding three mass differences in mixed base 6,5.

Python 2, 860 859 858 bytes

Based on @Cool Guy's version -

def f(x):print {"H":1,"He":4,"Li":7,"Be":9,"B":11,"C":12,"N":14,"O":16,"F":19,"Ne":20,"Na":23,"Mg":24,"Al":27,"Si":28,"P":31,"S":32,"Cl":35,"Ar":40,"K":39,"Ca":40,"Sc":45,"Ti":48,"V":51,"Cr":52,"Mn":55,"Fe":56,"Co":59,"Ni":59,"Cu":64,"Zn":65,"Ga":70,"Ge":73,"As":75,"Se":79,"Br":80,"Kr":84,"Rb":85,"Sr":88,"Y":89,"Zr":91,"Nb":93,"Mo":96,"Tc":98,"Ru":101,"Rh":103,"Pd":106,"Ag":108,"Cd":112,"In":115,"Sn":119,"Sb":122,"Te":128,"I":127,"Xe":131,"Cs":133,"Ba":137,"La":139,"Ce":140,"Pr":141,"Nd":144,"Pm":145,"Sm":150,"Eu":152,"Gd":157,"Tb":159,"Dy":163,"Ho":165,"Er":167,"Tm":169,"Yb":173,"Lu":175,"Hf":178,"Ta":181,"W":184,"Re":186,"Os":190,"Ir":192,"Pt":195,"Au":197,"Hg":201,"Tl":204,"Pb":207,"Bi":209,"Po":209,"At":210,"Rn":222,"Fr":223,"Ra":226,"Ac":227,"Th":232,"Pa":231,"U":238,"Np":237,"Pu":244,"Am":243,"Cm":247,"Bk":247,"Cf":251,"Es":252,"Fm":257}[x]

Usage -

f("K")

Output -

39

Try it here

Python 2, 630 bytes

Based on @Cool Guy's code, just packed all the strings into one and then used regexp to get them back. It saved me few bytes.

edit: rewrote mass list, just to be sure it's correct this time.

import re;print dict(zip(map(str.strip,re.findall("..","H HeLiBeB C N O F NeNaMgAlSiP S ClArK CaScTiV CrMnFeCoNiCuZnGaGeAsSeBrKrRbSrY ZrNbMoTcRuRhPdAgCdInSnSbTeI XeCsBaLaCePrNdPmSmEuGdTbDyHoErTmYbLuHfTaW ReOsIrPtAuHgTlPbBiPoAtRnFrRaAcThPaU NpPuAmCmBkCfEsFm")),(1,4,7,9,11,12,14,16,19,20,23,24,27,28,31,32,35,40,39,40,45,48,51,52,55,56,59,59,64,65,70,73,75,79,80,84,85,88,89,91,93,96,98,101,103,106,108,112,115,119,122,128,127,131,133,137,139,140,141,144,145,150,152,157,159,163,165,167,169,173,175,178,181,184,186,190,192,195,197,201,204,207,209,209,210,222,223,226,227,232,231,238,237,244,243,247,247,251,252,257)))[raw_input()]

Javascript ES6, 620 bytes

This is a pretty basic one, like my PHP answer.

It uses base36 to encode the values.

s=>parseInt("1|4|7|9|b|c|e|g|j|k|n|o|r|s|v|w|z|14|13|14|19|1c|1f|1g|1j|1k|1n|1n|1s|1t|1y|21|23|27|28|2c|2d|2g|2h|2j|2l|2o|2q|2t|2v|2y|30|34|37|3b|3e|3k|3j|3n|3p|3t|3v|3w|3x|40|41|46|48|4d|4f|4j|4l|4n|4p|4t|4v|4y|51|54|56|5a|5c|5f|5h|5l|5o|5r|5t|5t|5u|66|67|6a|6b|6g|6f|6m|6l|6s|6r|6v|6v|6z|70|75".split('|')["H0He0Li0Be0B0C0N0O0F0Ne0Na0Mg0Al0Si0P0S0Cl0Ar0K0Ca0Sc0Ti0V0Cr0Mn0Fe0Co0Ni0Cu0Zn0Ga0Ge0As0Se0Br0Kr0Rb0Sr0Y0Zr0Nb0Mo0Tc0Ru0Rh0Pd0Ag0Cd0In0Sn0Sb0Te0I0Xe0Cs0Ba0La0Ce0Pr0Nd0Pm0Sm0Eu0Gd0Tb0Dy0Ho0Er0Tm0Yb0Lu0Hf0Ta0W0Re0Os0Ir0Pt0Au0Hg0Tl0Pb0Bi0Po0At0Rn0Fr0Ra0Ac0Th0Pa0U0Np0Pu0Am0Cm0Bk0Cf0Es0Fm".split(0).indexOf(s)],36)

It creates an anonymous function that returns an integer value. Invalid values return weird results.

Try it (ES5, requires support for Array.prototype.indexOf()):

f=function(s){return parseInt("1|4|7|9|b|c|e|g|j|k|n|o|r|s|v|w|z|14|13|14|19|1c|1f|1g|1j|1k|1n|1n|1s|1t|1y|21|23|27|28|2c|2d|2g|2h|2j|2l|2o|2q|2t|2v|2y|30|34|37|3b|3e|3k|3j|3n|3p|3t|3v|3w|3x|40|41|46|48|4d|4f|4j|4l|4n|4p|4t|4v|4y|51|54|56|5a|5c|5f|5h|5l|5o|5r|5t|5t|5u|66|67|6a|6b|6g|6f|6m|6l|6s|6r|6v|6v|6z|70|75".split('|')["H0He0Li0Be0B0C0N0O0F0Ne0Na0Mg0Al0Si0P0S0Cl0Ar0K0Ca0Sc0Ti0V0Cr0Mn0Fe0Co0Ni0Cu0Zn0Ga0Ge0As0Se0Br0Kr0Rb0Sr0Y0Zr0Nb0Mo0Tc0Ru0Rh0Pd0Ag0Cd0In0Sn0Sb0Te0I0Xe0Cs0Ba0La0Ce0Pr0Nd0Pm0Sm0Eu0Gd0Tb0Dy0Ho0Er0Tm0Yb0Lu0Hf0Ta0W0Re0Os0Ir0Pt0Au0Hg0Tl0Pb0Bi0Po0At0Rn0Fr0Ra0Ac0Th0Pa0U0Np0Pu0Am0Cm0Bk0Cf0Es0Fm".split(0).indexOf(s)],36)}

document.getElementById('e').onkeyup=function(){
  document.getElementById('o').innerHTML=this.value?f(this.value):'';
}
<input type="text" id="e" placeholder="Element"><br>
<span>Element mass: <b id="o"></b></span> 

Java, 414 407 Bytes

void m(String e){String s="5.=\\>i6K<35)<?<@CB/L<Y0 ?M0ZCL59?OOA&z.8KI>qCR2v@./D@>)JP22%Jh=[::Dr2uH@.aA=5?:95h@H6)B+7J=J6~DH@*G?<xS*&xDw:<CX5L/A3$=H1`N0:rKW5nJ198:$8oD*:y=v<_CS6[H^:(An:nE<?`<u7T+*3Icj2y<].jLm /_}$7^U#;Ft)rD|33N#",a=s;int i=0,n=0,c,b;while(!a.equals(e)){c=s.charAt(i++)*95+s.charAt(i++)-3072;a=""+(char)(65+c%26);b=97+c/26%26;if(b!=122)a+=(char)b;c/=676;n+=c==9?12:c-1;}System.out.print(n);}

Usage: m("He")

The tuple (element code, delta from previous element) is transformed into an integer varying from 0 to 6760 (=26x26x10), then encoded in base 95 into the string.

It can be tested here: http://rextester.com/VFXLG54655

  • You have to print the value. And this seems to return a wrong mass for the 2nd and the last test case as well as several other elements. – Cool Guy Jun 26 '15 at 10:03
  • @CoolGuy Sorry, modified the code in order to print the value. I have tested for all elements, it seems to work? – Super Chafouin Jun 26 '15 at 10:07
  • Save two bytes by using System.out.print instead of System.out.println. BTW, still doesn't work – Cool Guy Jun 26 '15 at 10:09
  • It's working under eclipse. I check anyway. – Super Chafouin Jun 26 '15 at 10:13
  • @Cool Guy This seems to be a bug with rextester editor. When I use the editor "Simple", it's working. Please check : rextester.com/VJQG14496 – Super Chafouin Jun 26 '15 at 10:20

Python 3, 500 495

Pretty self-explanatory. Just use a regex built from the input to find the number after the element's abbreviation.

Try it here

import re
print(re.findall(r"(?<=%s)\d+"%input(),"H1He4Li7Be9B11C12N14O16F19Ne20Na23Mg24Al27Si28P31S32Cl35Ar40K39Ca40Sc45Ti48V51Cr52Mn55Fe56Co59Ni59Cu64Zn65Ga70Ge73As75Se79Br80Kr84Rb85Sr88Y89Zr91Nb93Mo96Tc98Ru101Rh103Pd106Ag108Cd112In115Sn119Sb122Te128I127Xe131Cs133Ba137La139Ce140Pr141Nd144Pm145Sm150Eu152Gd157Tb159Dy163Ho165Er167Tm169Yb173Lu175Hf178Ta181W184Re186Os190Ir192Pt195Au197Hg201Tl204Pb207Bi209Po209At210Rn222Fr223Ra226Ac227Th232Pa231U238Np237Pu244Am243Cm247Bk247Cf251Es252Fm257")[0])

PHP, 415 414 387 bytes

<?preg_match("/\d".$_GET[e]."\d/",$b="2H3He4Li4Be6B2C3N3O5F4Ne4Na3Mg3Al2Si2P6S3Cl6Ar2K1Ca4Sc4Ti5V4Cr5Mn3Fe4Co1Ni3Cu2Zn4Ga5Ge4As6Se4Br5Kr4Rb4Sr3Y3Zr2Nb3Mo2Tc2Ru2Rh2Pd1Ag3Cd3In4Sn5Sb8Te4I6Xe6Cs7Ba6La5Ce3Pr3Nd1Pm4Sm3Eu5Gd4Tb6Dy5Ho4Er3Tm5Yb4Lu4Hf4Ta4W5Re6Os5Ir5Pt4Au6Hg6Tl6Pb5Bi2Po0At9Rn8Fr8Ra6Ac8Th4Pa8U5Np9Pu5Am6Cm4Bk5Cf3Es5Fm0",$m,256);$s=$m[0][1];echo round(.0003*$s*$s+.81*$s-1)+$b{$s};

This answer works basically off the same principle as Sp3000's CJam answer; I did a quadratic regression with the element's position in the $b string as the independent variable and molar mass as the dependent, then found the difference between the actual value and regression value for each element, and put it all into the $b string. I actually originally did this in Java, but then discovered that it takes a lot of bytes to do regex in Java.

I've never done a code golf before so please let me know if I'm doing something wrong here.

Edit: try it out here (Actually, that link probably doesn't work)

Edit 2: Ismael Miguel helped me knock a bunch of bytes off of this!

  • Your "try it out here" link gives me a page with "Oh no... uvkk79d27f2c.vijrox.koding.io is sleeping right now. Check again a little later?" . I tried it on another online compiler and it worked. So +1 – Cool Guy Jun 28 '15 at 6:01
  • 383 bytes: <?preg_match("/\d$_GET[e]\d/",$b="2H3He4Li4Be6B2C3N3O5F4Ne4Na3Mg3Al2Si2P6S3Cl6Ar2K1Ca4Sc4Ti5V4Cr5Mn3Fe4Co1Ni3Cu2Zn4Ga5Ge4As6Se4Br5Kr4Rb4Sr3Y3Zr2Nb3Mo2Tc2Ru2Rh2Pd1Ag3Cd3In4Sn5Sb8Te4I6Xe6Cs7Ba6La5Ce3Pr3Nd1Pm4Sm3Eu5Gd4Tb6Dy5Ho4Er3Tm5Yb4Lu4Hf4Ta4W5Re6Os5Ir5Pt4Au6Hg6Tl6Pb5Bi2Po0At9Rn8Fr8Ra6Ac8Th4Pa8U5Np9Pu5Am6Cm4Bk5Cf3Es5Fm0",$m,256);$s=$m[0][1];echo round(.0003*$s*$s+.81*$s-1)+$b{$s}; (works the same, but WAY shorter) Try it: ideone.com/LqyIDx – Ismael Miguel Jun 28 '15 at 14:39
  • @CoolGuy yeah I forgot the service I use automatically turns the vm off... – vijrox Jun 28 '15 at 15:21
  • 1
    @IsmaelMiguel Nice! I'll edit my post – vijrox Jun 28 '15 at 15:25

Powershell, 324 bytes

('1H3He3Li2Be2B1C2N2O3F1Ne3Na1Mg3Al1Si3P1S3Cl4K1ArCa5Sc3Ti3V1Cr3Mn1Fe3CoNi5Cu1Zn5Ga3Ge2As4Se1Br4Kr1Rb3Sr1Y2Zr2Nb3Mo2Tc3Ru2Rh3Pd2Ag4Cd3In4Sn3Sb5I1Te3Xe2Cs4Ba2La1Ce1Pr3Nd1Pm5Sm2Eu5Gd2Tb4Dy2Ho2Er2Tm4Yb2Lu3Hf3Ta3W2Re4Os2Ir3Pt2Au4Hg3Tl3Pb2BiPo1At12Rn1Fr3Ra1Ac4Pa1Th5Np1U5Am1Pu3CmBk4Cf1Es5Fm'-split"$args")[0]-replace'\D+','+'|iex

Test script:

$f = {

('1H3He3Li2Be2B1C2N2O3F1Ne3Na1Mg3Al1Si3P1S3Cl4K1ArCa5Sc3Ti3V1Cr3Mn1Fe3CoNi5Cu1Zn5Ga3Ge2As4Se1Br4Kr1Rb3Sr1Y2Zr2Nb3Mo2Tc3Ru2Rh3Pd2Ag4Cd3In4Sn3Sb5I1Te3Xe2Cs4Ba2La1Ce1Pr3Nd1Pm5Sm2Eu5Gd2Tb4Dy2Ho2Er2Tm4Yb2Lu3Hf3Ta3W2Re4Os2Ir3Pt2Au4Hg3Tl3Pb2BiPo1At12Rn1Fr3Ra1Ac4Pa1Th5Np1U5Am1Pu3CmBk4Cf1Es5Fm'`
-split"$args")[0]-replace'\D+','+'|iex

}

@(
    ,(16,'O')
    ,(119,'Sn')
    ,(1,'H')
    ,(257,'Fm')
) | % {
    $e,$a = $_
    $r = &$f $a
    "$($e-eq$r): $r"
}

Output:

True: 16
True: 119
True: 1
True: 257

Explanation

The datastring contains chemical element labels and differences of the masses of adjacent elements. Zero differences are removed.

The script:

  1. splits the datastring by a target element label.
  2. takes a first substring with elements and differences that precede the target
  3. replaces nondigit symbols to + (result for Oxigen element is: 1+3+3+2+2+1+2+2)
  4. calculates the result string as powershell expression

PowerShell , 655

$S="Ac227Ag108Al027Am243Ar040As075At210Au197B 011Ba137Be009Bi209Bk247Br080C 012Ca040Cd112Ce140Cf251Cl035Cm247Co059Cr052Cs133Cu064Dy163Er167Es252Eu152F 019Fe056Fm257Fr223Ga070Gd157Ge073H 001He004Hf178Hg201Ho165I 127In115Ir192K 039Kr084La139Li007Lu175Mg024Mn055Mo096N 014Na023Nb093Nd144Ne020Ni059Np237O 016Os190P 031Pa231Pb207Pd106Pm145Po209Pr141Pt195Pu244Ra226Rb085Re186Rh103Rn222Ru101S 032Sb122Sc045Se079Si028Sm150Sn119Sr088Ta181Tb159Tc098Te128Th232Ti048Tl204Tm169U 238V 051W 184Xe131Y 089Yb173Zn065Zr091"

$a=$args[0][0];$b=$args[0][1];if(!$b){$b=" "};
for($i=0;$i-lt500;$i+=5){if(($a-match$s[$i])-and$b-match$s[$i+1]){$s[$i+2]+$s[$i+3]+$s[$i+4];break}}

the string s was constructed with

awk '{printf(\"%-2s %03d\n\",$3,$4)}' .\input.txt | sort | awk '{printf(\"%-2s%03d\",$1,$2)}' > .\output.txt

result as follows

enter image description here

T-SQL, 627 524 bytes

SELECT ISNULL((SELECT SUBSTRING(value,3,3)FROM
STRING_SPLIT('B 11-F 19-Na23-Al27-P 31-K 39-Ar40-V 51-Mn55-Co59-Cu64-Se79-Sr88-Nb93-I 127-La139-Pr141-Nd144-Bi209-Po209-Rn222-Pa231-Np237-Am243-Cm247-Cf251','-')m,t
WHERE s=LEFT(value,2)),
(SELECT CHARINDEX(s,'H .He.LiBe.C N O ..Ne..Mg..Si..S .Cl..KCa...Sc.Ti..Cr..Fe.Ni....Zn...Ga.GeAs...Br..KRb..Y Zr...MoTc.RuRh.PdAg..Cd.In..Sn.Sb....Te.XeCs..Ba.Ce...Pm...SmEu...GdTb..DyHoErTm..YbLu.Hf.Ta.W Re..OsIr.PtAu..Hg.Tl.Pb.At...........Fr.RAc...Th....U ....Pu.Bk...Es...Fm')
FROM t))

Significant redesign, here, saved over 100 bytes.

Here is how this one works, reading back to front:

  • The main piece here is a string (inside the CHARINDEX(), the dots are just filler) that returns the element mass based on the string position, for example, the letters Ga start at string position 70, which is the mass of Gallium.
  • That unfortunately doesn't work for elements that have the same mass (Ar and Ca, for example), or elements that differ with mass that differs only by one (Al and Si), so I have a more traditional lookup table (inside the STRING_SPLIT()) that covers the exceptions.
  • The ISNULL() statement pieces it all together: first it looks in the exception table, if that returns NULL, it instead returns the position from CHARINDEX.

Original version, 627 bytes:

SELECT SUBSTRING(value,3,3)
FROM STRING_SPLIT('H 1-He4-Li7-Be9-B 11-C 12-N 14-O 16-F 19-Ne20-Na23-Mg24-Al27-Si28-P 31
    -S 32-Cl35-Ar40-K 39-Ca40-Sc45-Ti48-V 51-Cr52-Mn55-Fe56-Co59-Ni59-Cu64-Zn65-Ga70-Ge73
    -As75-Se79-Br80-Kr84-Rb85-Sr88-Y 89-Zr91-Nb93-Mo96-Tc98-Ru101-Rh103-Pd106-Ag108-Cd112
    -In115-Sn119-Sb122-Te128-I 127-Xe131-Cs133-Ba137-La139-Ce140-Pr141-Nd144-Pm145-Sm150
    -Eu152-Gd157-Tb159-Dy163-Ho165-Er167-Tm169-Yb173-Lu175-Hf178-Ta181-W 184-Re186-Os190
    -Ir192-Pt195-Au197-Hg201-Tl204-Pb207-Bi209-Po209-At210-Rn222-Fr223-Ra226-Ac227-Th232
    -Pa231-U238-Np237-Pu244-Am243-Cm247-Bk247-Cf251-Es252-Fm257','-')
,t WHERE LEFT(value,2)=s

Returns are for formatting only.

Per our IO standards, input is taken via pre-existing table t with chemical symbol s. Joins to in-memory table derived from a delimited string.

C (clang), 252 251 bytes

*a=L"H效楌敂BCNOF敎慎杍汁楓PS汃牁K慃捓楔V牃湍敆潃楎畃湚慇敇獁敓牂牋扒牓Y牚扎潍捔畒桒摐杁摃湉湓打敔I敘獃慂慌敃牐摎浐浓畅摇扔祄潈牅浔扙界晈慔W敒獏牉瑐畁杈汔扐楂潐瑁湒牆慒捁桔慐U灎畐流浃歂晃獅浆";f(short*x){return L"敉敌敏救敓敔敖敘敛敜敟敠散敤敧敨敫数敯数敵數敻敼敿斀斃斃斈斉斎斑斓斗斘斜斝斠斡斣斥斨斪断斯斲斴斸斻斿旂旈旇旋旍旑旓旔旕旘旙旞无日旧旫旭旯旱旵旷旺旽昀昂昆昈昋昍昑昔昗昙昙昚昦昧昪昫昰是昶昵昼昻昿昿晃晄晉"[wcschr(a,*x)-a]-a[1];}

Try it online!

Just a pair of table lookups. Little endian only.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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