Tingkat Ketidakjenuhan

11

Tingkat Ketidakjenuhan

Ini bukan teka-teki kode yang sangat sulit - tetapi saya tertarik untuk melihat banyak cara Anda menyelesaikannya.

Derajat Unsaturasi adalah jumlah ikatan kimia ganda antara atom, dan / atau bilangan cincin dalam suatu senyawa kimia.

Anda akan diberikan rumus molekuler senyawa kimia dalam bentuk XaYbZc (di mana a, b dan c adalah jumlah atom X, Y atau Z dalam senyawa) - formulanya bisa panjang dan mengandung unsur kimia apa pun dalam tabel periodik (meskipun elemen selain C, H, N, F, Cl, Br, saya dapat diabaikan karena tidak ditampilkan dalam rumus). Senyawa ini akan mengandung setidaknya satu atom karbon. Anda harus menghitung dan menampilkan Derajat Ketidakjenuhannya.

Misalnya, senyawa benzena (gambar di bawah) memiliki DoU 4 karena memiliki tiga ikatan rangkap (ditunjukkan oleh garis ganda antara atom), dan cincin tunggal (sejumlah atom yang terhubung dalam satu lingkaran):

cincin benzena

Seperti yang didefinisikan oleh LibreTexts :

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

Dimana:

  • C adalah jumlah atom karbon
  • N adalah jumlah atom nitrogen
  • X adalah jumlah atom halogen ( F, Cl, Br, I)
  • H adalah jumlah atom hidrogen

Kasus uji:

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

Untuk penjelasan tentang CH lihat di sini

Intinya, Anda harus mengidentifikasi jika ada unsur-unsur di atas (C, H, N, F, Cl, Br, I) dalam senyawa, dan jika ada berapa banyak. Kemudian, hitung Derajat Ketidakjenuhan menggunakan rumus di atas.

Hanya C, H, N, F, Cl, Br, dan I yang merupakan input yang valid untuk rumus DoU. Untuk keperluan teka-teki ini, elemen lainnya dapat diabaikan sepenuhnya (mis. Jika komponnya adalah C6H6Mn hasilnya masih 4). Jika tidak ada senyawa di atas, jawabannya adalah nol.

Anda dapat mengasumsikan bahwa semua input senyawa secara kimiawi memungkinkan, mengandung setidaknya satu atom karbon, dan diketahui ada. Jika input tidak valid, program dapat menampilkan 0 atau -1, atau tidak menghasilkan apa-apa.

Aturan

Aturan dan celah IO standar berlaku. Input harus berupa string standar, dan Anda dapat mengasumsikan input tidak akan kosong. Ini adalah codegolf - jadi kode terpendek dalam byte menang.

Archie Roques
sumber
Kasus uji yang diusulkan: Sodium oxide: Na2Oand Methylidyne: CHand CCl4He. Ini adalah beberapa kasus sudut yang dapat memecahkan beberapa solusi. Ngomong-ngomong, bukankah itu penting bagi orang lain selain Mathematica (mungkin), tetapi dapatkah kita berasumsi bahwa senyawa (dapat) ada?
Stewie Griffin
Saya tidak mengerti C9H2O1 --> 0. Bukankah seharusnya angka 9? (2*9+2+0-0-2)/2
DLosc
menurut paragraf terakhir, apakah maksud Anda kode harus dapat menangani input yang tidak valid? Ngomong-ngomong, apakah dijamin bahwa setiap elemen dalam senyawa memiliki '1' tertinggal seperti pada C1H1?
Keyu Gan
@KeyuGan ya dan ya.
Archie Roques

Jawaban:

2

JavaScript (ES6), 117 112 byte

Pengembalian 0untuk input yang tidak valid.

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

Uji kasus

Versi alternatif, 103 byte

Jika input dijamin valid - karena pengantar tantangan menyesatkan - kita bisa melakukan:

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)

Demo

Arnauld
sumber
2

Python 3 , 142 151 148 byte

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)

Mengembalikan 0 pada kesalahan.

Berkat @HyperNeutrino menurunkan byte.

Cobalah online!

MooseOnTheRocks
sumber
oops - kasus uji diperbarui!
Archie Roques
Tidak cukup bekerja
HyperNeutrino
@HyperNeutrino Test case tidak jelas sedikitpun. Sekarang tidak memiliki output pada input yang tidak valid.
MooseOnTheRocks
148 bytes
HyperNeutrino
Penggunaan yang bagus di dictsana!
DLosc
0

Pip , 70 67 byte

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

Mengambil rumus kimia sebagai argumen baris perintah. Output 0untuk input yang tidak valid. Cobalah online!

Penjelasan

Menggunakan serangkaian penggantian regex untuk mengubah rumus kimia menjadi rumus matematika, mengevaluasinya, dan membuat beberapa penyesuaian untuk mendapatkan nilai akhir.

Pengganti (versi yang sedikit tidak diubah):

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)

Kami mengevaluasi string yang dihasilkan dengan V. Ini memberi kita 2C + N − X − H. Untuk mendapatkan nilai yang benar, kami melakukan penyesuaian berikut:

`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
DLosc
sumber
0

C (gcc) , 195197 202 byte

Mungkin jawaban terpanjang.

d,c,b,e,n;f(char*a){for(c=d=0;b=*a;d+=e?e-1?b-66?b-67?0:e-2?0:-n:e-3?0:-n:b-67?b-78?b/70*73/b?-n:0:n:(c=2*n):0)e=*++a>57?*a-108?*a-114?0:3:2:1,a+=e>1,n=strtol(a,&a,10);printf("%.1f",c?d/2.+1:0);}

Cobalah online!

Mengembalikan 0 pada kesalahan.

Keyu Gan
sumber