Ungesättigtheitsgrad

11

Ungesättigtheitsgrad

Dies ist kein besonders schwieriges Code-Puzzle - aber ich bin gespannt auf Ihre vielfältigen Lösungsmöglichkeiten.

Der Grad der Ungesättigtheit ist die Anzahl der chemischen Doppelbindungen zwischen Atomen und / oder die Anzahl der Ringe in einer chemischen Verbindung.

Sie erhalten die Summenformel einer chemischen Verbindung in der Form XaYbZc (wobei a, b und c die Anzahl der Atome von X, Y oder Z in der Verbindung sind) - die Formel kann beliebig lang sein und ein beliebiges chemisches Element enthalten im Periodensystem (obwohl andere Elemente als C, H, N, F, Cl, Br, I möglicherweise ignoriert werden, da sie nicht in der Formel enthalten sind). Die Verbindung enthält mindestens ein Atom Kohlenstoff. Sie müssen den Grad der Ungesättigtheit berechnen und anzeigen.

Zum Beispiel hat die Verbindung Benzol (siehe Abbildung unten) eine DoU von 4, da sie drei Doppelbindungen (dargestellt durch eine Doppellinie zwischen Atomen) und einen einzelnen Ring (eine Anzahl von Atomen, die in einer Schleife verbunden sind) aufweist:

Benzolring

Wie von LibreTexts definiert :

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

Wo:

  • C ist die Anzahl der Kohlenstoffatome
  • N ist die Anzahl der Stickstoffatome
  • X die Zahl der Halogenatome ist ( F, Cl, Br, I)
  • H ist die Anzahl der Wasserstoffatome

Testfälle:

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

Eine Erklärung zu CH finden Sie hier

Im Wesentlichen müssen Sie feststellen, ob die Verbindung eines der oben genannten Elemente (C, H, N, F, Cl, Br, I) enthält, und wenn ja, wie viele. Berechnen Sie dann den Grad der Ungesättigtheit mit der obigen Formel.

Nur C, H, N, F, Cl, Br und I sind gültige Eingaben für die DoU-Formel. Für die Zwecke dieses Puzzles können alle anderen Elemente vollständig ignoriert werden (z. B. wenn die Verbindung C6H6Mn wäre, wäre das Ergebnis immer noch 4). Wenn es keine der obigen Verbindungen gibt, wäre die Antwort Null.

Sie können davon ausgehen, dass alle eingegebenen Verbindungen chemisch möglich sind, mindestens ein Atom Kohlenstoff enthalten und bekanntermaßen existieren. Wenn die Eingabe ungültig ist, gibt das Programm möglicherweise entweder 0 oder -1 aus oder erzeugt kein Ergebnis.

Regeln

Es gelten Standard-E / A-Regeln und Lücken . Die Eingabe muss eine Standardzeichenfolge sein, und Sie können davon ausgehen, dass die Eingabe nicht leer ist. Dies ist Codegolf - also gewinnt der kürzeste Code in Bytes.

Archie Roques
quelle
Vorgeschlagene Testfälle: Natriumoxid: Na2Ound Methylidin: CHund CCl4He. Dies sind einige Eckfälle, die einige Lösungen beschädigen können. Übrigens nicht, dass es für andere als Mathematica (wahrscheinlich) von Bedeutung ist, aber können wir annehmen, dass die Verbindungen (können) existieren?
Stewie Griffin
Das verstehe ich nicht C9H2O1 --> 0. Sollte es nicht 9 sein? (2*9+2+0-0-2)/2
DLosc
Meinen Sie laut letztem Absatz, dass der Code in der Lage sein muss, ungültige Eingaben zu verarbeiten? Ist übrigens garantiert, dass jedes einzelne Element in der Verbindung eine nachgestellte '1' wie in C1H1 hat?
Keyu Gan
@KeyuGan ja und ja.
Archie Roques

Antworten:

2

JavaScript (ES6), 117 112 Byte

Rückgabe 0für ungültige Eingaben.

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

Testfälle

Alternative Version, 103 Bytes

Wenn die Eingabe garantiert gültig wäre - wie die Einführung der Herausforderung irreführend nahe legt - könnten wir einfach Folgendes tun:

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
quelle
2

Python 3 , 142 151 148 Bytes

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)

Gibt bei einem Fehler 0 zurück.

Dank @HyperNeutrino, der die Bytes reduziert.

Probieren Sie es online aus!

MooseOnTheRocks
quelle
oops - Testfälle aktualisiert!
Archie Roques
Funktioniert nicht ganz
HyperNeutrino
@ HyperNeutrino Testfälle waren für eine Weile unklar. Hat jetzt keine Ausgabe bei ungültiger Eingabe.
MooseOnTheRocks
148 Bytes
HyperNeutrino
Gute Verwendung dictdort!
DLosc
0

Pip , 70 67 Bytes

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

Nimmt die chemische Formel als Befehlszeilenargument. Ausgänge 0für ungültige Eingänge. Probieren Sie es online aus!

Erläuterung

Verwendet eine Reihe von Regex-Ersetzungen, um die chemische Formel in eine mathematische Formel umzuwandeln, bewertet sie und nimmt einige Änderungen vor, um den endgültigen Wert zu erhalten.

Die Ersetzungen (leicht ungolfed Version):

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)

Wir bewerten die resultierende Zeichenfolge mit V. Das gibt uns 2C + N − X − H. Um den richtigen Wert zu erhalten, nehmen wir folgende Anpassungen vor:

`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
quelle
0

C (gcc) , 195197 202 Bytes

Wahrscheinlich die längste Antwort.

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

Probieren Sie es online aus!

Gibt bei einem Fehler 0 zurück.

Keyu Gan
quelle