अणु से अणु


44

चुनौती

एक प्रोग्राम लिखें जो एक इनपुट रासायनिक सूत्र को तोड़ सकता है (नीचे देखें), और फॉर्म में अपने संबंधित परमाणुओं को आउटपुट करें element: atom-count


इनपुट

नमूना इनपुट:

H2O

आपके इनपुट में हमेशा कम से कम एक तत्व होगा, लेकिन दस से अधिक नहीं। आपके प्रोग्राम को ऐसे इनपुट्स को स्वीकार करना चाहिए, जिनमें कोष्ठक होते हैं, जो नेस्टेड हो सकते हैं।

तारों में तत्व हमेशा मेल खाते हैं [A-Z][a-z]*, जिसका अर्थ है कि वे हमेशा एक बड़े अक्षर से शुरू करेंगे। अंक हमेशा एकल अंक होंगे।


उत्पादन

नमूना आउटपुट (उपरोक्त इनपुट के लिए):

H: 2
O: 1

आपका आउटपुट वैकल्पिक रूप से एक नई पंक्ति द्वारा अनुसरण किया जा सकता है।


अणु का टूटना

कोष्ठकों के एक सेट के दाईं ओर संख्याएँ प्रत्येक तत्व को अंदर वितरित की जाती हैं:

Mg(OH)2

उत्पादन करना चाहिए:

Mg: 1
O: 2
H: 2

एक ही सिद्धांत व्यक्तिगत परमाणुओं पर लागू होता है:

O2

उत्पादन करना चाहिए:

O: 2

और भी जंजीर:

Ba(NO2)2

उत्पादन करना चाहिए:

Ba: 1
N: 2
O: 4

उदाहरण

> 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

इनपुट्स को एक तीर (अधिक से अधिक संकेत; >) द्वारा निरूपित किया जाता है ।

स्कोरबोर्ड

आपके स्कोर बोर्ड पर दिखाई देने के लिए, यह इस प्रारूप में होना चाहिए:

# Language, Score

या यदि आपने एक बोनस अर्जित किया है:

# Language, Score (Bytes - Bonus%)

संपादित करें: स्क्वायर ब्रैकेट अब सवाल का हिस्सा नहीं हैं। 3 सितंबर UTC के समय, 23 सितंबर से पहले पोस्ट किए गए कोई भी उत्तर सुरक्षित हैं और इस परिवर्तन से प्रभावित नहीं होंगे।


इनपुट के अनुमत रूप क्या हैं?
ओबेरोन

1
@ZachGates यह बेहतर है कि हमें या तो समर्थन करने की अनुमति है, लेकिन ध्यान रखें कि वर्ग कोष्ठक अभी भी गलत हैं। रासायनिक सूत्रों में एएफएआईके वर्ग कोष्ठक केवल संकेतित एकाग्रता के लिए उपयोग किए जाते हैं। उदाहरण के लिए: [HCl] = 0.01 mol L^-1
15

वे हैं, लेकिन सभी गहन उद्देश्यों के लिए हम उन्हें समूहीकरण के लिए उपयोग करने जा रहे हैं, भी। @orlp जब तक यह वास्तव में एक बड़ी बात नहीं है; किस स्थिति में, मैं कोष्ठक को पूरी तरह से हटा दूँगा।
जैच गेट्स 15

"उदाहरण" अनुभाग देखें। क्या कुछ विशिष्ट है जिसके बारे में आप पूछ रहे हैं? @ ऑबरन इनपुट्स ए द्वारा निरूपित किए जाते हैं >
जैच गेट्स 15

1
बस एक नोट, उदाहरणों में अभी भी कई अंकों के परमाणु गणना वाले तत्व हैं।
प्रोग्रामरदान

जवाबों:


11

CJam, 59 57 बाइट्स

q{:Ci32/")("C#-"[ ] aC~* Ca C+"S/=~}%`La`-S%$e`{~": "@N}/

CJam दुभाषिया में इसे ऑनलाइन आज़माएं ।

यह काम किस प्रकार करता है

q             e# Read all input from STDIN.
{             e# For each character:
  :Ci         e#   Save it in C and cast to integer.
  32/         e#   Divide the code point by 32. This pushes
              e#   2 for uppercase, 3 for lowercase and 1 for non-letters.
  ")("C#      e#   Find the index of C in that string. (-1 if not found.)
  -           e#   Subtract. This pushes 0 for (, 1 for ), 2 for digits,
              e#   3 for uppercase letters and 4 for lowercase letters.

 "[ ] aC~* Ca C+"

 S/           e#   Split it at spaces into ["[" "]" "aC~*" "Ca" "C+"].
 =~           e#   Select and evaluate the corresponding chunk.
              e#     (   : [    : Begin an array.
              e#     )   : ]    : End an array.
              e#     0-9 : aC~* : Wrap the top of the stack into an array
              e#                  and repeat that array eval(C) times.
              e#     A-Z : Ca   : Push "C".
              e#     a-z : C+   : Append C to the string on top of the stack.
}%            e#
`             e# Push a string representation of the resulting array.
              e# For input (Au(CH)2)2, this pushes the string
              e# [[["Au" [["C" "H"] ["C" "H"]]] ["Au" [["C" "H"].["C" "H"]]]]]
La`           e# Push the string [""].
-             e# Remove square brackets and double quotes from the first string.
S%            e# Split the result at runs of spaces.
$e`           e# Sort and perform run-length encoding.
{             e# For each pair [run-length string]:
  ~           e#   Dump both on the stack.
  ": "        e#   Push that string.
  @N          e#   Rotate the run-length on top and push a linefeed.
}/            e#

10

पायथ, 66 65 बाइट्स

VrSc-`v::z"([A-Z][a-z]*)""('\\1',),"",?(\d+)""*\\1,"`(k))8j": "_N

मेरे पायथन जवाब का पोर्ट। केवल नियमित ब्रैकेट का उपयोग करके इनपुट का समर्थन करता है।


3
+1। एक घंटे में तीन जवाब? अच्छा लगा।
जच गेट्स

10

पायथन 3, 157 154 बाइट्स

import re
s=re.sub
f=s("[()',]",'',str(eval(s(',?(\d+)',r'*\1,',s('([A-Z][a-z]*)',r'("\1",),',input()))))).split()
for c in set(f):print(c+":",f.count(c))

केवल नियमित ब्रैकेट का उपयोग करके इनपुट का समर्थन करता है।

evalउपर्युक्त का उपयोग करके गोल्फ समाधान बनाने से पहले मैंने यह संदर्भ समाधान बनाया, जिसे मैंने बहुत ही सुरुचिपूर्ण पाया:

import re, collections

parts = filter(bool, re.split('([A-Z][a-z]*|\(|\))', input()))
stack = [[]]
for part in parts:
    if part == '(':
        stack.append([])
    elif part == ')':
        stack[-2].append(stack.pop())
    elif part.isdigit():
        stack[-1].append(int(part) * stack[-1].pop())
    else:
        stack[-1].append([part])

count = collections.Counter()
while stack:
    if isinstance(stack[-1], list):
        stack.extend(stack.pop())
    else:
        count[stack.pop()] += 1

for e, i in count.items():
    print("{}: {}".format(e, i))

6

जावास्क्रिप्ट ईएस 6, 366 बाइट्स

function f(i){function g(a,b,c){b=b.replace(/[[(]([^[(\])]+?)[\])](\d*)/g,g).replace(/([A-Z][a-z]?)(\d*)/g,function(x,y,z){return y+((z||1)*(c||1))});return(b.search(/[[(]/)<0)?b:g(0,b)}return JSON.stringify(g(0,i).split(/(\d+)/).reduce(function(q,r,s,t){(s%2)&&(q[t[s-1]]=+r+(q[t[s-1]]||0));return q},{})).replace(/["{}]/g,'').replace(/:/g,': ').replace(/,/g,'\n')}

जेएस फिडल: https://jsfiddle.net/32tunzkr/1/

मुझे पूरा यकीन है कि इसे छोटा किया जा सकता है, लेकिन मुझे काम पर वापस जाने की आवश्यकता है। ;-)


2
मुझे पूरा यकीन है कि इसे छोटा भी किया जा सकता है। चूँकि आप ES6 का उपयोग करने से जुड़े हैं, इसलिए आप फ़ंक्शंस बनाने के लिए बिग-ऐरो नोटेशन का उपयोग करके शुरू कर सकते हैं। और निहित returnबयान। अभी के लिए इतना ही काफी होना चाहिए।
इस्माईल मिगुएल

आप replaceबहुत अधिक उपयोग करते हैं ताकि आप xyz[R='replace'](...)पहली बार और abc[R] (...)प्रत्येक बाद के समय का उपयोग करके कुछ बाइट्स बचा सकें ।
डंकेमेसेस

6

सेजमैथ , 156 148 बाइट्स

import re
i=input()
g=re.sub
var(re.findall("[A-Z][a-z]?",i))
print g("(\d+).(\S+)\D*",r"\2: \1\n",`eval(g("(\d+)",r"*\1",g("([A-Z(])",r"+\1",i)))`)

इसे यहाँ ऑनलाइन आज़माएँ (उम्मीद है कि लिंक काम करेगा, ऑनलाइन खाते की आवश्यकता हो सकती है)

नोट: यदि ऑनलाइन कोशिश की जाती है, तो आपको input()स्ट्रिंग के साथ बदलने की आवश्यकता होगी (जैसे "(CH3)3COOC(CH3)3")

व्याख्या

ऋषि आपको बीजीय अभिव्यक्तियों को सरल बनाने की अनुमति देता है, बशर्ते वे सही प्रारूप में हों (देखें इस लिंक का 'प्रतीकात्मक हेरफेर' )। Eval के अंदर regexes () मूल रूप से इनपुट स्ट्रिंग को सही प्रारूप में लाने के लिए काम करता है, उदाहरण के लिए कुछ इस तरह से:

+(+C+H*3)*3+C+O+O+C+(+C+H*3)*3

eval()8*C + 18*H + 2*Oतब इसे सरल करेंगे: और फिर यह सिर्फ एक और regex प्रतिस्थापन के साथ आउटपुट को स्वरूपित करने की बात है।


5

पायथन 3, 414 बाइट्स

मुझे आशा है कि परिणाम का क्रम गिनती नहीं करता है।

import re
t=input().replace("[", '(').replace("]", ')')
d={}
p,q="(\([^\(\)]*\))(\d*)","([A-Z][a-z]*)(\d*)"
for i in re.findall(q,t):t = t.replace(i[0]+i[1],i[0]*(1if i[1]==''else int(i[1])))
r=re.findall(p,t)
while len(r)>0:t=t.replace(r[0][0]+r[0][1],r[0][0][1:-1]*(1if r[0][1]==''else int(r[0][1])));r=re.findall(p,t)
for i in re.findall(q[:-5], t):d[i]=d[i]+1if i in d else 1
for i in d:print(i+': '+str(d[i]))

5

जावास्क्रिप्ट (ईएस 6), 286 284

अन्य ईएस 6 एक की तुलना में बहुत कम नहीं है, लेकिन मैंने इसे अपना सर्वश्रेष्ठ दिया। नोट: यदि आप इसे एक रिक्त स्ट्रिंग या अधिकांश अमान्य इनपुट देते हैं तो यह त्रुटि होगी। यह भी उम्मीद करता है कि सभी समूहों के पास 1 (यानी, नहीं CO[OH]) से अधिक की गिनती हो । यदि इससे कोई चुनौती नियम टूट जाता है, तो मुझे बताएं।

a=>(b=[],c={},a.replace(/([A-Z][a-z]*)(?![0-9a-z])/g, "$11").match(/[A-Z][a-z]*|[0-9]+|[\[\(]/g).reverse().map(d=>(d*1==d&&b.push(d*1),d.match(/\(|\[/)&&b.pop(),d.match(/[A-Z]/)&&eval('e=b.reduce((f,g)=>f*g,1),c[d]=c[d]?c[d]+e:e,b.pop()'))),eval('g="";for(x in c)g+=x+`: ${c[x]}\n`'))

स्टैक-आधारित दृष्टिकोण का उपयोग करता है। सबसे पहले, यह 1बिना संख्या के किसी भी तत्व को जोड़ने के लिए स्ट्रिंग को प्रीप्रोसेस करता है , अर्थात Co3(Fe(CN)6)2बन जाता है Co3(Fe1(C1N1)6)2। फिर यह रिवर्स ऑर्डर के माध्यम से लूप करता है और तत्व मायने रखता है।

a=>(
  // b: stack, c: accumulator
  b=[], c={},

  // adds the 1 to every element that doesn't have a count
  a.replace(/([A-Z][a-z]*)(?![0-9a-z])/g, "$11")

    // gathers a list of all the elements, counts, and grouping chars
    .match(/[A-Z][a-z]*|[0-9]+|[\[\(]/g)

    // loops in reverse order
    .reverse().map(d=>(

       // d*1 is shorthand here for parseInt(d)
       // d*1==d: true only if d is a number
       // if it's a number, add it to the stack
       d * 1 == d && b.push(d * 1),

       // if there's an opening grouping character, pop the last item
       // the item being popped is that group's count which isn't needed anymore
       d.match(/\(|\[/) && b.pop(),

       // if it's an element, update the accumulator
       d.match(/[A-Z]/) && eval('

         // multiplies out the current stack
         e = b.reduce((f, g)=> f * g, 1),

         // if the element exists, add to it, otherwise create an index for it
         c[d] = c[d] ? c[d] + e : e,

         // pops this element's count to get ready for the next element
         b.pop()
       ')
  )),

  // turns the accumulator into an output string and returns the string
  eval('
    g="";

    // loops through each item of the accumulator and adds it to the string
    // for loops in eval always return the last statement in the for loop
    // which in this case evaluates to g
    for(x in c)
      g+=x+`: ${c[x]}\n`
  ')
)

बेला


5

पर्ल, 177 172 बाइट्स

171 बाइट्स कोड + 1 बाइट कमांड लाइन पैरामीटर

ठीक है, तो मैं इस एक पर regex के साथ थोड़ा दूर किया हो सकता है ...

s/(?>[A-Z][a-z]?)(?!\d)/$&1/g;while(s/\(([A-Z][a-z]?)(\d+)(?=\w*\W(\d+))/$2.($3*$4).$1/e||s/([A-Z][a-z]?)(\d*)(\w*)\1(\d*)/$1.($2+$4).$3/e||s/\(\)\d+//g){};s/\d+/: $&\n/g

उपयोग उदाहरण:

echo "(CH3)3COOC(CH3)3" | perl -p entry.pl

2

मैथेमेटिका, 152 बाइट्स

f=TableForm@Cases[PowerExpand@Log@ToExpression@StringReplace[#,{a:(_?UpperCaseQ~~___?LowerCaseQ):>"\""<>a<>"\"",b__?DigitQ:>"^"<>b}],a_. Log[b_]:>{b,a}]&

उपरोक्त एक फ़ंक्शन को परिभाषित करता है fजो इनपुट के रूप में एक स्ट्रिंग लेता है। फ़ंक्शन स्ट्रिंग लेता है और प्रत्येक तत्व नाम को उद्धरण में लपेटता है और प्रत्येक नंबर से पहले एक infix घातांक ऑपरेटर जोड़ता है, फिर स्ट्रिंग को एक अभिव्यक्ति के रूप में व्याख्या करता है:

"YBa2Cu3O7" -> ""Y""Ba"^2"Cu"^3"O"^7" -> "Y" "Ba"^2 "Cu"^3 "O"^7

तब यह उस का लघुगणक लेता है और इसे बाहर निकालता है (गणितज्ञ ध्यान नहीं देता है कि, क्या लघुगणक लेना है :)):

Log["Y" "Ba"^2 "Cu"^3 "O"^7] -> Log["Y"] + 2 Log["Ba"] + 3 Log["Cu"] + 7 Log["O"]

और फिर यह Logएक संख्या के गुणन की सभी घटनाओं का पता लगाता है और इसे {log-argument, number}तालिका के रूप में प्रस्तुत करता है और उन लोगों को आउटपुट करता है। कुछ उदाहरण:

f@"K4(ON(SO3)2)2"
K   4
N   2
O   14
S   4


f@"(CH3)3COOC(CH3)3"
C   8
H   18
O   2


f@"Co3(Fe(CN)6)2"
C   12
Co  3
Fe  2
N   12

1

जावा, 827 बाइट्स

import java.util.*;class C{String[]x=new String[10];public static void main(String[]a){new C(a[0]);}C(String c){I p=new I();int[]d=d(c,p);for(int i=0;i<10;i++)if(x[i]!=null)System.out.println(x[i]+": "+d[i]);}int[]d(String c,I p){int[]f;int i,j;Vector<int[]>s=new Vector();while(p.v<c.length()){char q=c.charAt(p.v);if(q=='(')s.add(d(c,p.i()));if(q==')')break;if(q>='A'&&q<='Z'){f=new int[10];char[]d=new char[]{c.charAt(p.v),0};i=1;if(c.length()-1>p.v){d[1]=c.charAt(p.v+1);if(d[1]>='a'&&d[1]<='z'){i++;p.i();}}String h=new String(d,0,i);i=0;for(String k:x){if(k==null){x[i]=h;break;}if(k.equals(h))break;i++;}f[i]++;s.add(f);}if(q>='0'&&q<='9'){j=c.charAt(p.v)-'0';f=s.get(s.size()-1);for(i=0;i<10;)f[i++]*=j;}p.i();}f=new int[10];for(int[]w:s){j=0;for(int k:w)f[j++]+=k;}return f;}class I{int v=0;I i(){v++;return this;}}}

Git रिपॉजिटरी w / ungolfed स्रोत (सही समता नहीं, ungolfed मल्टी-कैरेक्टर नंबर का समर्थन करता है)।

कुछ समय के लिए, मुझे लगा कि मैं जावा को कुछ प्रतिनिधित्व दूंगा। निश्चित रूप से किसी भी पुरस्कार जीतने के लिए नहीं जा रहा :)।


1

ईएस 6, 198 बाइट्स

f=s=>(t=s.replace(/(([A-Z][a-z]?)|\(([A-Za-z]+)\))(\d+)/,(a,b,x,y,z)=>(x||y).repeat(z)))!=s?f(t):(m=new Map,s.match(/[A-Z][a-z]?/g).map(x=>m.set(x,-~m.get(x))),[...m].map(([x,y])=>x+": "+y).join`\n`)

कहाँ \nएक शाब्दिक newline चरित्र है।

Ungolfed:

function f(str) {
    // replace all multiple elements with individual copies
    // then replace all groups with copies working outwards
    while (/([A-Z][a-z]?)(\d+)/.test(str) || /\(([A-Za-z]+)\)(\d+)/.test(str)) {
        str = RegExp.leftContext + RegExp.$1.repeat(RegExp.$2) + RegExp.rightContext;
    }
    // count the number of each element in the expansion
    map = new Map;
    str.match(/[A-Z][a-z]?/g).forEach(function(x) {
        if (!map.has(x)) map.set(x, 1);
        else map.set(x, map.get(x) + 1);
    }
    // convert to string
    res = "";
    map.forEach(function(value, key) {
        res += key + ": " + value + "\n";
    }
    return res;
}

1

पिप , 85 77 + 1 = 78 बाइट्स

गैर-प्रतिस्पर्धात्मक उत्तर क्योंकि यह भाषा सुविधाओं का उपयोग करता है जो चुनौती से नए हैं। सूत्र को कमांड-लाइन तर्क के रूप में लेता है, और -nउचित आउटपुट स्वरूपण के लिए ध्वज का उपयोग करता है ।

Y(VaRl:`([A-Z][a-z]*)``"&"`R`\d+``X&`R`(?<=\d|")[("]``.&`l)u:UQyu.": ".Y_NyMu

इसे ऑनलाइन आज़माएं!

मुख्य चाल रीप्क्स रिप्लेसमेंट के माध्यम से सूत्र को पिप अभिव्यक्ति में बदलना है। यह, जब स्पष्ट होगा, पुनरावृत्ति करेगा और हमारे लिए कोष्ठक को हल करेगा। फिर हम परमाणु गणना प्राप्त करने और सब कुछ सही ढंग से प्रारूपित करने के लिए थोड़ा बाद की प्रक्रिया करते हैं।

टिप्पणियों के साथ असंगठित:

                         a is command-line arg (implicit)
l:`([A-Z][a-z]*)`        Regex matching element symbols
aR:l `"&"`               Replace each symbol in a with symbol wrapped in quotes
aR:`\d+` `X&`            Add X before each number
aR:`(?<=\d|")[("]` `.&`  Add . before ( or " if it's preceded by a digit or "
Y (Va)@l                 Eval result, findall matches of l, and yank resulting list into y
u:UQy                    Remove duplicates and store in u
u.": ".(_Ny M u)         Map function {a IN y} to u, returning list of element counts;
                           append this (with colon & space) itemwise to list of symbols
                         Print that list, newline-separated (implicit, -n flag)

यहां बताया गया है कि इनपुट कैसे Co3(Fe(CN)6)2रूपांतरित होता है:

Co3(Fe(CN)6)2
"Co"3("Fe"("C""N")6)2
"Co"X3("Fe"("C""N")X6)X2
"Co"X3.("Fe".("C"."N")X6)X2
CoCoCoFeCNCNCNCNCNCNFeCNCNCNCNCNCN

फिर:

["Co" "Co" "Co" "Fe" "C" "N" "C" "N" "C" "N" "C" "N" "C" "N" "C" "N" "Fe" "C" "N" "C" "N" "C" "N" "C" "N" "C" "N" "C" "N"]
["Co" "Fe" "C" "N"]
[3 2 12 12]
["Co: 3" "Fe: 2" "C: 12" "N: 12"]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.