質量分析計を作ろう!


8

チャレンジ

有機分子の高解像度の分子量を考慮して、分子の分子式を出力します。

説明

入力は、小数点以下3桁の精度の単一の数値、つまり分子の相対分子量になります。

ここで、分子量は、化合物中の原子の質量の合計として定義されます。あなたは有機化合物の分子式を見つけるだけなので、知っておくべき原子質量は次のとおりです。

  • C、カーボン:12.011
  • H、水素:1.008
  • O、酸素:15.999
  • N、窒素:14.007

フォーミュラは、炭素、水素、酸素または窒素のみを含む必要があります。

式を書くとき、それは次の形式をとるべきです:

CaHbOcNd

要素がこの順序でなければならない(ただしC -> H -> O -> N、そうC2O8N4H6でなければならないC2H6O8N4)とabcおよびd分子内の先行する要素の数(すなわち、あるC2分子内に2個の炭素原子が存在することを意味します)。

場合abcまたはdゼロであり、その要素は、(例えば、式中に含まれるべきではないC2H6O2N0でなければなりませんC2H6O2)。最後に、場合abcまたはd一つであり、あなたは式(例えばに番号を含めるべきではありませんC1H4する必要がありますCH4)。

入力は常に有効です(つまり、その質量の分子が存在します)。入力があいまいな場合(複数の分子が同じ質量を持っている場合)、分子の1つのみを出力する必要があります。この分子の選び方はあなた次第です。

実施例

入力が180.156であるとすると、この分子量を持つことができる要素の組み合わせは1つだけです。

12.011*6 + 1.008*12 + 15.999*6 + 14.007*0 = 180.156

だからあります:

  • 6カーボン
  • 12水素
  • 6酸素
  • 0窒素

したがって、出力は次のようになります。

C6H12O6

その他の例

Input -> Output

28.054 -> C2H4
74.079 -> C3H6O2
75.067 -> C2H5O2N
18.015 -> H2O

勝利

バイト単位の最短コードが優先されます。


2
入力があいまいな場合はどうなりますか?
NoOneIsHere

@NoOneIsHere AFAIK入力はあいまいであってはなりませんが、とにかくそれをルールに追加します。
ベータ崩壊

入力はintとして取得できます(つまり、ピリオドはありません-エテンはそうなります28054
Stephen

4
12.011炭素の相対原子質量であり、同位体の相対同位体質量の加重平均です。異なる同位体が区別される質量分析計では、正確に表示されます12。他の原子についても同様です。
Leaky Nun

2
楽しいテストのために、入力に672.336は、純粋な窒素と純粋な水素のソリューションを含む、24の可能なソリューションがあることに注意してください。
グレッグマーティン

回答:


2

Mathematica、108バイト

Print@@Join@@({Characters@"CHON",#}ᵀ/.a_/;Last@a<2:>Table@@a)&/@{12011,1008,15999,14007}~FrobeniusSolve~#&

入力を整数(相対分子量の1000倍)として期待する純粋な関数。STOUDへの可能なすべての回答を出力します(そしてNullsの配列を返します)。

重い処理は組み込みによって行われます。組み込み関数{12011,1008,15999,14007}~FrobeniusSolve~#は、入力に等しいハードコードされた重みのすべての非負の整数の組み合わせを見つけます。{Characters@"CHON",#}ᵀそのような組み合わせをそれぞれのような形に置きます{{"C", 0}, {"H", 1}, {"O", 2}, {"N", 3}}。(実際には、3バイトのプライベートMathematica文字U + F3C7です。)

変換規則は、/.a_/;Last@a<2:>Table@@aフォームのペアを変更{x, 0}する{}と、フォームのペア{x, 1}{x}(それは同様に式全体に適用しようとしてエラーを吐き出します)。次にPrint@@Join@@、正しい形式で結果を出力します。整数を文字列としてキャストして連結する必要はありません。


672336の結果は何ですか?:)
ベータ崩壊

間違った文字のようです。する必要があります
マーティンエンダー

ええ、読みやすいか、切り取り/貼り付けやすいかを選択する必要があります。
グレッグマーティン

2

Python 2、242バイト

b=[12011,1008,15999,14007]
def p(m):
 if m in b:x=[0,]*4;x[b.index(m)]=1;return x
 elif m<1:return 0
 else:
  for i in range(4):
   x=p(m-b[i])
   if x:x[i]+=1;return x
  return 0
print''.join(a+`n`*(n>1)for n,a in zip(p(input()),'CHON')if n)

オンラインでお試しください!
再帰関数、入力は整数(相対分子量の1000倍)で、Stephen Sのアイデアに感謝


私のマシンは、この変更されたコード672336を使用C33H115O3N8して変換するまでに40セグメントを必要としました。再帰呼び出しの量を減らすためのヒット/失敗のルックアップテーブルと、要素を複数回カウントするための最適化(質量が十分に大きい場合)が含まれています


180156すべてのテストケースが非常に高速なのに、なぜタイムアウトになるのですか?(キャッシュヒットなし)
Beta Decay

@BetaDecayうーん、18015代わりに?
ロッド

いいえ、そうで18015H2OありませんC6H12O6
Beta Decay

1

JavaScript(ES6)、159 158バイト

正確ではない...

w=>[...Array(w**4|0)].some((_,n)=>![12011,1008,15999,14007].reduce((p,c,i)=>p-c*(x[i]=n%w|!(n/=w)),w*1e3,x=[]))&&x.map((v,i)=>('CHON'[i]+v).slice(0,v)).join``

デモ


高速バージョン、174 173バイト

w=>[...Array(w**3|0)].some((_,n)=>r=(d=w*1e3-14007*(a=n/w/w%w|0)-15999*(b=n/w%w|0)-12011*(c=n%w|0))%1008|d<0?0:[c,d/1008,b,a])&&r.map((v,i)=>('CHON'[i]+v).slice(0,v)).join``

すべてのテストケース

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.