비 환식 탄소 사슬 명명


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. 두 개 이상의 다른 치환기가있는 경우 기본 이름을 사용하여 사전 순으로 나열됩니다 (접두사 무시). 알파벳 순서로 치환기를 넣을 때 사용되는 유일한 접두사는 이소 프로필 또는 이소 부틸에서와 같이 이소이다. 접두사 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'대신에 'yl'이 있습니다.

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 두 개의 메틸 사슬이 있기 때문에 동의합니다.
Jonathan Frech

@NieDzejkob 실제로 수정되었습니다.
피터 Lenkefi

답변:


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. 올바르게 인쇄하십시오.

편집 : 사이드 체인이없는 경우 오류가 발생하는 버그가 수정되었습니다.

편집 : 몇 개의 추가 공백을 발견 한 MD XF 덕분입니다 (for 루프에 대한 들여 쓰기).

편집 : 나는 동일한 치환기를 갖는 접두사를 완전히 잊어 버렸습니다.

참고 :이 작업을 수행하려면 각 줄의 너비가 같아야합니다. 즉, 후행 공백이 필요합니다.

재미있는 사실 : 대부분의 고리 형 탄화수소는 "메탄"으로 결정됩니다

재미있는 사실 : 당신이 경우에 C-C-...-C-C(13 개) 고사와 함께, 그것은 줄 것이다 ethane다음 thane, 14 ropane등, 15

Jonathan Frech 덕분에 -79 바이트,
NieDzejkob 덕분에 -119
바이트, ovs 덕분에 -17 바이트

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.