不飽和度


11

不飽和度

これは特に難しいコードのパズルではありませんが、それを解決する複数の方法を見てみたいと思います。

不飽和度は、原子間の二重化学結合の数、および/または化合物の環の数です。

XaYbZc(a、b、cは化合物中のX、Y、Zの原子数)の形式で化合物の分子式が与えられます-式は任意の長さで、任意の化学元素を含むことができます周期表では(ただし、C、H、N、F、Cl、Br以外の元素は、式に含まれていないため無視されます)。化合物には、少なくとも1つの炭素原子が含まれます。不飽和度を計算して表示する必要があります。

たとえば、化合物ベンゼン(下図)は、3つの二重結合(原子間の二重線で表示)と単一の環(ループで接続された原子の数)があるため、DoUは4です。

ベンゼン環

LibreTextsで定義されているとおり

DoU =(2C + 2 + N − X − H)/ 2

どこ:

  • C は炭素原子の数です
  • N は窒素原子の数です
  • X あるハロゲン原子の数(FClBrI
  • H は水素原子の数です

テストケース:

C6H6 --> 4
C9H2O1 --> 0
C9H9N1O4 --> 6
U1Pt1 --> Not a valid input, no carbon
Na2O1 --> Not a valid input, no carbon
C1H1 --> 1.5, although in practice this would be one, but is a part of a compound rather than a compound in entirety. 
N1H3 would return 0 - though in practice it isn't an organic compound (in other words it contains no carbon) so the formula wouldn't apply and it isn't a valid input

CHの説明については、こちらをご覧ください

本質的に、化合物に上記の要素(C、H、N、F、Cl、Br、I)のいずれかが存在するかどうか、および存在する場合はその数を識別する必要があります。次に、上記の式を使用して不飽和度を計算します。

DoU数式の有効な入力は、C、H、N、F、Cl、Br、およびIのみです。このパズルの目的上、他の要素は完全に無視される場合があります(たとえば、化合物がC6H6Mnの場合、結果は4のままになります)。上記の化合物がない場合、答えはゼロになります。

すべての化合物の入力は化学的に可能であり、少なくとも1つの炭素原子を含み、存在することがわかっていると仮定できます。入力が無効な場合、プログラムは0または-1を出力するか、結果を生成しません。

ルール

標準のIOルール抜け穴が適用されます。入力は標準の文字列である必要があり、入力は空ではないと想定できます。これはcodegolfです。したがって、バイト単位の最短コードが優先されます。


提案されたテストケース:酸化ナトリウム:Na2Oおよびメチリジン:CHおよびCCl4He。これらはいくつかの解決策を壊すかもしれないいくつかのコーナーケースです。ちなみに、(おそらく)Mathematica以外の人にとっては重要ではありませんが、化合物が存在する可能性があると仮定できますか?
スティーヴィーグリフィン

分かりませんC9H2O1 --> 0。9であってはいけませんか?(2*9+2+0-0-2)/2
DLosc

最後の段落によると、コードは無効な入力を処理できる必要があるということですか?ちなみに、C1H1のように、コンパウンド内のすべての要素に末尾の「1」が保証されていますか?
キーガン

@KeyuGanはい、はい。
アーチーロックス

回答:


2

JavaScript(ES6)、117 112バイト

0無効な入力に対して返します。

s=>s.split(/(\d+)/).reduce((p,c,i,a)=>p+[0,k=a[i+1]/2,2*k,-k][n='NCFHIClBr'.search(c||0)+1,s|=n==2,n>2?3:n],1)*s

テストケース

代替バージョン、103バイト

入力が有効であることが保証されている場合-チャレンジの紹介が誤解を招くように示唆しているように-行うことができます:

s=>s.split(/(\d+)/).reduce((p,c,i,a)=>p+[0,k=a[i+1]/2,2*k,-k][n='NCFHIClBr'.search(c||0)+1,n>2?3:n],1)

デモ


2

Pythonの3142の151 148バイト

import re
l=dict(re.findall("(\D+)(\d+)",input()))
m=lambda k:int(l.get(k,0))
print(m("C")and m("C")+1+(m("N")-sum(map(m,"F I H Cl Br".split())))/2)

エラー時に0を返します。

@HyperNeutrinoがバイトを減らしてくれてありがとう。

オンラインでお試しください!


おっと-テストケースが更新されました!
アーチーロックス


@HyperNeutrinoテストケースは少し不明瞭でした。無効な入力での出力がなくなりました。
MooseOnTheRocks


dictそこの素敵な使用!
DLosc

0

ピップ70 67バイト

`C\d`Na&1+/2*VaR+XDs._R['C'NC`H|F|I|Cl|Br`].s["+2*"'+'-]RXU.XX"+0*"

コマンドライン引数として化学式を取ります。0無効な入力の出力。オンラインでお試しください!

説明

一連の正規表現の置換を使用して、化学式を数学式に変換し、評価し、いくつかの調整を行って最終値を取得します。

置換(わずかに未使用のバージョン):

aR+XDs._R"C ""+2*"R"N "'+R`(H|F|I|Cl|Br) `'-RXU.XX"+0*"

a                    Cmdline arg
 R+XD                 Replace runs of 1 or more digits (\d+)
     s._               with a callback function that prepends a space
                       (putting a space between each element and the following number)
 R"C "                Replace carbon symbol
      "+2*"            with +2* (add 2* the number of carbon atoms to the tally)
 R"N "                Replace nitrogen symbol
      '+               with + (add the number of nitrogen atoms to the tally)
 R`(H|F|I|Cl|Br) `    Replace hydrogen or halogen symbol
                  '-   with - (subtract the number of atoms from the tally)
 RXU.XX               Replace uppercase letter followed by another char ([A-Z].)
       "+0*"           with +0* (cancel out numbers of all other kinds of atoms)

結果の文字列をで評価しVます。これは私たちに与え2C + N − X − Hます。正しい値を取得するために、次の調整を行います。

`C\d`Na&1+/2*V...

             V...  Value of expression calculated above
          /2*      multiplied by 1/2
        1+         plus 1
`C\d`Na            Is carbon in the original formula? (i.e. C followed by a digit)
       &           Logical AND: if no carbon, return 0, otherwise return the formula value

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