Nazywanie niecyklicznych łańcuchów węglowych

30

(Nie jestem chemikiem! Mogę się mylić w niektórych sprawach, piszę to, czego nauczyłem się w szkole średniej)

Atomy węgla mają specjalną właściwość: mogą wiązać się z 4 innymi atomami (co nie jest tak wyjątkowe) i pozostają stabilne nawet w długich łańcuchach, co jest bardzo wyjątkowe. Ponieważ można je łączyć i łączyć na wiele różnych sposobów, potrzebujemy jakiejś konwencji nazewnictwa, aby je nazwać.

To najmniejsza cząsteczka, jaką możemy wytworzyć:

CH4

To się nazywa metan. Składa się tylko z jednego węgla i 4 atomów wodoru. Następny to:

CH3 - CH3

To się nazywa etan. Składa się z 2 atomów węgla i 6 atomów wodoru.

Następne 2 to:

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

Są to propan i butan. Problemy zaczynają się od łańcuchów z 4 atomami węgla, ponieważ można je budować na 2 różne sposoby. Jeden pokazano powyżej, a drugi to:

CH3 - CH - CH3
       |
      CH3

To oczywiście nie to samo co inne. Liczba atomów i wiązań są różne. Oczywiście samo złożenie wiązań i obrócenie molekuły nie sprawi, że będzie inaczej! Więc to:

CH3 - CH2 - CH2 - CH3

I to:

CH3 - CH2
       |
CH3 - CH2

Są takie same (jeśli zajmujesz się teorią grafów, możesz powiedzieć, że jeśli między 2 cząsteczkami występuje izomorfizm; są one takie same). Odtąd nie będę wypisywać atomów wodoru, ponieważ nie są one niezbędne do tego wyzwania.

Ponieważ nienawidzisz chemii organicznej i masz wiele różnych atomów węgla, zdecydujesz się napisać program, który zrobi to za Ciebie. Nie masz zbyt wiele miejsca na dysku twardym, więc program musi być jak najmniejszy.

Wyzwanie

Napisz program, który pobiera tekst wielowierszowy jako dane wejściowe (łańcuch węglowy) i wyświetla nazwę łańcucha węglowego. Dane wejściowe będą zawierać tylko spacje, wielkie litery „c” i „|” i „-”, które reprezentuje wiązanie. Łańcuch wejściowy nigdy nie będzie zawierał cykli! Przykład:

Wkład:

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

Wydajność:

4-etylo-2-metyloheksan

Każde wyjście jest akceptowalne, o ile jest czytelne dla człowieka i zasadniczo takie samo (więc możesz na przykład użyć różnych separatorów).

Konwencja nazewnictwa:

(Patrz: zasady IUPAC )

  1. Zidentyfikuj najdłuższy łańcuch węglowy. Ten łańcuch nazywa się łańcuchem macierzystym.

  2. Zidentyfikuj wszystkie podstawniki (grupy dołączające z łańcucha macierzystego).

  3. Policz węgle łańcucha macierzystego od końca, który daje podstawnikom najniższe liczby. Porównując serię liczb, seria „najniższa” to ta, która zawiera najniższą liczbę przy pierwszej różnicy. Jeśli dwa lub więcej łańcuchów bocznych znajduje się w równoważnych pozycjach, przypisz najniższy numer do tego, który będzie pierwszy w nazwie.

  4. Jeśli ten sam podstawnik występuje więcej niż jeden raz, podaje się lokalizację każdego punktu, w którym występuje podstawnik. Ponadto liczbę wystąpień grupy podstawnikowej wskazuje przedrostek (di, tri, tetra itp.).

  5. Jeśli istnieją dwa lub więcej różnych podstawników, są one wymienione w kolejności alfabetycznej przy użyciu nazwy podstawowej (zignoruj ​​prefiksy). Jedynym przedrostkiem, który jest używany podczas ustawiania podstawników w porządku alfabetycznym, jest izo jak w izopropylu lub izobutylu. Prefiksy sec- i tert- nie są używane do określania kolejności alfabetycznej, chyba że są porównywane ze sobą.

  6. Jeśli łańcuchy o równej długości rywalizują o wybór jako łańcuch macierzysty, wówczas wybór idzie w szeregu do:

    • łańcuch, który ma największą liczbę łańcuchów bocznych.
    • łańcuch, którego podstawniki mają najniższe liczby.
    • łańcuch mający największą liczbę atomów węgla w najmniejszym łańcuchu bocznym.
    • łańcuch mający najmniej rozgałęzione łańcuchy boczne (wykres mający najmniejszą liczbę liści).

W przypadku łańcucha nadrzędnego jest to:

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

Żadne łańcuchy nie będą dłuższe niż 12, więc to wystarczy. W przypadku podłańcuchów jest tak samo, ale zamiast „ane” na końcu mamy „yl”.

Możesz założyć, że Cs są w nieparzystych kolumnach, a wiązania ( |i -znaki) mają długość 1 między atomami węgla.

Przypadki testowe:

Wkład:

C-C-C-C

Wydajność:

butan

Wkład:

C-C-C
  |
  C

Wydajność:

2-metylopropan

Wkład:

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

Wydajność:

3-metyloheksan

Wkład:

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

Wydajność:

3-metyloheksan

Wkład:

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

Wydajność:

3,4-dimetylo-5-etyloheptan

Edycja: Przepraszamy za złe przykłady. Nie byłem dobrym studentem :(. Teraz powinny zostać naprawione.

Peter Lenkefi
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Dennis
2
Czy zgodnie z tą zasadą 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.).nie należy nazywać ostatniego przykładu 3,4- di metylo-5-etyloheptanem? (dopiero zaczynamy chemię organiczną, mogę się mylić: P)
NieDzejkob
@NieDzejkob Zgodziłbym się, ponieważ istnieją dwa łańcuchy metylowe.
Jonathan Frech,
@NieDzejkob Rzeczywiście, naprawione.
Peter Lenkefi,

Odpowiedzi:

18

Python 2 , 1876 1871 1870 1859 1846 1830 1826 1900 1932 1913 1847 1833 1635 1613 1596 bajtów

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'

Wypróbuj online!

Cóż, proszę bardzo. Na pewno nie najbardziej golfowy, ale działa (mam nadzieję): D

Może zajęło mi to około 10 godzin? Prawdopodobnie mój najdłuższy golf zarówno pod względem wielkości, jak i czasu, a to mówi coś, biorąc pod uwagę, że używałem Java D:

Logika:

  1. Konwertuj z reprezentacji ASCII na reprezentację grafu z każdym atomem węgla jako węzłem i każdym wiązaniem jako krawędzią reprezentowaną w formie przylegania.
  2. Znajdź wszystkie liście; to znaczy węzły z tylko jednym wiązaniem. Najdłuższy łańcuch jest gwarantowany z jednego do drugiego.
  3. Znajdź dyadyczny produkt z liści; to znaczy wszystkie pary węzłów krawędzi. Następnie weź długość wszystkich tych łańcuchów.
  4. Dla każdego łańcucha znajdź jego łańcuchy.
  5. Rób rzeczy, aby wybrać odpowiedni łańcuch. Jeśli istnieją więzi, to tak naprawdę nie ma znaczenia. Ciekawostka: zawsze będzie remis, ponieważ każdy łańcuch jest liczony dwukrotnie, raz na odwrót.
  6. Wydrukuj poprawnie.

EDYCJA : Naprawiono błąd, który powodował błędy, jeśli nie było żadnych łańcuchów bocznych.

EDYCJA : Dzięki MD XF za zauważenie kilku dodatkowych spacji (wcięcia dla pętli for).

EDYCJA : Zupełnie zapomniałem o prefiksie dla tego samego podstawnika.

UWAGA : Każda linia musi mieć tę samą szerokość, aby to działało. Oznacza to, że wymagane są spacje końcowe.

Ciekawostka: większość cyklicznych węglowodorów będzie określana jako „metan”

Ciekawostka: jeśli zrobisz to C-C-...-C-Cz 13 C, da ethaneto thaneza 14, ropaneza 15 itd.

-79 bajtów dzięki Jonathan Frech
-119 bajtów dzięki NieDzejkob
-17 bajtów dzięki ovs

HyperNeutrino
źródło