Названня нециклічних вуглецевих ланцюгів


30

(Я не хімік! Я можу помилятися в деяких речах, пишу те, що навчився в середній школі)

Атоми вуглецю мають особливий атрибут: вони можуть зв’язуватися з 4 іншими атомами (що не так вже й особливо) і вони залишаються стабільними навіть у довгих ланцюгах, що дуже унікально. Оскільки їх можна зв'язати ланцюгами та об'єднати різними способами, нам потрібна якась конвенція про іменування, щоб їх назвати.

Це найменша молекула, яку ми можемо зробити:

CH4

Це називається метан. Він складається лише з одного атома вуглецю та 4 водню. Наступний:

CH3 - CH3

Це називається етаном. Він складається з 2 вуглецевих та 6 атомів водню.

Наступні 2:

CH3 - CH2 - CH3
CH3 - CH2 - CH2 - CH3

Вони є пропаном і бутаном. Проблеми починаються з ланцюгів з 4 атомами вуглецю, оскільки його можна побудувати двома різними способами. Одне показано вище, а інше:

CH3 - CH - CH3
       |
      CH3

Це, очевидно, не те саме, що інші. Кількість атомів та зв’язок різні. Звичайно, просто складання зв'язок і обертання молекули не зроблять її іншою! Отже це:

CH3 - CH2 - CH2 - CH3

І це:

CH3 - CH2
       |
CH3 - CH2

Один і той же (Якщо ви займаєтеся теорією графів, ви можете сказати, що якщо між двома молекулами існує ізоморфізм; вони однакові). Відтепер я не випишу атоми водню, оскільки вони не є важливими для цього завдання.

Оскільки ви ненавидите органічну хімію і у вас є багато різних атомів вуглецю, ви вирішили написати програму, яка робить це за вас. У вас не так багато місця на жорсткому диску, тому програма повинна бути якомога меншою.

Змагання

Напишіть програму, яка містить багаторядковий текст як вхідний (вуглецевий ланцюг) і виводить назву вуглецевого ланцюга. Вхід буде містити лише пробіли, великі символи 'c' та '|' і '-', що являє собою зв'язування. Ланцюжок вводу ніколи не буде містити циклів! Приклад:

Вхід:

C-C-C-C-C-C
  |   |
  C   C-C

Вихід:

4-етил-2-метилгексан

Будь-який вихід прийнятний до тих пір, поки він читається людиною і по суті є однаковим (тому ви можете використовувати різні роздільники, наприклад, якщо хочете).

Конвенція про іменування:

(Див. Правила IUPAC )

  1. Визначте найдовший ланцюг вуглецю. Цей ланцюг називається батьківським ланцюгом.

  2. Визначте всі заступники (групи, що надходять із батьківського ланцюга).

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

  4. Якщо один і той же заступник зустрічається більше одного разу, вказується місце розташування кожної точки, в якій відбувається заступник. Крім того, кількість разів, коли виникає група заступника, позначається префіксом (di, tri, tetra тощо).

  5. Якщо є два або більше різних заступників, вони перераховуються в алфавітному порядку, використовуючи базову назву (ігноруйте префікси). Єдиний префікс, який використовується при введенні заступників в алфавітному порядку - iso, як у ізопропілу або ізобутилі. Префікси sec- і tert- не використовуються при визначенні алфавітного порядку, за винятком випадків, коли порівнюються один з одним.

  6. Якщо ланцюги однакової довжини конкурують за вибір в якості батьківського ланцюга, то вибір послідовно виконується на:

    • ланцюг, який має найбільшу кількість бічних ланцюгів.
    • ланцюг, заступники якого мають найменші числа.
    • ланцюг, що має найбільшу кількість атомів вуглецю в найменшому бічному ланцюзі.
    • ланцюг, що має найменш розгалужені бічні ланцюги (графік, що має найменшу кількість листків).

Для батьківського ланцюга найменування:

Number of carbons   Name
1                  methane
2                  ethane
3                  propane
4                  butane
5                  pentane
6                  hexane
7                  heptane
8                  octane
9                  nonane
10                 decane
11                 undecane
12                 dodecane

Жоден ланцюжок не буде довше 12, тому цього буде достатньо. Для під-ланцюгів це те саме, але замість 'ane' в кінці ми маємо 'il'.

Можна припустити, що Cs знаходяться в непарних стовпцях, а посилання ( |і -символи) на 1 довгу між атомами вуглецю.

Тестові приклади:

Вхід:

C-C-C-C

Вихід:

бутан

Вхід:

C-C-C
  |
  C

Вихід:

2-метилпропан

Вхід:

C-C-C-C
  |
  C
  |
  C-C

Вихід:

3-метилгексан

Вхід:

C-C-C-C-C
  |
  C
  |
  C

Вихід:

3-метилгексан

Вхід:

    C
    |
    C
    |
C-C-C-C
  |
  C-C-C
  |
  C-C

Вихід:

3,4-диметил-5-етилгептан

Редагувати: Вибачте за неправильні приклади. Я не був хорошим учнем :(. Їх слід виправити зараз.


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Денніс

2
Відповідно до цього правила, If the same substituent occurs more than once, the location of each point on which the substituent occurs is given. In addition, the number of times the substituent group occurs is indicated by a prefix (di, tri, tetra, etc.).чи не слід називати останній приклад 3,4- ді метил-5-етилгептаном? (ми тільки починаємо органічну хімію, я можу помилятися: P)
NieDzejkob

@NieDzejkob Я погодився б, оскільки є дві метильні ланцюги.
Джонатан Фрех

@NieDzejkob Дійсно, виправлено.
Пітер Ленкефі

Відповіді:


18

Python 2 , 1876 1871 1870 1859 1846 1830 1826 1900 1932 1913 1847 1833 1635 1613 1596 байт

s=input().split('\n')
W=enumerate
J=len
Y=sorted
l=J(s[0])
s=''.join(s)
S=set
M=max
A=min
p=map
f=lambda k:[(x/l,x%l)for x,V in W(s)if V==k]
g=lambda x,i,h=lambda x,i,j:x[:i]+(x[i]+j,)+x[i+1:]:[(h(q,i,-1),h(q,i,1))for q in x]
v=f('C');e=g(f('-'),1)+g(f('|'),0)
E=[V for V in v if sum(e,()).count(V)==1]
o=lambda v:[E[~E.index(v)]for E in e if v in E]
T=lambda a:lambda b:z((a,b))
Z=lambda a:p(T(a[0]),a[1])
n=lambda R:'mepbphhondudetrueeeco nothotnxptn ddh p t t'[R-1::12].strip()+(R>9)*'ec'
G=lambda K:[H[i]for i,V in W(K)if V==A(K)]
q=lambda x:[`k[0]`for k in H if k[1]==x]
B='-'.join
def z(n,c=[]):k=[x for x in S(o(n[0]))-S(c)];p=[z((j,n[1]),c+k)for j in k];return 1-~-(n[0]==n[1])*(p and A(p)or J(v))
C=[(a,b)for a in E for b in E]
a=p(z,C)
s=[(k,[E for E in v if~-z((k[0],E))+z((k[1],E))==z((k[0],k[1]))])for k in[C[x]for x,V in W(a)if V==M(a)]]
H=[]
R=0
for k,_ in s:R=M(J(_),R);_.sort(key=T(k[0]));a=sum([list(S(o(k))-S(_))for k in _],[]);H+=zip(p(lambda a:Z((a,_)).index(2),a),p(Z,[(O,[x for x in S(v)-S(_)if z((x,O),_)<J(v)])for O in a])),
X=n(R)
U=any(H)
if U:H=G([[h[0]for h in Q]for Q in H if J(Q)==M(p(J,H))]);K=[[J(Q[1])for Q in j]for j in H];H=[H[i]for i,V in W(K)if A(V)==A(sum(K,[]))];K=[J([Q[1]for Q in j if J(S(Q[1]))-J(Q[1])])for j in H];H=[[p[0]+1,n(M(p[1]))+[['isopropyl','butyl-tert','butyl-sec','isobutyl'][J(p[1])+p[1].count(3)-3],'yl'][Y(p[1])==range(1,1+M(p[1]))]]for p in G(K)[0]]
print(U and B([','.join(q(x))+'-'+'dttphhondireeeecoe itnxptnc  rtataaa  aa a '[J(q(x))-2::9].strip()+B(x.split('-')[::-1])for x in Y(list(S(zip(*H)[1])))])+X or[X,'meth']['t'==X])+'ane'

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

Ну там ви йдете. Звичайно, не найголовніший, але це працює (сподіваюся): D

Забрав мене близько 10 годин, можливо? Можливо, мій найдовший гольф і за розміром, і за часом, і це говорить про те, що я використовував Java D:

Логіка:

  1. Перетворіть з представлення ASCII у графічне подання з кожним атомом вуглецю як вузлом і кожним зв’язком у вигляді краю, представленого у формі суміжності.
  2. Знайдіть усі листя; тобто вузли лише з одним зв’язком. Гарантовано, що найдовший ланцюг буде переходити від одного до іншого.
  3. Знайдіть діадичний продукт з листя; тобто всі пари крайових вузлів. Потім візьміть довжину всіх цих ланцюгів.
  4. Для кожного ланцюга знайдіть його підзаголовки.
  5. Робіть речі, щоб вибрати правильний ланцюжок. Якщо є зв’язки, то це насправді не має значення. Факт веселості: Завжди буде краватка, оскільки кожен ланцюжок рахується двічі, один раз у зворотному порядку.
  6. Надрукуйте його належним чином.

EDIT : виправлена ​​помилка, яка раніше викликала помилки, якщо не було бічних ланцюгів.

EDIT : Завдяки MD XF, що помітив кілька додаткових пробілів (відступ для циклу for).

EDIT : Я повністю забув про префікс для того самого заступника.

ПРИМІТКА . Для роботи кожного рядка потрібно однакової ширини. Тобто потрібні пробіли.

Веселий факт: більшість циклічних вуглеводнів визначатимуться як "метан"

Веселий факт: якщо ви робите C-C-...-C-Cз 13 Cs, це дасть ethane, то thaneза 14, ropaneза 15 і т.д.

-79 байт завдяки Джонатану Фреху
-119 байтів завдяки NieDzejkob
-17 байт завдяки ovs

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