4
\$\begingroup\$

Air balloons need a gas that is lighter than air. However, hydrogen is flammable, while helium is not sustainable, so we need a replacement! You must write code that determines whether any given gas is lighter than air.


Input: a molecular chemical formula of a gas (ASCII)

Output: true if the gas is lighter than air; false otherwise (see here for consensus on what can be used as true and false).

If the chemical formula doesn't represent a gas (at standard conditions), or if it's a nonsense, any behavior is acceptable.

That is to say, you can assume the following:

  • The input is a valid chemical formula
  • The input is a molecular chemical formula: all element symbols are mentioned only once, and there are no parentheses
  • The chemical substance exists at normal conditions
  • The chemical substance is a gas at normal conditions

As a special case, H2O (water vapor) is considered a gas, because you can mix a significant quantity of it with air at standard conditions.


Whether or not a gas is lighter than air can be determined by calculating its molar mass:

Extract the chemical element symbols from the formula. Their atomic masses are given by the following table:

  • H - 1
  • He - 4
  • B - 11
  • C - 12
  • N - 14
  • O - 16
  • F - 19
  • Ne - 20
  • Others - greater values

Calculate the molar mass, which is the sum of all the atomic masses. If the molar mass is less than 29, the gas is lighter than air.


Test cases:

H2      true
He      true
B2H6    true
CH4     true
C2H2    true
C2H4    true
HCN     true
N2      true
NH3     true
H2O     true
CO      true
HF      true
Ne      true
O2      false
C2H6    false
C4H10   false
H2S     false
COH2    false
CO2     false
SiH4    false
NO      false
BN      behavior nor specified: not a gas
HBO2    behavior nor specified: not a gas
F2O     behavior nor specified: incorrect formula
CH3     behavior nor specified: incorrect formula
HCOOH   behavior nor specified: not a molecular formula
B(OH)3  behavior nor specified: not a molecular formula
XYZ     behavior nor specified: nonsense

(Note: this is meant to be an enumeration of all possible inputs that generate true. If I forgot some, I'll add it. In any case, Wikipedia is the answer for questions like "Does substance X exist?", "Is it a gas?")


A related (but different) question: calculate the molar mass

\$\endgroup\$
  • 5
    \$\begingroup\$ Can we assume that He are Neare noble and so don't combine? \$\endgroup\$ – Luis Mendo May 26 '16 at 15:00
  • 4
    \$\begingroup\$ This seems like just take your linked "calculate the molar mass" challenge and add a conditional on the output. How does that make this challenge different enough to not be a duplicate? \$\endgroup\$ – AdmBorkBork May 26 '16 at 15:03
  • 1
    \$\begingroup\$ 'Others - greater values'. What are the others, and those greater values? Maybe I just don't know enough chemisty, but it's not obvious to me why F2O and CH3 and invalid. \$\endgroup\$ – Morgan Thrapp May 26 '16 at 15:11
  • \$\begingroup\$ @TimmyD This is significantly easier (fewer possibilities; no floating-point), so I think you can make code significantly smaller. And also maybe different approaches are possible with this challenge (dictionary?). \$\endgroup\$ – anatolyg May 26 '16 at 15:12
  • \$\begingroup\$ Can I assume that the input will not have parentheses? \$\endgroup\$ – Leaky Nun May 26 '16 at 15:13
1
\$\begingroup\$

Perl 5, 52 bytes

51 plus 1 for -p:

$_=/^(B2H6|C2H2|C2?H4|H(CN|F|2O?|e)|N2|NH3|Ne|CO)$/

or

$_=/^(B2H6|C2H2|C2?H4|H(CN|F|2O)|[HN][e2]|NH3|CO)$/

or any of a few similar scripts.

Based (obviously) on MattPutnam's Clojure answer.

\$\endgroup\$
1
\$\begingroup\$

Retina, 108 104 bytes

[A-Z]
;$&
Ne
xF
F
xxxO
O
xxN
N
xxC
C
xB
B
11$*x
e
xxx
H
x
x(?=x*(\d+))
$1$*x
[A-Z]
30$*x
[^x]

M`x{29}
0

Try it online!

Test suite.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 119 bytes

s=>s.replace(/([A-Z][a-z]?)(\d*)/g,(_,a,n)=>m+=[11,12,19,1,4,14,20,16]["B C F H HeN NeO".search(a)/2]*(n||1),m=0)&&m<29

Any unknown atom causes the result to compute to NaN which is not less than 29.

\$\endgroup\$
1
\$\begingroup\$

Clojure, 69 bytes

#(#{"H2""He""B2H6""CH4""C2H2""C2H4""HCN""N2""NH3""H2O""CO""HF""Ne"}%)

If that's the full list of truthy answers...

\$\endgroup\$
  • 1
    \$\begingroup\$ Can you compress it? I see a lot of quote characters there. \$\endgroup\$ – anatolyg May 28 '16 at 11:45
0
\$\begingroup\$

Python, 235 Bytes

import re
a={"H":1,"He":4,"B":11,"C":12,"N":14,"O":16,"F":19,"Ne":20}
try:print(str(29>sum([int(p[1])*a[p[0]] for p in [c if c[1]!="" else (c[0],"1") for c in re.findall(r'([A-Z][a-z]*)(\d*)',input())]])).lower())
except:print("false")

Explanation:

import re # For the Regex
a={...} # Defining masses
try... except: # Catches unexpected elements and return false
re.findall(r'([A-Z][a-z]*)(\d*)',input()) # Group capture of the elements (credit to Draxx)
c if c[1]!="" else (c[0],"1") for c in # Sometimes, they may not have numbers after them, thus, if else!
int(p[1])*a[p[0]] # Mass of each elements
str(29>sum(...)).lower() # Boolean whether the statement is true/false translated to lower case string

Or, taking the MattPutnam way of doing things...

Python, 71 Bytes

lambda n:n in"H2 He B2H6 CH4 C2H2 C2H4 HCN N2 NH3 H2O CO HF Ne".split()

(Credit to @Lynn)

\$\endgroup\$
  • \$\begingroup\$ lambda n:n in"H2 He B2H6 CH4 C2H2 C2H4 HCN N2 NH3 H2O CO HF Ne".split() might work \$\endgroup\$ – Lynn May 29 '16 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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