Calculating dehydration synthesis results

6

Disclaimer: This challenge is extremely scientifically inaccurate. ;)

Given an input of a list of molecules, output what the result would be if they were to all combine via dehydration synthesis, if possible.

For the purposes of this challenge, although this description is inaccurate, a dehydration reaction between two molecules is performed as follows:

  1. Remove OH (one oxygen and one hydrogen atom) from either of the two molecules.

  2. Remove H (a single hydrogen atom) from the other one.

  3. Combine the two molecules into one.

For instance, combining two C6H12O6 molecules via dehydration synthesis would result in C12H22O11. Note that there are two less Hs and one less O in the product than in the reactants. (These missing parts would form H2O, hence "dehydration," but that's irrelevant to this challenge.)

An example of molecules that cannot be combined via dehydration synthesis is C6H12O6 + CO2. The required amount of hydrogen and oxygen is present, but neither OH nor H can be taken from the CO2.

The format of the input for each molecule is a list of atoms concatenated. An atom is always a single capital letter, possibly followed by a single lowercase letter (you don't have to handle atoms like Uuo). Atoms may also have integers ≥ 2 after them, representing how many of them there are; if this number is not present, it is assumed to be 1. Atoms will never be repeated within the same molecule.

Input may be provided as either an array/list/etc. of strings, or a single string separated by any non-alphanumeric character. Output must be a single string, but the output for "invalid input" (i.e. a list of molecules that cannot be combined via dehydration synthesis) may be any string containing at least one non-alphanumeric character (to distinguish from valid output). The order of the atoms in the output does not matter.

Since this is , the shortest code in bytes will win.

Test cases (invalid output is represented here by an asterisk *):

In                                                Out
------------------------------------------------------------------
C6H12O6 C6H12O6 C6H12O6 C6H12O6 C6H12O6 C6H12O6 | C36H62O31
CHO5 CH2 CH2 CH2 CH2 CH2                        | C6H
CHO4 CH2 CH2 CH2 CH2 CH2                        | *
H H H CH3O3                                     | C
H H H CH4O2                                     | *
C6H12O6 ABCDELMNOP C6H12O6                      | *
HO HO HO H3                                     | <empty string>
HgO4 C6H12O6                                    | *
HgHO4 C6H12O6                                   | HgH11O9C6
PdZnXeRaHO KrArKRbFH                            | PdZnXeRaKrArKRbF

Doorknob

Posted 2016-02-14T23:17:44.483

Reputation: 68 138

1Flashbacks to my chem class... Nice challenge though. – Rɪᴋᴇʀ – 2016-02-17T22:06:29.910

Answers

1

Python (337 336 chars)

import re
i=input().split()
a,d,o,e=[],{},"",len(i)-1
for b in i:a.append(dict(re.findall(r"([A-Z][a-z]*)(\d*)",b)))
a=[{b:int(c[b])if c[b]else 1for b in c}for c in a]
for b in a:
 for c in b:d[c]=c in d and d[c]+b[c]or b[c] 
 if"H"not in b:d["-"]=0
d["H"]-=2*e;d["O"]-=e
for b in d:o+=b+(str(d[b])if d[b]-1else"")if d[b]else""
print(o)

Here is an example of how to use this program:

sh3.14$ python dehydrate.py <-Run the program
C6H12O6 HgHO4               <-Input
O9H11C6Hg                   <-Output

Try it!

K Zhang

Posted 2016-02-14T23:17:44.483

Reputation: 5 698

I don't think having the user define i is acceptable as input. Try defining i as i=input(). – Rɪᴋᴇʀ – 2016-03-17T02:29:27.650

@EasterlyIrk Really? I think it's valid. Look at the question again: "Input may be provided as either an array/list/etc. of strings, or a single string separated by any non-alphanumeric character." – K Zhang – 2016-03-17T20:45:54.930

@KZhange yes, but consensus is that you may not force the user to do anything that modifies the code. – Rɪᴋᴇʀ – 2016-03-17T21:39:47.763

Here is a meta post about it: link.

– Rɪᴋᴇʀ – 2016-03-17T21:45:48.577

@EasterlyIrk Okay, I have modified the program to be a function instead. Thanks for notifying me, by the way. – K Zhang – 2016-03-17T22:14:24.070

You can also just use i=input(). – Rɪᴋᴇʀ – 2016-03-17T22:59:02.713

1

Pyth (95 chars)

After seeing tiny, unreadable programs in CJam, Jelly, and Pyth, I decided to learn a golfing language, and because I am familiar with Python, I learned Pyth. Here is my code to solve this question:

FNQ aY.dm.Dd0:N"([A-Z][a-z]*)(\d*)"4;FNYFkN XkH|s@Nk1; X"O"HJ-1lQ; X"H"H*2J;FNHI@HNpNI>@HN1p@HN

The method that I have used to combine the molecules is similar to the one that I have used above implemented in Python. Here is a breakdown of that happens, statement by statement, character by character.

FNQ                                  For N in Q (input):
        m                             Map (same as python map())
         .Dd0                          Function for removing first element
             :N"([A-Z][a-z]*)(\d*)"4;  Get array of matches & groups
      .d                              Convert to dict
    aY                                Append to Y (pre-defined as an array)

FNY                                  For N in Y:
   FkN                                For K in N:
       XkH                             Increment/set H[k] (H pre-defined as a dict) to the following value
          |s@Nk1;                       if N[k] is null, then 1; else int(N[k])

 X"O"HJ-1lQ;                         Decrement H["O"] by length of Q - 1, and set J to length of Q - 1

 X"H"H*2J;                           Decrement H["H"] by 2 * J

FNH                                  For N in H:
   I@HN                               If H[N] (!= 0):
       pN                              Print N
         I>@HN1                       If H[N] > 1:
               p@HN                    Print H[N]

Test it! Note: The spaces in the code are for suppressing outputs.

K Zhang

Posted 2016-02-14T23:17:44.483

Reputation: 5 698