In chemistry there is a type of extension, .xyz extension,(https://en.wikipedia.org/wiki/XYZ_file_format), that prints in each line a chemical element, and the coordinates in the plane of the element. This is very useful for chemists to understand chemical compounds and to visualize the compounds in 3D. I thought it would be fun to, given a .xyz file, print the chemical formula.


Given an .xyz file, print the chemical formula of the compound in any programming language in the smallest possible number of bytes. Note:

  • Originally, the input was to be given as a file. As I have been pointed out, this constraints the challenge. Therefore you may assume the input is a list/array of strings, each representing a line of the .xyz file.
  • There are no restrictions in the ordering of the elements.
  • Each element should be printed with an underscore "_" delimiting the element and the number of times it appears
  • The first two lines of any .xyz file is the number of elements, and a comment line (keep that in mind).

Example Input and Output

Suppose you have a file p.xyz which contains the following (where the first line is the number of elements, and the second a comment), input:

A mystery chemical formula...  
Ba      0.000   0.000  0.000  
Hf      0.5     0.5    0.5  
O       0.5     0.5    0.000  
O       0.5     0.000  0.5  
O       0.000   0.5    0.5  



A quick test is with the example mentioned. A more thorough test is the following: since the test file is thousands of lines, I'll share the .xyz file:

  • \$\begingroup\$ Requiring input to be read from a file unnecessarily and unfairly prohibits a very significant portion of programming languages from participating in your challenge. See: meta.codegolf.stackexchange.com/a/8077/3808, meta.codegolf.stackexchange.com/q/2447/3808 \$\endgroup\$
    – Doorknob
    Jan 26, 2016 at 22:37
  • \$\begingroup\$ @Doorknob Good point. I've changed that. \$\endgroup\$
    – McGuire
    Jan 26, 2016 at 22:41
  • 2
    \$\begingroup\$ @Mego how about now? :) \$\endgroup\$
    – McGuire
    Jan 26, 2016 at 22:49
  • 5
    \$\begingroup\$ what is the answer for the large test case? \$\endgroup\$
    – Maltysen
    Jan 26, 2016 at 23:08
  • 3
    \$\begingroup\$ Does ordering matter in the output? \$\endgroup\$ Jan 26, 2016 at 23:18

5 Answers 5


Pyth - 18 bytes


Try it online here.


Japt, 21 bytes

U=¢m¸mg)â £X+'_+Uè_¥X

Test it online! Input is given as an array of strings (which can be formatted as in the link).

Ungolfed and explanation

U=¢   m¸  mg)â £    X+'_+Uè_  ¥ X
U=Us2 mqS mg)â mXYZ{X+'_+UèZ{Z==X

          // Implicit: U = input array of strings
Us2       // Slice off the first two items of U.
mqS mg    // Map each item by splitting at spaces, then taking the first item.
U=    )   // Set U to the result.
â mXYZ{   // Uniquify, then map each item X to:
UèZ{Z==X  //  Count the number of items Z in U where Z == X.
X+'_+     //  Prepend X and an underscore.
          // Implicit output

AWK, 44

NR>2{a[$1]++}END{for(i in a)printf i"_"a[i]}

Try it online.


Shell + GNU Utilities, 67

sed '1d;2d;s/ .*//'|sort|uniq -c|sed -Ez 's/\s*(\S+) (\S+)/\2_\1/g'

Try it online.

  • \$\begingroup\$ 1d;2d1,2d \$\endgroup\$
    – manatwork
    Jan 27, 2016 at 18:29
  • \$\begingroup\$ Just because trailing spaces in the output are not forbidden: tail -n+3|cut -c-3|sort|uniq -c|sed -rz 's/\s*(\S+) (\S+)/\2_\1/g' \$\endgroup\$
    – manatwork
    Jan 27, 2016 at 18:41

Mathematica, 79 53 bytes


Quite simple.


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.