# Codeium Golfide

## C, 208205175 169 bytes

argv[1] : cation
argv[2] : anion
Charges of ions are taken on stdin.

#define z(b)for(i=*++v;*++i>95;);printf(b>1?*i?"(%s)_%d":"%s_%d":"%s",*v,b);
main(c,v,d,e,g,h,i)char**v,*i;{scanf("%d%d",&c,&d);for(e=c,h=-d;g=h;e=g)h=e%g;z(-d/e)z(c/e)}


### Retina, 86 80 bytes

Thanks to Neil for saving 6 bytes.

^
(
\^.+
)_$&$*
(1+)(\1|¶.+)+_(\1)+#3$2_$#2
_1$m)T().+\)$|$$.[a-z]?$$
¶



Try it online!

Input is linefeed-separated (test suite uses comma-separation for convenience).

### Explanation

^
(


We start by prepending a ( to each molecule. The ^ matches on line beginnings because the m) towards the end of the program sets multiline mode for all preceding stages.

\^.+
)_$&$*


We replace the ^[-+]n part with )_, followed by n copies of 1 (i.e. we convert the charges to unary, dropping the signs).

(1+)(\1|¶.+)+_(\1)+#3$2_$#2


This stage does three things: it divides both charges by their GCD, converts them back to decimal and swaps them. The GCD can be found quite easily in regex, by matching the longest 1+ that lets us match both charges using only the backreference \1. To divide by this, we make use of Retina's "capture count" feature, which tells us how often a group has been used. So $#2 is the first charge divided by the GCD and $#3 is the second charge divided by the GCD (both in decimal).

_1$ We remove _1s from the ends of both parts. m)T().+\)$|$$.[a-z]?$$


And we drop the parentheses from lines which end in a ) (i.e. those that had a _1 there), as well as lines that only contain a single atom.

¶



Finally, we concatenate the two molecules by dropping the linefeed.

## APL (Dyalog), 6059 61 bytes

+2 since charges must be given signed.

Anonymous infix function. Takes list of ions (anion, cation) as left argument and list of corresponding charges as right argument.

{∊(⍺{⍵∧1<≢⍺∩⎕D,⎕A:1⌽')(',⍺⋄⍺}¨m),¨(m←s≠1)/¨'_',∘⍕¨s←⍵÷⍨∧/⍵}∘|


Try it online!

{}∘| function where ⍺ is left argument and ⍵ is right argument's magnitude:

∧/⍵ LCM of the charges

⍵÷⍨ divide the charges by that

s← store in s (for subscripts)

'_',∘⍕¨ format (stringify) and prepend underbar to each

()/ replicate each letter of each with the corresponding value from:

s≠1 Is s different from 1? (gives 1 or 0)

m← store in m (for multiple)

(),¨ prepend the following respectively to those:

⍺{}¨m for each, call this function with ions and m as arguments:

⎕D,⎕ADigits followed by uppercase Alphabet

⍺∩ intersection of ion and that

≢ tally the number of characters in that

1< Is one less than that? (i.e. do we have a multi-element ion?)

⍵∧ and do we need multiple of that ion?

: if so, then:

')(',⍺ prepend the string to the ion

1⌽ cyclically rotate one step to the left (puts ) on the right)

⋄ else

⍺ return the ion unmodified

∊ϵnlist (flatten)