অণুতে পরমাণু


44

চ্যালেঞ্জ

এমন একটি প্রোগ্রাম লিখুন যা কোনও ইনপুট রাসায়নিক সূত্র ভেঙে ফেলতে পারে (নীচে দেখুন) এবং ফর্মটিতে তার সম্পর্কিত পরমাণুগুলি আউটপুট করতে পারে element: atom-count


ইনপুট

নমুনা ইনপুট:

H2O

আপনার ইনপুটটিতে সর্বদা কমপক্ষে একটি উপাদান থাকবে তবে দশজনের বেশি হবে না। আপনার প্রোগ্রামটি এমন ইনপুটগুলি গ্রহণ করতে হবে যাতে বন্ধনী রয়েছে which

স্ট্রিংগুলির উপাদানগুলি সর্বদা মিলবে [A-Z][a-z]*, এর অর্থ তারা সর্বদা বড় হাতের অক্ষর দিয়ে শুরু করবে। নম্বরগুলি সর্বদা একক অঙ্কে থাকবে।


আউটপুট

নমুনা আউটপুট (উপরের ইনপুট জন্য):

H: 2
O: 1

আপনার আউটপুটটি lineচ্ছিকভাবে একটি নতুন লাইন অনুসরণ করতে পারে।


অণুগুলি ভেঙে ফেলা হচ্ছে

বন্ধনীগুলির একটি সেটের ডানদিকে নম্বরগুলি প্রতিটি উপাদানগুলিতে ভিতরে বিতরণ করা হয়:

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 টা ইউটিসি সময়ের আগে পোস্ট করা কোনও উত্তর নিরাপদ এবং এই পরিবর্তন দ্বারা প্রভাবিত হবে না।


ইনপুট এর অনুমোদিত ফর্ম কি কি?
ওবেরন

1
@ জাচগেটস এটি আরও ভাল যে আমাদের কোনওটিকে সমর্থন করার অনুমতি দেওয়া হয়েছে তবে মনে রাখবেন যে বর্গাকার বন্ধনীগুলি এখনও ভুল is রাসায়নিক সূত্রে AFAIK বর্গাকার বন্ধনীগুলি কেবলমাত্র নির্দেশিত ঘনত্বের জন্য ব্যবহৃত হয়। উদাহরণ: [HCl] = 0.01 mol L^-1
orlp

তারা হ'ল, তবে সমস্ত নিবিড় উদ্দেশ্যে আমরা তাদেরকেও গ্রুপিংয়ের জন্য ব্যবহার করব। @orlp না করা যদি না এটি সত্যই বড় ব্যাপার; এই ক্ষেত্রে, আমি বন্ধনী সম্পূর্ণরূপে অপসারণ করব।
জ্যাচ গেটস

"উদাহরণ" বিভাগটি দেখুন। আপনি সুনির্দিষ্ট কিছু জিজ্ঞাসা করছেন? @ ওবারন ইনপুটগুলি এ দ্বারা বোঝানো হয়েছে >
জ্যাচ গেটস

1
কেবল একটি নোট, উদাহরণগুলিতে এখনও একাধিক অঙ্কের পরমাণু গণনা সহ উপাদান রয়েছে।
প্রোগ্রামারড্যান

উত্তর:


11

সিজেম, 59 57 বাইট

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

সিজেএম ইন্টারপ্রেটারে এটি অনলাইনে চেষ্টা করুন ।

কিভাবে এটা কাজ করে

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

জাভাস্ক্রিপ্ট ES6, 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") দিয়ে প্রতিস্থাপন করতে হবে

ব্যাখ্যা

সেজে আপনাকে বীজগণিতীয় ভাবগুলি সহজ করার অনুমতি দেয়, তারা সঠিক বিন্যাসে থাকে ( এই লিঙ্কটির 'প্রতীকী ম্যানিপুলেশন' দেখুন) providing এভাল () এর অভ্যন্তরে থাকা রেজিক্সগুলি মূলত ইনপুট স্ট্রিংটিকে সঠিক বিন্যাসে আনতে পরিবেশন করে, উদাহরণস্বরূপ:

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

eval()8*C + 18*H + 2*Oএরপরে এটিকে আরও সরল করে তুলবে: এবং তারপরে এটি অন্য রেজেক্স বিকল্পের সাথে আউটপুট ফর্ম্যাট করার বিষয়।


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

জাভাস্ক্রিপ্ট (ES6), 286 284

অন্যান্য ES6 এর চেয়ে খুব কম নয় তবে আমি এটি আমার সেরা দিয়েছি। দ্রষ্টব্য: আপনি যদি এটি একটি খালি স্ট্রিং বা সর্বাধিক অবৈধ ইনপুট দেন তবে এটি ত্রুটিযুক্ত হবে। এছাড়াও আশা করে যে সমস্ত গোষ্ঠী 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 বাইট কমান্ড লাইন প্যারামিটার

ঠিক আছে, তাই আমি এই একটার সাথে রেজেক্সের সাথে কিছুটা দূরে সরে যেতে পারি ...

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যা স্ট্রিংটিকে ইনপুট হিসাবে গ্রহণ করে। ফাংশনটি স্ট্রিং নেয় এবং প্রতিটি উপাদানটির নাম উদ্ধৃতিতে মোড়ক করে এবং প্রতিটি সংখ্যার আগে একটি ইনফিক্স এক্সপেনসিটিশন অপারেটর যুক্ত করে, তারপরে স্ট্রিংটিকে এক্সপ্রেশন হিসাবে ব্যাখ্যা করে:

"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সংখ্যার দ্বারা a এর গুণনের সমস্ত উপস্থিতি খুঁজে বের করে এবং এটিকে আকারে পার্স {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;}}}

গিট সংগ্রহস্থল W / ungolfed উত্স (নিখুঁত সমতা নয়, ungolfed বহু-চরিত্র সংখ্যা সমর্থন করে)।

কিছুক্ষণ হয়ে গেল, ভেবেছিলাম জাভাকে কিছু উপস্থাপনা দেব। অবশ্যই কোনও পুরস্কার জিততে হবে না :)।


1

ES6, 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আক্ষরিক নতুন লাইনের চরিত্রটি কোথায় ।

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"]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.