Grado di insaturazione


11

Grado di insaturazione

Questo non è un puzzle di codice particolarmente difficile, ma mi interessa vedere i tuoi molteplici modi di risolverlo.

Il grado di insaturazione è il numero di doppi legami chimici tra gli atomi e / o il numero di anelli in un composto chimico.

Ti verrà data la formula molecolare di un composto chimico nella forma XaYbZc (dove a, bec sono il numero di atomi di X, Y o Z nel composto) - la formula potrebbe essere di qualsiasi lunghezza e contenere qualsiasi elemento chimico nella tavola periodica (sebbene elementi diversi da C, H, N, F, Cl, Br, potrei essere ignorato in quanto non presenti nella formula). Il composto conterrà almeno un atomo di carbonio. È necessario calcolare e visualizzare il grado di insaturazione.

Ad esempio, il benzene composto (nella foto sotto) ha una DoU di 4 in quanto ha tre doppi legami (mostrati da una doppia linea tra gli atomi) e un singolo anello (un numero di atomi collegati in un anello):

anello benzenico

Come definito da LibreTexts :

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

Dove:

  • C è il numero di atomi di carbonio
  • N è il numero di atomi di azoto
  • X è il numero di atomi di alogeno ( F, Cl, Br, I)
  • H è il numero di atomi di idrogeno

Casi test:

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

Per una spiegazione di CH vedere qui

In sostanza, è necessario identificare se ci sono degli elementi di cui sopra (C, H, N, F, Cl, Br, I) nel composto e, in tal caso, quanti ce ne sono. Quindi, calcolare il grado di insaturazione utilizzando la formula sopra.

Solo C, H, N, F, Cl, Br e I sono input validi per la formula DoU. Ai fini di questo enigma, qualsiasi altro elemento può essere completamente ignorato (ad esempio se il composto fosse C6H6Mn il risultato sarebbe ancora 4). Se non ci fosse nessuno dei composti sopra elencati la risposta sarebbe zero.

Si può presumere che tutti i composti immessi siano chimicamente possibili, contengano almeno un atomo di carbonio e siano noti per esistere. Se l'input non è valido, il programma può produrre 0 o -1 o non produrre alcun risultato.

Regole

Si applicano le regole IO standard e le lacune . L'input deve essere una stringa standard e si può presumere che l'input non sia vuoto. Questo è codegolf - quindi vince il codice più breve in byte.


Casi di prova proposti: ossido di sodio: Na2Oe metilidino: CHe CCl4He. Questi sono alcuni casi angolari che potrebbero compromettere alcune soluzioni. A proposito, non è importante per chiunque altro che Mathematica (probabilmente), ma possiamo supporre che i composti (possano) esistano?
Stewie Griffin,

Non capisco C9H2O1 --> 0. Non dovrebbe essere 9? (2*9+2+0-0-2)/2
DLosc,

secondo l'ultimo paragrafo, vuoi dire che il codice deve essere in grado di gestire input non validi? A proposito, è garantito che ogni singolo elemento nel composto abbia un '1' finale come in C1H1?
Keyu Gan,

@KeyuGan sì e sì.
Archie Roques,

Risposte:


2

JavaScript (ES6), 117 112 byte

Restituisce 0per input non validi.

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

Casi test

Versione alternativa, 103 byte

Se l'input fosse garantito come valido - come l'introduzione della sfida suggerisce in modo fuorviante - potremmo semplicemente fare:

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)

dimostrazione


2

Python 3 , 142 151 148 byte

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)

Restituisce 0 in caso di errore.

Grazie a @HyperNeutrino abbattendo i byte.

Provalo online!


oops - casi di test aggiornati!
Archie Roques,


@HyperNeutrino I casi di test non erano chiari per un po '. Ora non ha output su input non validi.
MooseOnTheRocks,


Bel uso di dictlì!
DLosc,

0

Pip , 70 67 byte

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

Prende la formula chimica come argomento della riga di comando. Uscite 0per ingressi non validi. Provalo online!

Spiegazione

Utilizza una serie di sostituzioni regex per trasformare la formula chimica in una formula matematica, la elimina e fa un paio di modifiche per ottenere il valore finale.

Le sostituzioni (versione leggermente non golfata):

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)

Valutiamo la stringa risultante con V. Questo ci dà 2C + N − X − H. Per ottenere il valore corretto, apportiamo le seguenti modifiche:

`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 byte

Probabilmente la risposta più lunga.

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

Provalo online!

Restituisce 0 in caso di errore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.