Ступінь ненасиченості


11

Ступінь ненасиченості

Це не особливо складна загадка коду - але мені цікаво бачити ваші декілька способів її вирішення.

Ступінь ненасиченості - це кількість подвійних хімічних зв’язків між атомами та / або число кільця в хімічній сполуці.

Вам дадуть молекулярну формулу хімічної сполуки у формі XaYbZc (де a, b і c - кількість атомів X, Y або Z у сполуці) - формула може бути будь-якої довжини і містити будь-який хімічний елемент у періодичній таблиці (хоча елементи, відмінні від C, H, N, F, Cl, Br, мене можуть ігнорувати, оскільки вони не містять формули). З'єднання міститиме щонайменше один атом вуглецю. Ви повинні розрахувати та відобразити його ступінь ненасиченості.

Наприклад, сполука бензолу (на фотографії нижче) має DoU 4, оскільки має три подвійні зв’язки (показані подвійною лінією між атомами) та одне кільце (кількість атомів, з'єднаних у циклі):

бензольне кільце

Як визначено LibreTexts :

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

Де:

  • C - кількість атомів вуглецю
  • N - кількість атомів азоту
  • X це число атомів галогену ( F, Cl, Br, I)
  • 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

Пояснення СН див. Тут

По суті, ви повинні визначити, чи є якісь із зазначених вище елементів (C, H, N, F, Cl, Br, I), і якщо так, то їх кількість. Потім обчисліть ступінь ненасиченості, використовуючи наведену вище формулу.

Тільки C, H, N, F, Cl, Br, і I є дійсними входами для формули DoU. Для цілей цієї головоломки будь-які інші елементи можуть бути повністю проігноровані (наприклад, якби з'єднання було C6H6Mn, результат все одно був би 4). Якщо жодної із зазначених сполук немає, відповідь буде нульовою.

Можна припустити, що всі вхідні сполуки хімічно можливі, містять щонайменше один атом вуглецю і, як відомо, існують. Якщо введення недійсне, програма може вивести або 0, або -1, або не дасть результату.

Правила

Застосовуються стандартні правила вводу- виводу та лазівки . Введення має бути стандартним рядком, і ви можете припустити, що введення не буде порожнім. Це codegolf - так виграє найкоротший код у байтах.


Пропоновані тестові приклади: оксид натрію: Na2Oі метилідин: CHі CCl4He. Це деякі кутові випадки, які можуть порушити декілька рішень. До речі, не те, що має значення для когось, крім Mathematica (напевно), але чи можна вважати, що сполуки (можуть) існувати?
Стюі Гріффін

Я не розумію C9H2O1 --> 0. Чи не повинно бути 9? (2*9+2+0-0-2)/2
DLosc

Відповідно до останнього абзацу, ви маєте на увазі, що код повинен вміти працювати з невірними вводами? До речі, чи гарантується, що кожен елемент у складі має задні «1», як у C1H1?
Кейу Ган

@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

Пітон 3 , 142 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 збиває байти.

Спробуйте в Інтернеті!


oops - тестові справи оновлені!
Арчі Рокес


Випробування @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

0

C (gcc) , 195197 202 байт

Мабуть, найдовша відповідь.

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);}

Спробуйте в Інтернеті!

Повертає 0 за помилкою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.