44
0
The Challenge
Write a program that can break down an input chemical formula (see below), and output its respective atoms in the form element: atom-count.
Input
Sample input:
H2O
Your input will always contain at least one element, but no more than ten. Your program should accept inputs that contain parentheses, which may be nested.
Elements in the strings will always match [A-Z][a-z]*, meaning they will always start with an uppercase letter. Numbers will always be single digits.
Output
Sample output (for the above input):
H: 2
O: 1
Your output can be optionally followed by a newline.
Breaking Down Molecules
Numbers to the right of a set of parentheses are distributed to each element inside:
Mg(OH)2
Should output:
Mg: 1
O: 2
H: 2
The same principle applies to individual atoms:
O2
Should output:
O: 2
And also chaining:
Ba(NO2)2
Should output:
Ba: 1
N: 2
O: 4
Examples
> Ba(PO3)2
Ba: 1
P: 2
O: 6
> C13H18O2
C: 13
H: 18
O: 2
> K4(ON(SO3)2)2
K: 4
O: 14
N: 2
S: 4
> (CH3)3COOC(CH3)3
C: 8
H: 18
O: 2
> (C2H5)2NH
C: 4
H: 11
N: 1
> Co3(Fe(CN)6)2
Co: 3
Fe: 2
C: 12
N: 12
Inputs are denoted by an arrow (greater-than sign; >).
Scoreboard
For your score to appear on the board, it should be in this format:
# Language, Score
Or if you earned a bonus:
# Language, Score (Bytes - Bonus%)
function getURL(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){$.ajax({url:getURL(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),useData(answers)}})}function getOwnerName(e){return e.owner.display_name}function useData(e){var s=[];e.forEach(function(e){var a=e.body.replace(/<s>.*<\/s>/,"").replace(/<strike>.*<\/strike>/,"");console.log(a),VALID_HEAD.test(a)&&s.push({user:getOwnerName(e),language:a.match(VALID_HEAD)[1],score:+a.match(VALID_HEAD)[2],link:e.share_link})}),s.sort(function(e,s){var a=e.score,r=s.score;return a-r}),s.forEach(function(e,s){var a=$("#score-template").html();a=a.replace("{{RANK}}",s+1+"").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SCORE}}",e.score),a=$(a),$("#scores").append(a)})}var QUESTION_ID=58469,ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",answers=[],answer_ids,answers_hash,answer_page=1;getAnswers();var VALID_HEAD=/<h\d>([^\n,]*)[, ]*(\d+).*<\/h\d>/;
body{text-align:left!important}table thead{font-weight:700}table td{padding:10px 0 0 30px}#scores-cont{padding:10px;width:600px}#scores tr td:first-of-type{padding-left:0}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id="scores-cont"><h2>Scores</h2><table class="score-table"><thead> <tr><td></td><td>User</td><td>Language</td><td>Score</td></tr></thead> <tbody id="scores"></tbody></table></div><table style="display: none"> <tbody id="score-template"><tr><td>{{RANK}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SCORE}}</td></tr></tbody></table>
Edit: Square brackets are no longer a part of the question. Any answers posted before 3AM UTC time, September 23, are safe and will not be affected by this change.
What are the allowed forms of input? – Oberon – 10 years ago
1@ZachGates It's better that we're allowed to support either, but keep in mind that square brackets is still incorrect. AFAIK in chemical formulae square brackets are only used to indicated concentration. E.g.:
[HCl] = 0.01 mol L^-1. – orlp – 10 years agoThey are, but for all intensive purposes we're going to use them for grouping, too. @orlp Unless it's really a big deal; in which case, I'll removed brackets completely. – Zach Gates – 10 years ago
See the "Examples" section. Is there something specific you're asking about? @Oberon Inputs are denoted by a
>. – Zach Gates – 10 years agoCould you maybe add some really complex examples for people to test with? – orlp – 10 years ago
I've just added a few more examples. Currently, only valid chemical formulas are shown in the post. I could perhaps add some non-real examples; just let me know. @orlp – Zach Gates – 10 years ago
The prompt is needed? Is it enough to process one formula at once? The prompt is '> ' or just '>'? – uno20001 – 10 years ago
No, it should handle just one input. The
>format was purely for demonstration. @uno20001 – Zach Gates – 10 years agoMust the output format be exactly as above? Or are similar formats allowed? – orlp – 10 years ago
Each element must be in the format
element: atom-countfollowed by a newline. (the format above) @orlp – Zach Gates – 10 years ago+1 for a great challenge, but is there any good reason you are allowing square brackets? They are chemically incorrect and arguably don't add much to the question. – March Ho – 10 years ago
I've just removed them. :-) Any answers posted before 3AM UTC, September 23, are safe and will not be affected by this change, as per the above edit. @MarchHo – Zach Gates – 10 years ago
Would it be safe to assume that the numbers are always single digit? – Reto Koradi – 10 years ago
Yes. I just edited to add this detail, also. @RetoKoradi – Zach Gates – 10 years ago
Challenge would be so much better if you had to output the elements in Atomic Number order :-) – corsiKa – 10 years ago
Perhaps the next one will have that element. @corsiKa – Zach Gates – 10 years ago
I hope so, it will energize the community. – corsiKa – 10 years ago
1Just a note, the examples still have elements with multiple digit atom counts. – ProgrammerDan – 10 years ago
In Perl 5, it seems to me that
s/(?|([A-Z][a-z]*)|\(((?0)+)\))(\d)?/$1x($2||1)/geshould work to expand the string (preparatory to parsing it further), but it doesn't. Maybe someone can work with that, though. – msh210 – 10 years ago